Add a new v3 namespace, containing a new iterator_interface based on deducing

this instead of CRTP.
This commit is contained in:
Zach Laine
2023-06-05 00:12:48 -05:00
parent 6ee9557df9
commit df9e186bd6
23 changed files with 416 additions and 33 deletions

View File

@@ -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]

View File

@@ -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

View File

@@ -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> &>;

View File

@@ -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>
{

View File

@@ -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>
{

View File

@@ -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++;
//]

View File

@@ -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>
{

View File

@@ -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>

View File

@@ -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

View File

@@ -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,

View File

@@ -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 &>>

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View File

@@ -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

View File

@@ -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

View File

@@ -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++;

View File

@@ -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;

View File

@@ -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++;

View File

@@ -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++;

View File

@@ -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> &>;

View File

@@ -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 &>>

View File

@@ -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 &>>