Add a macro for disabling the C++20 v2 namespace. Add documentation

of the inlining v1/v2 behavior.
This commit is contained in:
Zach Laine
2020-08-15 22:16:08 -05:00
parent 56ffa7c6ad
commit fd9bfb11bb
8 changed files with 44 additions and 10 deletions

View File

@@ -30,7 +30,7 @@ dramatically.
provides `std::view_interface`). These are constrained templates using C++20
concepts. These are in the `boost::stl_interfaces::v2` namespace, and are
considered experimental, because at the time of this writing, no
C++20-conforming compiler exists.]
C++20-conforming compiler exists. ]
[heading A Quick Example]
@@ -217,3 +217,30 @@ than to try and address the shortcomings of _Iterator_'s `iterator_facade` and
`iterator_adaptor` templates directly.
[endsect]
[section The `v1` and `v2` Namespaces, and the Use of C++20 Concepts]
For much of this library, there are two interfaces: one in namespace
`boost::stl_interfaces::v1`, and one in `boost::stl_interfaces::v2`.
The `v1` version uses SFINAE to constrain templates, and the `v2`
version uses concepts, including the standard concepts from C++20.
When you build with a conforming C++20 compiler, the compiler defines
a macro `__cpp_lib_concepts` that indicates that the compiler supports
concepts, and provides the standard concepts in `std` and
`std::ranges`. When _IFaces_ sees the `__cpp_lib_concepts` macro
defined, it inlines the `v2` namespace; otherwise, it inlines the `v1`
namespace.
The net result for you as a user is that, for some function or type
`foo` with `v1` and `v2` versions, you can use
`boost::stl_interfaces::foo`, and you will get
`boost::stl_interfaces::v1::foo` when building in C++14 or C++17
modes, and `boost::stl_interfaces::v2::foo` when building in C++20 or
later.
If you are using an early C++20 implementation that claims to have
concept support, but that breaks when you build _IFaces_'s C++20 code,
you can disable the `v2` namespace by defining _disable_concepts_m_. ]
[endsect]

View File

@@ -61,6 +61,7 @@
[def _concept_m_ [macroref BOOST_STL_INTERFACES_STATIC_ASSERT_CONCEPT]]
[def _traits_m_ [macroref BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS]]
[def _disable_concepts_m_ [macroref BOOST_STL_INTERFACES_DISABLE_CONCEPTS]]
[def _CRTP_ [@https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern CRTP]]
[def _Iterator_ [@https://www.boost.org/doc/libs/release/libs/iterator Boost.Iterator]]

View File

@@ -10,12 +10,18 @@
#include <iterator>
#if defined(__cpp_lib_concepts) && !defined(BOOST_STL_INTERFACES_DISABLE_CONCEPTS)
#define BOOST_STL_INTERFACES_USE_CONCEPTS 1
#else
#define BOOST_STL_INTERFACES_USE_CONCEPTS 0
#endif
// The inline namespaces v1 and v2 represent pre- and post-C++20. v1 is
// inline for standards before C++20, and v2 is inline for C++20 and later.
// Note that this only applies to code for which a v2 namespace alternative
// exists. Some instances of the v1 namespace may still be inline, if there
// is no v2 version of its contents.
#if defined(__cpp_lib_concepts)
#if BOOST_STL_INTERFACES_USE_CONCEPTS
# define BOOST_STL_INTERFACES_NAMESPACE_V1 namespace v1
# define BOOST_STL_INTERFACES_NAMESPACE_V2 inline namespace v2
#else

View File

@@ -8,7 +8,7 @@
#include <boost/stl_interfaces/config.hpp>
#if defined(__cpp_lib_concepts)
#if BOOST_STL_INTERFACES_USE_CONCEPTS
#include <ranges>
#endif
#if defined(__cpp_lib_three_way_comparison)

View File

@@ -46,7 +46,7 @@ namespace boost { namespace stl_interfaces {
this template implies a copy or move of the underlying object of type
`T`. */
template<typename T>
#if defined(BOOST_STL_INTERFACES_DOXYGEN) || defined(__cpp_lib_concepts)
#if defined(BOOST_STL_INTERFACES_DOXYGEN) || BOOST_STL_INTERFACES_USE_CONCEPTS
// clang-format off
requires std::is_object_v<T>
#endif
@@ -546,7 +546,7 @@ namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V1 {
}}}
#if defined(BOOST_STL_INTERFACES_DOXYGEN) || defined(__cpp_lib_concepts)
#if defined(BOOST_STL_INTERFACES_DOXYGEN) || BOOST_STL_INTERFACES_USE_CONCEPTS
namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V2 {
@@ -893,7 +893,7 @@ namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V2 {
diff_t>::value, \
"");
#if defined(__cpp_lib_concepts)
#if BOOST_STL_INTERFACES_USE_CONCEPTS
#define BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS( \
iter, category, concept, value_type, reference, pointer, difference_type) \
static_assert( \

View File

@@ -63,7 +63,7 @@ namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V1 {
struct reverse_iterator
: iterator_interface<
reverse_iterator<BidiIter>,
#if defined(__cpp_lib_concepts)
#if BOOST_STL_INTERFACES_USE_CONCEPTS
typename boost::stl_interfaces::v2::v2_dtl::iter_concept_t<
BidiIter>,
#else
@@ -170,7 +170,7 @@ namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V1 {
}}}
#if defined(BOOST_STL_INTERFACES_DOXYGEN) || defined(__cpp_lib_concepts)
#if defined(BOOST_STL_INTERFACES_DOXYGEN) || BOOST_STL_INTERFACES_USE_CONCEPTS
namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V2 {

View File

@@ -670,7 +670,7 @@ namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V1 {
}}}
#if defined(BOOST_STL_INTERFACES_DOXYGEN) || defined(__cpp_lib_concepts)
#if defined(BOOST_STL_INTERFACES_DOXYGEN) || BOOST_STL_INTERFACES_USE_CONCEPTS
namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V2 {

View File

@@ -201,7 +201,7 @@ namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V1 {
}}}
#if defined(BOOST_STL_INTERFACES_DOXYGEN) || defined(__cpp_lib_concepts)
#if defined(BOOST_STL_INTERFACES_DOXYGEN) || BOOST_STL_INTERFACES_USE_CONCEPTS
namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V2 {