mirror of
https://github.com/boostorg/stl_interfaces.git
synced 2026-01-19 04:42:12 +00:00
Add a new v3 namespace, containing a new iterator_interface based on deducing
this instead of CRTP.
This commit is contained in:
@@ -37,7 +37,10 @@ dramatically.
|
||||
|
||||
[note C++20 versions of _iter_iface_ and _cont_iface_ are provided (C++20
|
||||
provides `std::view_interface`). These are constrained templates using C++20
|
||||
concepts. These are in the `boost::stl_interfaces::v2` namespace. ]
|
||||
concepts. These are in the `boost::stl_interfaces::v2` namespace. There is
|
||||
also a C++23 version of _iter_iface_ that uses deducing `this` instead of
|
||||
_CRTP_. If you do nothing, you'll get the latest `vN` namespace inlined,
|
||||
depending on your compiler's language support. ]
|
||||
|
||||
[heading A Quick Example]
|
||||
|
||||
|
||||
@@ -19,8 +19,9 @@ the full set of operations it supports can be defined in terms of that much
|
||||
smaller basis.
|
||||
|
||||
It is possible to define any iterator `Iter` in terms of a subset of
|
||||
user-defined operations. By deriving `Iter` from _iter_iface_ using _CRTP_,
|
||||
we can generate the full set of operations. Here is the declaration of
|
||||
user-defined operations. By deriving `Iter` from _iter_iface_, we can
|
||||
generate the full set of operations. _iter_iface_ uses _CRTP_ in C++20 and
|
||||
earlier, and deducing `this` in C++23 and later. Here is the declaration of
|
||||
_iter_iface_:
|
||||
|
||||
template<
|
||||
@@ -32,10 +33,24 @@ _iter_iface_:
|
||||
typename DifferenceType = std::ptrdiff_t>
|
||||
struct iterator_interface;
|
||||
|
||||
Or, for C++23 and later:
|
||||
|
||||
template<
|
||||
typename IteratorConcept,
|
||||
typename ValueType,
|
||||
typename Reference = ValueType &,
|
||||
typename Pointer = ValueType *,
|
||||
typename DifferenceType = std::ptrdiff_t>
|
||||
struct iterator_interface;
|
||||
|
||||
Let's break that down.
|
||||
|
||||
`Derived` is the type that you're deriving _iter_iface_ from.
|
||||
|
||||
[important In C++23 and later, as long as you have not defined
|
||||
`BOOST_STL_INTERFACES_DISABLE_DEDUCED_THIS`, you do not pass the derived type
|
||||
to _iter_iface_; it has no `Derived` template parameter.]
|
||||
|
||||
`IteratorConcept` defines the iterator category/concept. This must be one of
|
||||
the C++ standard iterator tag types, like `std::forward_iterator_tag`. In
|
||||
C++20 and later, `std::contiguous_iterator_tag` is a valid tag to use.
|
||||
@@ -85,12 +100,30 @@ reasonable defaults for _iter_iface_'s parameters:
|
||||
proxy_arrow_result<Reference>,
|
||||
DifferenceType>;
|
||||
|
||||
Or, for C++23 and later:
|
||||
|
||||
template<
|
||||
typename IteratorConcept,
|
||||
typename ValueType,
|
||||
typename Reference = ValueType,
|
||||
typename DifferenceType = std::ptrdiff_t>
|
||||
using proxy_iterator_interface = iterator_interface<
|
||||
IteratorConcept,
|
||||
ValueType,
|
||||
Reference,
|
||||
proxy_arrow_result<Reference>,
|
||||
DifferenceType>;
|
||||
|
||||
[note As shown above, _proxy_iter_iface_ uses a template called
|
||||
`proxy_arrow_result` as its pointer-type. This template makes a copy of
|
||||
whatever value is obtained by `operator*`, and then returns a pointer to the
|
||||
copy in its `operator->`. You may want to use something else if this is a
|
||||
performance concern. ]
|
||||
|
||||
[important If you are using C++23 or later and have not defined
|
||||
`BOOST_STL_INTERFACES_DISABLE_DEDUCED_THIS`, the `Derived` template parameter
|
||||
above will not be present.]
|
||||
|
||||
|
||||
[heading User-Defined Iterator Operations]
|
||||
|
||||
@@ -231,8 +264,9 @@ will get us there.
|
||||
[node_iterator_class_head]
|
||||
|
||||
We are deriving `node_iterator` from _iter_iface_, and because we're using
|
||||
_CRTP_, we first have to pass `node_iterator` for the `Derived` template
|
||||
parameter, so that _iter_iface_ knows what derived type to cast to in order to
|
||||
_CRTP_ in C++20 and earlier, we first have to pass `node_iterator` for the
|
||||
`Derived` template parameter if `BOOST_STL_INTERFACES_USE_DEDUCED_THIS` is not
|
||||
defined, so that _iter_iface_ knows what derived type to cast to in order to
|
||||
get at the user-defined operations. Then, we pass `std::forward_iterator_tag`
|
||||
for `IteratorConcept`, since that's appropriate for a singly-linked list.
|
||||
Finally, we pass `T` to let _iter_iface_ know what the `value_type` is for our
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
// iterator_interface is flexible enough to handle this odd kind of iterator.
|
||||
template<typename Container>
|
||||
struct back_insert_iterator : boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
back_insert_iterator<Container>,
|
||||
#endif
|
||||
std::output_iterator_tag,
|
||||
typename Container::value_type,
|
||||
back_insert_iterator<Container> &>
|
||||
@@ -51,7 +53,9 @@ struct back_insert_iterator : boost::stl_interfaces::iterator_interface<
|
||||
back_insert_iterator & operator++() { return *this; }
|
||||
|
||||
using base_type = boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
back_insert_iterator<Container>,
|
||||
#endif
|
||||
std::output_iterator_tag,
|
||||
typename Container::value_type,
|
||||
back_insert_iterator<Container> &>;
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
//[ filtered_int_iterator_defn
|
||||
template<typename Pred>
|
||||
struct filtered_int_iterator : boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
filtered_int_iterator<Pred>,
|
||||
#endif
|
||||
std::bidirectional_iterator_tag,
|
||||
int>
|
||||
{
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
// from the same template.
|
||||
template<typename ValueType>
|
||||
struct random_access_iterator : boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
random_access_iterator<ValueType>,
|
||||
#endif
|
||||
std::random_access_iterator_tag,
|
||||
ValueType>
|
||||
{
|
||||
|
||||
@@ -24,8 +24,11 @@ struct node
|
||||
//[ node_iterator_class_head
|
||||
template<typename T>
|
||||
struct node_iterator
|
||||
: boost::stl_interfaces::
|
||||
iterator_interface<node_iterator<T>, std::forward_iterator_tag, T>
|
||||
: boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
node_iterator<T>,
|
||||
#endif
|
||||
std::forward_iterator_tag, T>
|
||||
//]
|
||||
{
|
||||
//[ node_iterator_ctors
|
||||
@@ -48,8 +51,11 @@ struct node_iterator
|
||||
//]
|
||||
|
||||
//[ node_iterator_using_declaration
|
||||
using base_type = boost::stl_interfaces::
|
||||
iterator_interface<node_iterator<T>, std::forward_iterator_tag, T>;
|
||||
using base_type = boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
node_iterator<T>,
|
||||
#endif
|
||||
std::forward_iterator_tag, T>;
|
||||
using base_type::operator++;
|
||||
//]
|
||||
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
// parameters for most stl_interfaces template parameters.
|
||||
struct simple_random_access_iterator
|
||||
: boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
simple_random_access_iterator,
|
||||
#endif
|
||||
std::random_access_iterator_tag,
|
||||
int>
|
||||
{
|
||||
|
||||
@@ -12,7 +12,9 @@
|
||||
|
||||
//[ repeated_chars_iterator
|
||||
struct repeated_chars_iterator : boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
repeated_chars_iterator,
|
||||
#endif
|
||||
std::random_access_iterator_tag,
|
||||
char,
|
||||
char>
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
template<typename BidiIter>
|
||||
struct reverse_iterator
|
||||
: boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
reverse_iterator<BidiIter>,
|
||||
#endif
|
||||
#if 201703L < __cplusplus && defined(__cpp_lib_ranges)
|
||||
boost::stl_interfaces::v2::v2_dtl::iter_concept_t<BidiIter>,
|
||||
#else
|
||||
|
||||
@@ -15,7 +15,9 @@ namespace detail {
|
||||
template<typename Iter>
|
||||
struct take_iterator
|
||||
: boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
take_iterator<Iter>,
|
||||
#endif
|
||||
std::forward_iterator_tag,
|
||||
typename std::iterator_traits<Iter>::value_type,
|
||||
typename std::iterator_traits<Iter>::reference,
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
// reference -- the reference type is a pair of references, std::tuple<int &,
|
||||
// int &>.
|
||||
struct zip_iterator : boost::stl_interfaces::proxy_iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
zip_iterator,
|
||||
#endif
|
||||
std::random_access_iterator_tag,
|
||||
std::tuple<int, int>,
|
||||
std::tuple<int &, int &>>
|
||||
|
||||
@@ -17,17 +17,32 @@
|
||||
#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 BOOST_STL_INTERFACES_USE_CONCEPTS
|
||||
# define BOOST_STL_INTERFACES_NAMESPACE_V1 namespace v1
|
||||
# define BOOST_STL_INTERFACES_NAMESPACE_V2 inline namespace v2
|
||||
#if defined(__cpp_explicit_this_parameter) && \
|
||||
BOOST_STL_INTERFACES_USE_CONCEPTS && \
|
||||
!defined(BOOST_STL_INTERFACES_DISABLE_DEDUCED_THIS)
|
||||
#define BOOST_STL_INTERFACES_USE_DEDUCED_THIS 1
|
||||
#else
|
||||
#define BOOST_STL_INTERFACES_USE_DEDUCED_THIS 0
|
||||
#endif
|
||||
|
||||
// The inline namespaces v1, v2, and v3 represent C++14, C++20, and C++23 and
|
||||
// later, respectively. 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
|
||||
// multiple vI namespace alternatives exist. For example, some instances of
|
||||
// the v1 namespace may still be inline, if there is no v2 version of its
|
||||
// contents.
|
||||
#if !BOOST_STL_INTERFACES_USE_CONCEPTS && !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
# define BOOST_STL_INTERFACES_NAMESPACE_V1 inline namespace v1
|
||||
# define BOOST_STL_INTERFACES_NAMESPACE_V2 namespace v2
|
||||
# define BOOST_STL_INTERFACES_NAMESPACE_V3 namespace v3
|
||||
#elif BOOST_STL_INTERFACES_USE_CONCEPTS && !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
# define BOOST_STL_INTERFACES_NAMESPACE_V1 namespace v1
|
||||
# define BOOST_STL_INTERFACES_NAMESPACE_V2 inline namespace v2
|
||||
# define BOOST_STL_INTERFACES_NAMESPACE_V3 namespace v3
|
||||
#else
|
||||
# define BOOST_STL_INTERFACES_NAMESPACE_V1 namespace v1
|
||||
# define BOOST_STL_INTERFACES_NAMESPACE_V2 namespace v2
|
||||
# define BOOST_STL_INTERFACES_NAMESPACE_V3 inline namespace v3
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -922,6 +922,198 @@ namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V2 {
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_STL_INTERFACES_DOXYGEN) || BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
|
||||
namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V3 {
|
||||
|
||||
// clang-format off
|
||||
|
||||
/** A base template that one may derive from to make defining iterators
|
||||
easier. */
|
||||
template<
|
||||
typename IteratorConcept,
|
||||
typename ValueType,
|
||||
typename Reference = ValueType &,
|
||||
typename Pointer = ValueType *,
|
||||
typename DifferenceType = std::ptrdiff_t>
|
||||
struct iterator_interface
|
||||
: v2::v2_dtl::iterator_category_base<IteratorConcept, Reference>
|
||||
{
|
||||
using iterator_concept = IteratorConcept;
|
||||
using value_type = std::remove_const_t<ValueType>;
|
||||
using reference = Reference;
|
||||
using pointer = detail::pointer_t<Pointer, iterator_concept>;
|
||||
using difference_type = DifferenceType;
|
||||
|
||||
constexpr decltype(auto) operator*(this auto&& self)
|
||||
requires requires { *access::base(self); } {
|
||||
return *access::base(self);
|
||||
}
|
||||
|
||||
constexpr auto operator->(this auto&& self)
|
||||
requires (!std::same_as<pointer, void>) && std::is_reference_v<reference> && requires { *self; } {
|
||||
return detail::make_pointer<pointer, reference>(*self);
|
||||
}
|
||||
|
||||
constexpr decltype(auto) operator[](this auto const& self, difference_type n)
|
||||
requires requires { self + n; } {
|
||||
auto retval = self;
|
||||
retval = retval + n;
|
||||
return *retval;
|
||||
}
|
||||
|
||||
constexpr decltype(auto) operator++(this auto& self)
|
||||
requires requires { ++access::base(self); } && (!requires { self += difference_type(1); }) {
|
||||
++access::base(self);
|
||||
return self;
|
||||
}
|
||||
constexpr decltype(auto) operator++(this auto& self)
|
||||
requires requires { self += difference_type(1); } {
|
||||
return self += difference_type(1);
|
||||
}
|
||||
constexpr auto operator++(this auto& self, int) requires requires { ++self; } {
|
||||
if constexpr (std::is_same_v<IteratorConcept, std::input_iterator_tag>){
|
||||
++self;
|
||||
} else {
|
||||
auto retval = self;
|
||||
++self;
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
constexpr decltype(auto) operator+=(this auto& self, difference_type n)
|
||||
requires requires { access::base(self) += n; } {
|
||||
access::base(self) += n;
|
||||
return self;
|
||||
}
|
||||
|
||||
constexpr decltype(auto) operator--(this auto& self)
|
||||
requires requires { --access::base(self); } && (!requires { self += difference_type(1); }) {
|
||||
--access::base(self);
|
||||
return self;
|
||||
}
|
||||
constexpr decltype(auto) operator--(this auto& self)
|
||||
requires requires { self += -difference_type(1); } {
|
||||
return self += -difference_type(1);
|
||||
}
|
||||
constexpr auto operator--(this auto& self, int) requires requires { --self; } {
|
||||
auto retval = self;
|
||||
--self;
|
||||
return retval;
|
||||
}
|
||||
constexpr decltype(auto) operator-=(this auto& self, difference_type n)
|
||||
requires requires { self += -n; } {
|
||||
return self += -n;
|
||||
}
|
||||
};
|
||||
|
||||
namespace v3_dtl {
|
||||
template<
|
||||
typename IteratorConcept,
|
||||
typename ValueType,
|
||||
typename Reference,
|
||||
typename Pointer,
|
||||
typename DifferenceType>
|
||||
void derived_iterator(v3::iterator_interface<
|
||||
IteratorConcept,
|
||||
ValueType,
|
||||
Reference,
|
||||
Pointer,
|
||||
DifferenceType> const &);
|
||||
|
||||
template<typename D>
|
||||
concept derived_iter = requires (D d) { v3_dtl::derived_iterator(d); };
|
||||
}
|
||||
|
||||
template<typename D>
|
||||
constexpr auto operator+(D it, typename D::difference_type n)
|
||||
requires v3_dtl::derived_iter<D> && requires { it += n; }
|
||||
{ return it += n; }
|
||||
template<typename D>
|
||||
constexpr auto operator+(typename D::difference_type n, D it)
|
||||
requires v3_dtl::derived_iter<D> && requires { it += n; }
|
||||
{ return it += n; }
|
||||
|
||||
template<typename D1, typename D2>
|
||||
constexpr auto operator-(D1 lhs, D2 rhs)
|
||||
requires v3_dtl::derived_iter<D1> && v3_dtl::derived_iter<D2> &&
|
||||
requires { access::base(lhs) - access::base(rhs); }
|
||||
{ return access::base(lhs) - access::base(rhs); }
|
||||
template<typename D>
|
||||
constexpr auto operator-(D it, typename D::difference_type n)
|
||||
requires v3_dtl::derived_iter<D> && requires { it += -n; }
|
||||
{ return it += -n; }
|
||||
|
||||
#if defined(__cpp_lib_three_way_comparison)
|
||||
template<typename D1, typename D2>
|
||||
constexpr auto operator<=>(D1 lhs, D2 rhs)
|
||||
requires v3_dtl::derived_iter<D1> && v3_dtl::derived_iter<D2> &&
|
||||
(v2::v2_dtl::base_3way<D1, D2> || v2::v2_dtl::iter_sub<D1, D2>) {
|
||||
if constexpr (v2::v2_dtl::base_3way<D1, D2>) {
|
||||
return access::base(lhs) <=> access::base(rhs);
|
||||
} else {
|
||||
using diff_type = typename D1::difference_type;
|
||||
diff_type const diff = rhs - lhs;
|
||||
return diff < diff_type(0) ? std::strong_ordering::less :
|
||||
diff_type(0) < diff ? std::strong_ordering::greater :
|
||||
std::strong_ordering::equal;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
template<typename D1, typename D2>
|
||||
constexpr bool operator<(D1 lhs, D2 rhs)
|
||||
requires v3_dtl::derived_iter<D1> && v3_dtl::derived_iter<D2> && v2::v2_dtl::iter_sub<D1, D2>
|
||||
{ return (lhs - rhs) < typename D1::difference_type(0); }
|
||||
template<typename D1, typename D2>
|
||||
constexpr bool operator<=(D1 lhs, D2 rhs)
|
||||
requires v3_dtl::derived_iter<D1> && v3_dtl::derived_iter<D2> && v2::v2_dtl::iter_sub<D1, D2>
|
||||
{ return (lhs - rhs) <= typename D1::difference_type(0); }
|
||||
template<typename D1, typename D2>
|
||||
constexpr bool operator>(D1 lhs, D2 rhs)
|
||||
requires v3_dtl::derived_iter<D1> && v3_dtl::derived_iter<D2> && v2::v2_dtl::iter_sub<D1, D2>
|
||||
{ return (lhs - rhs) > typename D1::difference_type(0); }
|
||||
template<typename D1, typename D2>
|
||||
constexpr bool operator>=(D1 lhs, D2 rhs)
|
||||
requires v3_dtl::derived_iter<D1> && v3_dtl::derived_iter<D2> && v2::v2_dtl::iter_sub<D1, D2>
|
||||
{ return (lhs - rhs) >= typename D1::difference_type(0); }
|
||||
|
||||
template<typename D1, typename D2>
|
||||
constexpr bool operator==(D1 lhs, D2 rhs)
|
||||
requires v3_dtl::derived_iter<D1> && v3_dtl::derived_iter<D2> &&
|
||||
detail::interoperable<D1, D2>::value &&
|
||||
(v2::v2_dtl::base_eq<D1, D2> || v2::v2_dtl::iter_sub<D1, D2>) {
|
||||
if constexpr (v2::v2_dtl::base_eq<D1, D2>) {
|
||||
return (access::base(lhs) == access::base(rhs));
|
||||
} else if constexpr (v2::v2_dtl::iter_sub<D1, D2>) {
|
||||
return (lhs - rhs) == typename D1::difference_type(0);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename D1, typename D2>
|
||||
constexpr auto operator!=(D1 lhs, D2 rhs) -> decltype(!(lhs == rhs))
|
||||
requires v3_dtl::derived_iter<D1> && v3_dtl::derived_iter<D2>
|
||||
{ return !(lhs == rhs); }
|
||||
|
||||
// clang-format on
|
||||
|
||||
|
||||
/** A template alias useful for defining proxy iterators. \see
|
||||
`iterator_interface`. */
|
||||
template<
|
||||
typename IteratorConcept,
|
||||
typename ValueType,
|
||||
typename Reference = ValueType,
|
||||
typename DifferenceType = std::ptrdiff_t>
|
||||
using proxy_iterator_interface = iterator_interface<
|
||||
IteratorConcept,
|
||||
ValueType,
|
||||
Reference,
|
||||
proxy_arrow_result<Reference>,
|
||||
DifferenceType>;
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_STL_INTERFACES_DOXYGEN
|
||||
|
||||
/** `static_asserts` that type `type` models concept `concept_name`. This is
|
||||
|
||||
@@ -62,7 +62,9 @@ namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V1 {
|
||||
template<typename BidiIter>
|
||||
struct reverse_iterator
|
||||
: iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
reverse_iterator<BidiIter>,
|
||||
#endif
|
||||
#if BOOST_STL_INTERFACES_USE_CONCEPTS
|
||||
typename boost::stl_interfaces::v2::v2_dtl::iter_concept_t<
|
||||
BidiIter>,
|
||||
@@ -160,7 +162,7 @@ namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V1 {
|
||||
}
|
||||
|
||||
/** Makes a `reverse_iterator<BidiIter>` from an iterator of type
|
||||
`Bidiiter`. */
|
||||
`BidiIter`. */
|
||||
template<typename BidiIter>
|
||||
auto make_reverse_iterator(BidiIter it)
|
||||
{
|
||||
@@ -182,7 +184,28 @@ namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V2 {
|
||||
|
||||
|
||||
/** Makes a `reverse_iterator<BidiIter>` from an iterator of type
|
||||
`Bidiiter`. This only exists to make migration from
|
||||
`BidiIter`. This only exists to make migration from
|
||||
Boost.STLInterfaces to C++20 easier; switch to the one in `std` as
|
||||
soon as you can. */
|
||||
template<typename BidiIter>
|
||||
auto make_reverse_iterator(BidiIter it)
|
||||
{
|
||||
return reverse_iterator<BidiIter>(it);
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V3 {
|
||||
|
||||
/** A template alias for `std::reverse_iterator`. This only exists to
|
||||
make migration from Boost.STLInterfaces to C++20 easier; switch to the
|
||||
one in `std` as soon as you can. */
|
||||
template<typename BidiIter>
|
||||
using reverse_iterator = std::reverse_iterator<BidiIter>;
|
||||
|
||||
|
||||
/** Makes a `reverse_iterator<BidiIter>` from an iterator of type
|
||||
`BidiIter`. This only exists to make migration from
|
||||
Boost.STLInterfaces to C++20 easier; switch to the one in `std` as
|
||||
soon as you can. */
|
||||
template<typename BidiIter>
|
||||
|
||||
@@ -20,7 +20,9 @@ namespace boost { namespace stl_interfaces { namespace detail {
|
||||
|
||||
template<typename T, typename SizeType>
|
||||
struct n_iter : iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
n_iter<T, SizeType>,
|
||||
#endif
|
||||
std::random_access_iterator_tag,
|
||||
T>
|
||||
{
|
||||
@@ -1025,4 +1027,17 @@ namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V2 {
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_STL_INTERFACES_DOXYGEN) || BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
|
||||
namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V3 {
|
||||
|
||||
// TODO: Reimplement using deduced this.
|
||||
template<typename D,
|
||||
element_layout Contiguity = element_layout::discontiguous>
|
||||
using sequence_container_interface = v2::sequence_container_interface<D, Contiguity>;
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -213,6 +213,16 @@ namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V2 {
|
||||
|
||||
}}}
|
||||
|
||||
namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V3 {
|
||||
|
||||
/** A template alias for `std::ranges::view_interface`. This only exists
|
||||
to make migration from Boost.STLInterfaces to C++20 easier; switch to
|
||||
the one in `std` as soon as you can. */
|
||||
template<typename D, element_layout = element_layout::discontiguous>
|
||||
using view_interface = std::ranges::view_interface<D>;
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
|
||||
|
||||
struct basic_bidirectional_iter : boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
basic_bidirectional_iter,
|
||||
#endif
|
||||
std::bidirectional_iterator_tag,
|
||||
int>
|
||||
{
|
||||
@@ -43,7 +45,9 @@ struct basic_bidirectional_iter : boost::stl_interfaces::iterator_interface<
|
||||
}
|
||||
|
||||
using base_type = boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
basic_bidirectional_iter,
|
||||
#endif
|
||||
std::bidirectional_iterator_tag,
|
||||
int>;
|
||||
using base_type::operator++;
|
||||
@@ -71,7 +75,9 @@ static_assert(
|
||||
|
||||
struct basic_adapted_bidirectional_ptr_iter
|
||||
: boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
basic_adapted_bidirectional_ptr_iter,
|
||||
#endif
|
||||
std::bidirectional_iterator_tag,
|
||||
int>
|
||||
{
|
||||
@@ -99,7 +105,9 @@ BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
|
||||
|
||||
struct basic_adapted_bidirectional_list_iter
|
||||
: boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
basic_adapted_bidirectional_list_iter,
|
||||
#endif
|
||||
std::bidirectional_iterator_tag,
|
||||
int>
|
||||
{
|
||||
@@ -129,7 +137,9 @@ BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
|
||||
template<typename ValueType>
|
||||
struct adapted_bidirectional_ptr_iter
|
||||
: boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
adapted_bidirectional_ptr_iter<ValueType>,
|
||||
#endif
|
||||
std::bidirectional_iterator_tag,
|
||||
ValueType>
|
||||
{
|
||||
@@ -185,7 +195,9 @@ BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
|
||||
|
||||
template<typename ValueType>
|
||||
struct bidirectional_iter : boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
bidirectional_iter<ValueType>,
|
||||
#endif
|
||||
std::bidirectional_iterator_tag,
|
||||
ValueType>
|
||||
{
|
||||
@@ -216,7 +228,9 @@ struct bidirectional_iter : boost::stl_interfaces::iterator_interface<
|
||||
}
|
||||
|
||||
using base_type = boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
bidirectional_iter<ValueType>,
|
||||
#endif
|
||||
std::bidirectional_iterator_tag,
|
||||
ValueType>;
|
||||
using base_type::operator++;
|
||||
|
||||
@@ -17,8 +17,11 @@ struct node
|
||||
|
||||
template<typename Node>
|
||||
struct iterator
|
||||
: boost::stl_interfaces::
|
||||
iterator_interface<iterator<Node>, std::forward_iterator_tag, Node>
|
||||
: boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
iterator<Node>,
|
||||
#endif
|
||||
std::forward_iterator_tag, Node>
|
||||
{
|
||||
using value_type = typename Node::value_type;
|
||||
|
||||
|
||||
@@ -19,8 +19,11 @@ template<typename T>
|
||||
using decrementable_t = decltype(--std::declval<T &>());
|
||||
|
||||
struct basic_forward_iter
|
||||
: boost::stl_interfaces::
|
||||
iterator_interface<basic_forward_iter, std::forward_iterator_tag, int>
|
||||
: boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
basic_forward_iter,
|
||||
#endif
|
||||
std::forward_iterator_tag, int>
|
||||
{
|
||||
basic_forward_iter() : it_(nullptr) {}
|
||||
basic_forward_iter(int * it) : it_(it) {}
|
||||
@@ -37,8 +40,11 @@ struct basic_forward_iter
|
||||
return lhs.it_ == rhs.it_;
|
||||
}
|
||||
|
||||
using base_type = boost::stl_interfaces::
|
||||
iterator_interface<basic_forward_iter, std::forward_iterator_tag, int>;
|
||||
using base_type = boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
basic_forward_iter,
|
||||
#endif
|
||||
std::forward_iterator_tag, int>;
|
||||
using base_type::operator++;
|
||||
|
||||
private:
|
||||
@@ -60,7 +66,9 @@ static_assert(ill_formed<decrementable_t, basic_forward_iter>::value, "");
|
||||
|
||||
template<typename ValueType>
|
||||
struct forward_iter : boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
forward_iter<ValueType>,
|
||||
#endif
|
||||
std::forward_iterator_tag,
|
||||
ValueType>
|
||||
{
|
||||
@@ -85,7 +93,9 @@ struct forward_iter : boost::stl_interfaces::iterator_interface<
|
||||
}
|
||||
|
||||
using base_type = boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
forward_iter<ValueType>,
|
||||
#endif
|
||||
std::forward_iterator_tag,
|
||||
ValueType>;
|
||||
using base_type::operator++;
|
||||
|
||||
@@ -16,8 +16,11 @@
|
||||
|
||||
|
||||
struct basic_input_iter
|
||||
: boost::stl_interfaces::
|
||||
iterator_interface<basic_input_iter, std::input_iterator_tag, int>
|
||||
: boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
basic_input_iter,
|
||||
#endif
|
||||
std::input_iterator_tag, int>
|
||||
{
|
||||
basic_input_iter() : it_(nullptr) {}
|
||||
basic_input_iter(int * it) : it_(it) {}
|
||||
@@ -33,8 +36,11 @@ struct basic_input_iter
|
||||
return lhs.it_ == rhs.it_;
|
||||
}
|
||||
|
||||
using base_type = boost::stl_interfaces::
|
||||
iterator_interface<basic_input_iter, std::input_iterator_tag, int>;
|
||||
using base_type = boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
basic_input_iter,
|
||||
#endif
|
||||
std::input_iterator_tag, int>;
|
||||
using base_type::operator++;
|
||||
|
||||
private:
|
||||
@@ -56,7 +62,9 @@ BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
|
||||
|
||||
template<typename ValueType>
|
||||
struct input_iter : boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
input_iter<ValueType>,
|
||||
#endif
|
||||
std::input_iterator_tag,
|
||||
ValueType>
|
||||
{
|
||||
@@ -81,7 +89,9 @@ struct input_iter : boost::stl_interfaces::iterator_interface<
|
||||
}
|
||||
|
||||
using base_type = boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
input_iter<ValueType>,
|
||||
#endif
|
||||
std::input_iterator_tag,
|
||||
ValueType>;
|
||||
using base_type::operator++;
|
||||
@@ -112,7 +122,9 @@ using const_pair_input = input_iter<std::pair<int, int> const>;
|
||||
|
||||
template<typename ValueType>
|
||||
struct proxy_input_iter : boost::stl_interfaces::proxy_iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
proxy_input_iter<ValueType>,
|
||||
#endif
|
||||
std::input_iterator_tag,
|
||||
ValueType>
|
||||
{
|
||||
@@ -137,7 +149,9 @@ struct proxy_input_iter : boost::stl_interfaces::proxy_iterator_interface<
|
||||
}
|
||||
|
||||
using base_type = boost::stl_interfaces::proxy_iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
proxy_input_iter<ValueType>,
|
||||
#endif
|
||||
std::input_iterator_tag,
|
||||
ValueType>;
|
||||
using base_type::operator++;
|
||||
|
||||
@@ -14,8 +14,11 @@
|
||||
|
||||
|
||||
struct basic_output_iter
|
||||
: boost::stl_interfaces::
|
||||
iterator_interface<basic_output_iter, std::output_iterator_tag, int>
|
||||
: boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
basic_output_iter,
|
||||
#endif
|
||||
std::output_iterator_tag, int>
|
||||
{
|
||||
basic_output_iter() : it_(nullptr) {}
|
||||
basic_output_iter(int * it) : it_(it) {}
|
||||
@@ -27,8 +30,11 @@ struct basic_output_iter
|
||||
return *this;
|
||||
}
|
||||
|
||||
using base_type = boost::stl_interfaces::
|
||||
iterator_interface<basic_output_iter, std::output_iterator_tag, int>;
|
||||
using base_type = boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
basic_output_iter,
|
||||
#endif
|
||||
std::output_iterator_tag, int>;
|
||||
using base_type::operator++;
|
||||
|
||||
private:
|
||||
@@ -61,7 +67,9 @@ BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
|
||||
|
||||
template<typename Container>
|
||||
struct back_insert_iter : boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
back_insert_iter<Container>,
|
||||
#endif
|
||||
std::output_iterator_tag,
|
||||
typename Container::value_type,
|
||||
back_insert_iter<Container> &>
|
||||
@@ -84,7 +92,9 @@ struct back_insert_iter : boost::stl_interfaces::iterator_interface<
|
||||
}
|
||||
|
||||
using base_type = boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
back_insert_iter<Container>,
|
||||
#endif
|
||||
std::output_iterator_tag,
|
||||
typename Container::value_type,
|
||||
back_insert_iter<Container> &>;
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
|
||||
|
||||
struct basic_random_access_iter : boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
basic_random_access_iter,
|
||||
#endif
|
||||
std::random_access_iterator_tag,
|
||||
int>
|
||||
{
|
||||
@@ -63,7 +65,9 @@ static_assert(
|
||||
template<typename ValueType>
|
||||
struct basic_random_access_iter_dependent
|
||||
: boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
basic_random_access_iter_dependent<ValueType>,
|
||||
#endif
|
||||
std::random_access_iterator_tag,
|
||||
ValueType>
|
||||
{
|
||||
@@ -103,7 +107,9 @@ BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
|
||||
|
||||
struct basic_adapted_random_access_iter
|
||||
: boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
basic_adapted_random_access_iter,
|
||||
#endif
|
||||
std::random_access_iterator_tag,
|
||||
int>
|
||||
{
|
||||
@@ -131,7 +137,9 @@ BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
|
||||
|
||||
template<typename ValueType>
|
||||
struct adapted_random_access_iter : boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
adapted_random_access_iter<ValueType>,
|
||||
#endif
|
||||
std::random_access_iterator_tag,
|
||||
ValueType>
|
||||
{
|
||||
@@ -180,7 +188,9 @@ BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
|
||||
|
||||
template<typename ValueType>
|
||||
struct random_access_iter : boost::stl_interfaces::iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
random_access_iter<ValueType>,
|
||||
#endif
|
||||
std::random_access_iterator_tag,
|
||||
ValueType>
|
||||
{
|
||||
@@ -238,7 +248,9 @@ BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
|
||||
std::ptrdiff_t)
|
||||
|
||||
struct zip_iter : boost::stl_interfaces::proxy_iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
zip_iter,
|
||||
#endif
|
||||
std::random_access_iterator_tag,
|
||||
std::tuple<int, int>,
|
||||
std::tuple<int &, int &>>
|
||||
@@ -298,7 +310,9 @@ struct int_t
|
||||
};
|
||||
|
||||
struct udt_zip_iter : boost::stl_interfaces::proxy_iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
udt_zip_iter,
|
||||
#endif
|
||||
std::random_access_iterator_tag,
|
||||
std::tuple<int_t, int>,
|
||||
std::tuple<int_t &, int &>>
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
|
||||
|
||||
struct zip_iter : boost::stl_interfaces::proxy_iterator_interface<
|
||||
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
|
||||
zip_iter,
|
||||
#endif
|
||||
std::random_access_iterator_tag,
|
||||
std::tuple<int, int>,
|
||||
std::tuple<int &, int &>>
|
||||
|
||||
Reference in New Issue
Block a user