Skip to content

Commit 33e052f

Browse files
committed
Only forward-declare from_range_t if __cpp_lib_containers_ranges is defined. Define al alternative otherwise.
1 parent 4e3dac1 commit 33e052f

2 files changed

Lines changed: 42 additions & 10 deletions

File tree

include/boost/container/detail/range_utils.hpp

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,21 @@
2626
//! Defines boost::container::from_range_t and the boost::container::from_range
2727
//! tag, used to disambiguate the range-based members of the containers.
2828
//!
29-
//! Following the same technique as boost::container::piecewise_construct_t and
30-
//! boost::container::allocator_arg_t, from_range_t is a reference to the
31-
//! standard ::std::from_range_t (only forward declared in <std_fwd.hpp>), so
32-
//! the tag is the very same type as the standard one and interoperates with
33-
//! ::std::from_range, yet the heavyweight <ranges> header is not required.
29+
//! When the standard library provides ::std::from_range_t (feature-test macro
30+
//! __cpp_lib_containers_ranges), from_range_t is a reference to it -following
31+
//! the same technique as boost::container::piecewise_construct_t and
32+
//! boost::container::allocator_arg_t- so the tag is the very same type as the
33+
//! standard one and interoperates with ::std::from_range, yet the heavyweight
34+
//! <ranges> header is not required. Otherwise, there is no standard type to
35+
//! refer to and from_range_t is defined as a standalone type.
3436

3537
namespace boost {
3638
namespace container {
3739

3840
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
3941

42+
#if defined(__cpp_lib_containers_ranges)
43+
4044
template <int Dummy = 0>
4145
struct std_from_range_holder
4246
{
@@ -48,18 +52,31 @@ namespace container {
4852

4953
typedef const ::std::from_range_t & from_range_t;
5054

51-
#else
55+
//! A instance of type from_range_t
56+
static from_range_t from_range = *std_from_range_holder<>::dummy;
57+
58+
#else //!defined(__cpp_lib_containers_ranges)
59+
60+
//The standard library does not provide ::std::from_range_t, so there is nothing
61+
//to interoperate with: from_range_t is a standalone type.
62+
struct from_range_t {};
63+
64+
//! A instance of type from_range_t
65+
static const from_range_t from_range = from_range_t();
66+
67+
#endif //defined(__cpp_lib_containers_ranges)
68+
69+
#else //BOOST_CONTAINER_DOXYGEN_INVOKED
5270

5371
//! The from_range_t struct is an empty structure type used as a unique type to
5472
//! disambiguate the constructors and member functions that build or replace the
5573
//! contents of a container from a container-compatible range.
5674
typedef unspecified from_range_t;
5775

58-
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
76+
//! A instance of type from_range_t
77+
static from_range_t from_range;
5978

60-
//! A instance of type
61-
//! from_range_t
62-
static from_range_t from_range = BOOST_CONTAINER_DOC1ST(unspecified, *std_from_range_holder<>::dummy);
79+
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
6380

6481
///@cond
6582

include/boost/container/detail/std_fwd.hpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,17 @@
2525

2626
#include <cstddef>
2727

28+
//<version> is needed to reliably query the __cpp_lib_containers_ranges
29+
//feature-test macro, which tells whether the standard library provides
30+
//::std::from_range_t. It is one of the lightest standard headers (only macros).
31+
#if defined(__has_include)
32+
# if __has_include(<version>)
33+
# include <version>
34+
# endif
35+
#elif BOOST_CXX_VERSION >= 202002L
36+
# include <version>
37+
#endif
38+
2839
#include <boost/move/detail/std_ns_begin.hpp>
2940
BOOST_MOVE_STD_NS_BEG
3041

@@ -58,7 +69,11 @@ struct piecewise_construct_t;
5869
template <class Ptr>
5970
struct pointer_traits;
6071

72+
//Only forward declare ::std::from_range_t when the standard library actually
73+
//provides it; otherwise there is no such type to refer to.
74+
#if defined(__cpp_lib_containers_ranges)
6175
struct from_range_t;
76+
#endif
6277

6378
BOOST_MOVE_STD_NS_END
6479
#include <boost/move/detail/std_ns_end.hpp>

0 commit comments

Comments
 (0)