Removed MPL usage from iterator_facade.hpp.

This commit is contained in:
Andrey Semashev
2025-02-01 02:04:19 +03:00
parent 1875d95019
commit b12874b6ca

View File

@@ -7,7 +7,12 @@
#ifndef BOOST_ITERATOR_FACADE_23022003THW_HPP #ifndef BOOST_ITERATOR_FACADE_23022003THW_HPP
#define BOOST_ITERATOR_FACADE_23022003THW_HPP #define BOOST_ITERATOR_FACADE_23022003THW_HPP
#include <cstddef>
#include <memory>
#include <type_traits>
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/mp11/utility.hpp>
#include <boost/iterator/interoperable.hpp> #include <boost/iterator/interoperable.hpp>
#include <boost/iterator/iterator_traits.hpp> #include <boost/iterator/iterator_traits.hpp>
@@ -16,37 +21,21 @@
#include <boost/iterator/detail/type_traits/conjunction.hpp> #include <boost/iterator/detail/type_traits/conjunction.hpp>
#include <boost/iterator/detail/type_traits/negation.hpp> #include <boost/iterator/detail/type_traits/negation.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/always.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/if.hpp>
#include <cstddef>
#include <type_traits>
#include <memory>
namespace boost { namespace boost {
namespace iterators { namespace iterators {
// This forward declaration is required for the friend declaration // This forward declaration is required for the friend declaration
// in iterator_core_access // in iterator_core_access
template <class I, class V, class TC, class R, class D> class iterator_facade; template<
typename Derived,
typename Value,
typename CategoryOrTraversal,
typename Reference = Value&,
typename Difference = std::ptrdiff_t
>
class iterator_facade;
namespace detail namespace detail {
{
// A binary metafunction class that always returns bool. VC6
// ICEs on mpl::always<bool>, probably because of the default
// parameters.
struct always_bool2
{
template <class T, class U>
struct apply
{
typedef bool type;
};
};
// The type trait checks if the category or traversal is at least as advanced as the specified required traversal // The type trait checks if the category or traversal is at least as advanced as the specified required traversal
template< typename CategoryOrTraversal, typename Required > template< typename CategoryOrTraversal, typename Required >
@@ -58,14 +47,14 @@ namespace iterators {
// enable if for use in operator implementation. // enable if for use in operator implementation.
// //
template< template<
class Facade1 typename Facade1,
, class Facade2 typename Facade2,
, class Return typename Return
> >
struct enable_if_interoperable : struct enable_if_interoperable :
public std::enable_if< public std::enable_if<
is_interoperable<Facade1, Facade2>::value is_interoperable< Facade1, Facade2 >::value,
, Return Return
> >
{}; {};
@@ -73,18 +62,18 @@ namespace iterators {
// enable if for use in implementation of operators specific for random access traversal. // enable if for use in implementation of operators specific for random access traversal.
// //
template< template<
class Facade1 typename Facade1,
, class Facade2 typename Facade2,
, class Return typename Return
> >
struct enable_if_interoperable_and_random_access_traversal : struct enable_if_interoperable_and_random_access_traversal :
public std::enable_if< public std::enable_if<
detail::conjunction< detail::conjunction<
is_interoperable< Facade1, Facade2 > is_interoperable< Facade1, Facade2 >,
, is_traversal_at_least< typename iterator_category< Facade1 >::type, random_access_traversal_tag > is_traversal_at_least< typename iterator_category< Facade1 >::type, random_access_traversal_tag >,
, is_traversal_at_least< typename iterator_category< Facade2 >::type, random_access_traversal_tag > is_traversal_at_least< typename iterator_category< Facade2 >::type, random_access_traversal_tag >
>::value >::value,
, Return Return
> >
{}; {};
@@ -93,25 +82,27 @@ namespace iterators {
// given parameters. // given parameters.
// //
template< template<
class ValueParam typename ValueParam,
, class CategoryOrTraversal typename CategoryOrTraversal,
, class Reference typename Reference,
, class Difference typename Difference
> >
struct iterator_facade_types struct iterator_facade_types
{ {
typedef typename facade_iterator_category< using iterator_category = typename facade_iterator_category<
CategoryOrTraversal, ValueParam, Reference CategoryOrTraversal, ValueParam, Reference
>::type iterator_category; >::type;
typedef typename std::remove_const<ValueParam>::type value_type; using value_type = typename std::remove_const< ValueParam >::type;
// Not the real associated pointer type // Not the real associated pointer type
typedef typename mpl::eval_if< using pointer = typename std::add_pointer<
boost::iterators::detail::iterator_writability_disabled<ValueParam,Reference> typename std::conditional<
, std::add_pointer<const value_type> boost::iterators::detail::iterator_writability_disabled< ValueParam, Reference >::value,
, std::add_pointer<value_type> const value_type,
>::type pointer; value_type
>::type
>::type;
}; };
// iterators whose dereference operators reference the same value // iterators whose dereference operators reference the same value
@@ -120,15 +111,15 @@ namespace iterators {
// value must be read and stored away before the increment occurs // value must be read and stored away before the increment occurs
// so that *a++ yields the originally referenced element and not // so that *a++ yields the originally referenced element and not
// the next one. // the next one.
template <class Iterator> template< typename Iterator >
class postfix_increment_proxy class postfix_increment_proxy
{ {
typedef typename iterator_value<Iterator>::type value_type; using value_type = typename iterator_value< Iterator >::type;
public: public:
explicit postfix_increment_proxy(Iterator const& x) explicit postfix_increment_proxy(Iterator const& x) :
: stored_iterator(x) stored_iterator(x),
, stored_value(*x) stored_value(*x)
{} {}
// Returning a mutable reference allows nonsense like // Returning a mutable reference allows nonsense like
@@ -159,39 +150,39 @@ namespace iterators {
}; };
template <class Iterator> template< typename Iterator >
class writable_postfix_increment_dereference_proxy; class writable_postfix_increment_dereference_proxy;
template <class T> template< typename T >
struct is_not_writable_postfix_increment_dereference_proxy : struct is_not_writable_postfix_increment_dereference_proxy :
public std::true_type public std::true_type
{}; {};
template <class Iterator> template< typename Iterator >
struct is_not_writable_postfix_increment_dereference_proxy< struct is_not_writable_postfix_increment_dereference_proxy<
writable_postfix_increment_dereference_proxy< Iterator > writable_postfix_increment_dereference_proxy< Iterator >
> : > :
public std::false_type public std::false_type
{}; {};
template <class Iterator> template< typename Iterator >
class writable_postfix_increment_proxy; class writable_postfix_increment_proxy;
// //
// In general, we can't determine that such an iterator isn't // In general, we can't determine that such an iterator isn't
// writable -- we also need to store a copy of the old iterator so // writable -- we also need to store a copy of the old iterator so
// that it can be written into. // that it can be written into.
template <class Iterator> template< typename Iterator >
class writable_postfix_increment_dereference_proxy class writable_postfix_increment_dereference_proxy
{ {
friend class writable_postfix_increment_proxy< Iterator >; friend class writable_postfix_increment_proxy< Iterator >;
typedef typename iterator_value<Iterator>::type value_type; using value_type = typename iterator_value< Iterator >::type;
public: public:
explicit writable_postfix_increment_dereference_proxy(Iterator const& x) explicit writable_postfix_increment_dereference_proxy(Iterator const& x) :
: stored_iterator(x) stored_iterator(x),
, stored_value(*x) stored_value(*x)
{} {}
// Provides readability of *r++ // Provides readability of *r++
@@ -200,7 +191,7 @@ namespace iterators {
return this->stored_value; return this->stored_value;
} }
template <class OtherIterator> template< typename OtherIterator >
writable_postfix_increment_dereference_proxy const& writable_postfix_increment_dereference_proxy const&
operator=(writable_postfix_increment_dereference_proxy< OtherIterator > const& x) const operator=(writable_postfix_increment_dereference_proxy< OtherIterator > const& x) const
{ {
@@ -210,7 +201,7 @@ namespace iterators {
} }
// Provides writability of *r++ // Provides writability of *r++
template <class T> template< typename T >
typename std::enable_if< typename std::enable_if<
is_not_writable_postfix_increment_dereference_proxy< T >::value, is_not_writable_postfix_increment_dereference_proxy< T >::value,
writable_postfix_increment_dereference_proxy const& writable_postfix_increment_dereference_proxy const&
@@ -225,14 +216,14 @@ namespace iterators {
mutable value_type stored_value; mutable value_type stored_value;
}; };
template <class Iterator> template< typename Iterator >
class writable_postfix_increment_proxy class writable_postfix_increment_proxy
{ {
typedef typename iterator_value<Iterator>::type value_type; using value_type = typename iterator_value< Iterator >::type;
public: public:
explicit writable_postfix_increment_proxy(Iterator const& x) explicit writable_postfix_increment_proxy(Iterator const& x) :
: dereference_proxy(x) dereference_proxy(x)
{} {}
writable_postfix_increment_dereference_proxy< Iterator > const& writable_postfix_increment_dereference_proxy< Iterator > const&
@@ -257,12 +248,11 @@ namespace iterators {
writable_postfix_increment_dereference_proxy< Iterator > dereference_proxy; writable_postfix_increment_dereference_proxy< Iterator > dereference_proxy;
}; };
template <class Reference, class Value> template< typename Reference, typename Value >
struct is_non_proxy_reference struct is_non_proxy_reference :
: std::is_convertible< public std::is_convertible<
typename std::remove_reference<Reference>::type typename std::remove_reference< Reference >::type const volatile*,
const volatile* Value const volatile*
, Value const volatile*
> >
{}; {};
@@ -281,44 +271,41 @@ namespace iterators {
// operations, we're not going to try to support them. Therefore, // operations, we're not going to try to support them. Therefore,
// even if r++ returns a proxy, *r++ will only return a proxy if // even if r++ returns a proxy, *r++ will only return a proxy if
// *r also returns a proxy. // *r also returns a proxy.
template <class Iterator, class Value, class Reference, class CategoryOrTraversal> template< typename Iterator, typename Value, typename Reference, typename CategoryOrTraversal >
struct postfix_increment_result struct postfix_increment_result
: mpl::eval_if< {
using type = mp11::mp_eval_if_not<
detail::conjunction< detail::conjunction<
// A proxy is only needed for readable iterators // A proxy is only needed for readable iterators
std::is_convertible< std::is_convertible<
Reference Reference,
// Use add_lvalue_reference to form `reference to Value` due to // Use add_lvalue_reference to form `reference to Value` due to
// some (strict) C++03 compilers (e.g. `gcc -std=c++03`) reject // some (strict) C++03 compilers (e.g. `gcc -std=c++03`) reject
// 'reference-to-reference' in the template which described in CWG // 'reference-to-reference' in the template which described in CWG
// DR106. // DR106.
// http://www.open-std.org/Jtc1/sc22/wg21/docs/cwg_defects.html#106 // http://www.open-std.org/Jtc1/sc22/wg21/docs/cwg_defects.html#106
, typename std::add_lvalue_reference<Value const>::type typename std::add_lvalue_reference< Value const >::type
> >,
// No multipass iterator can have values that disappear // No multipass iterator can have values that disappear
// before positions can be re-visited // before positions can be re-visited
, detail::negation< detail::negation<
std::is_convertible< detail::is_traversal_at_least< CategoryOrTraversal, forward_traversal_tag >
typename iterator_category_to_traversal<CategoryOrTraversal>::type
, forward_traversal_tag
> >
> >,
> Iterator,
, mpl::if_< mp11::mp_if,
is_non_proxy_reference<Reference,Value> is_non_proxy_reference< Reference, Value >,
, postfix_increment_proxy<Iterator> postfix_increment_proxy< Iterator >,
, writable_postfix_increment_proxy<Iterator> writable_postfix_increment_proxy< Iterator >
> >;
, mpl::identity<Iterator> };
>
{};
// operator->() needs special support for input iterators to strictly meet the // operator->() needs special support for input iterators to strictly meet the
// standard's requirements. If *i is not a reference type, we must still // standard's requirements. If *i is not a reference type, we must still
// produce an lvalue to which a pointer can be formed. We do that by // produce an lvalue to which a pointer can be formed. We do that by
// returning a proxy object containing an instance of the reference object. // returning a proxy object containing an instance of the reference object.
template <class Reference, class Pointer> template< typename Reference, typename Pointer >
struct operator_arrow_dispatch // proxy references struct operator_arrow_dispatch // proxy references
{ {
struct proxy struct proxy
@@ -330,17 +317,20 @@ namespace iterators {
operator Reference*() { return std::addressof(m_ref); } operator Reference*() { return std::addressof(m_ref); }
Reference m_ref; Reference m_ref;
}; };
typedef proxy result_type;
using result_type = proxy;
static result_type apply(Reference const& x) static result_type apply(Reference const& x)
{ {
return result_type(x); return result_type(x);
} }
}; };
template <class T, class Pointer> template< typename T, typename Pointer >
struct operator_arrow_dispatch< T&, Pointer > // "real" references struct operator_arrow_dispatch< T&, Pointer > // "real" references
{ {
typedef Pointer result_type; using result_type = Pointer;
static result_type apply(T& x) static result_type apply(T& x)
{ {
return std::addressof(x); return std::addressof(x);
@@ -350,17 +340,17 @@ namespace iterators {
// A proxy return type for operator[], needed to deal with // A proxy return type for operator[], needed to deal with
// iterators that may invalidate referents upon destruction. // iterators that may invalidate referents upon destruction.
// Consider the temporary iterator in *(a + n) // Consider the temporary iterator in *(a + n)
template <class Iterator> template< typename Iterator >
class operator_brackets_proxy class operator_brackets_proxy
{ {
// Iterator is actually an iterator_facade, so we do not have to // Iterator is actually an iterator_facade, so we do not have to
// go through iterator_traits to access the traits. // go through iterator_traits to access the traits.
typedef typename Iterator::reference reference; using reference = typename Iterator::reference;
typedef typename Iterator::value_type value_type; using value_type = typename Iterator::value_type;
public: public:
operator_brackets_proxy(Iterator const& iter) operator_brackets_proxy(Iterator const& iter) :
: m_iter(iter) m_iter(iter)
{} {}
operator reference() const operator reference() const
@@ -380,58 +370,58 @@ namespace iterators {
// A metafunction that determines whether operator[] must return a // A metafunction that determines whether operator[] must return a
// proxy, or whether it can simply return a copy of the value_type. // proxy, or whether it can simply return a copy of the value_type.
template <class ValueType, class Reference> template< typename ValueType, typename Reference >
struct use_operator_brackets_proxy struct use_operator_brackets_proxy :
: detail::negation< public detail::negation<
detail::conjunction< detail::conjunction<
std::is_copy_constructible<ValueType> std::is_copy_constructible< ValueType >,
, std::is_trivial<ValueType> std::is_trivial< ValueType >,
, iterator_writability_disabled<ValueType,Reference> iterator_writability_disabled< ValueType, Reference >
> >
> >
{}; {};
template <class Iterator, class Value, class Reference> template< typename Iterator, typename Value, typename Reference >
struct operator_brackets_result struct operator_brackets_result
{ {
typedef typename std::conditional< using type = typename std::conditional<
use_operator_brackets_proxy<Value,Reference>::value use_operator_brackets_proxy<Value, Reference>::value,
, operator_brackets_proxy<Iterator> operator_brackets_proxy<Iterator>,
, Value Value
>::type type; >::type;
}; };
template <class Iterator> template< typename Iterator >
operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, std::true_type) inline operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, std::true_type)
{ {
return operator_brackets_proxy< Iterator >(iter); return operator_brackets_proxy< Iterator >(iter);
} }
template <class Iterator> template< typename Iterator >
typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, std::false_type) inline typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, std::false_type)
{ {
return *iter; return *iter;
} }
struct choose_difference_type // A binary metafunction class that always returns bool.
{ template< typename Iterator1, typename Iterator2 >
template <class I1, class I2> using always_bool_t = bool;
struct apply : mpl::eval_if<
std::is_convertible<I2,I1> template< typename Iterator1, typename Iterator2 >
, iterator_difference<I1> using choose_difference_type_t = typename std::conditional<
, iterator_difference<I2> std::is_convertible< Iterator2, Iterator1 >::value,
> iterator_difference< Iterator1 >,
{}; iterator_difference< Iterator2 >
}; >::type::type;
template< template<
class Derived typename Derived,
, class Value typename Value,
, class CategoryOrTraversal typename CategoryOrTraversal,
, class Reference typename Reference,
, class Difference typename Difference,
, bool IsBidirectionalTraversal bool IsBidirectionalTraversal,
, bool IsRandomAccessTraversal bool IsRandomAccessTraversal
> >
class iterator_facade_base; class iterator_facade_base;
@@ -441,16 +431,16 @@ namespace iterators {
// Macros which describe the declarations of binary operators // Macros which describe the declarations of binary operators
#define BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, enabler) \ #define BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, enabler) \
template< \ template< \
class Derived1, class V1, class TC1, class Reference1, class Difference1 \ typename Derived1, typename V1, typename TC1, typename Reference1, typename Difference1, \
, class Derived2, class V2, class TC2, class Reference2, class Difference2 \ typename Derived2, typename V2, typename TC2, typename Reference2, typename Difference2 \
> \ > \
prefix typename enabler< \ prefix typename enabler< \
Derived1, Derived2 \ Derived1, Derived2, \
, typename mpl::apply2<result_type,Derived1,Derived2>::type \ result_type< Derived1, Derived2 > \
>::type \ >::type \
operator op( \ operator op( \
iterator_facade<Derived1, V1, TC1, Reference1, Difference1> const& lhs \ iterator_facade< Derived1, V1, TC1, Reference1, Difference1 > const& lhs, \
, iterator_facade<Derived2, V2, TC2, Reference2, Difference2> const& rhs) iterator_facade< Derived2, V2, TC2, Reference2, Difference2 > const& rhs)
#define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \ #define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable) BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable)
@@ -459,13 +449,13 @@ namespace iterators {
BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable_and_random_access_traversal) BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable_and_random_access_traversal)
#define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \ #define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \
template <class Derived, class V, class TC, class R, class D> \ template< typename Derived, typename V, typename TC, typename R, typename D > \
prefix typename std::enable_if< \ prefix typename std::enable_if< \
boost::iterators::detail::is_traversal_at_least< \ boost::iterators::detail::is_traversal_at_least< \
TC \ TC, \
, boost::iterators::random_access_traversal_tag \ boost::iterators::random_access_traversal_tag \
>::value \ >::value, \
, Derived \ Derived \
>::type operator+ args >::type operator+ args
// //
@@ -479,12 +469,13 @@ namespace iterators {
// //
class iterator_core_access class iterator_core_access
{ {
template <class I, class V, class TC, class R, class D> friend class iterator_facade; template< typename I, typename V, typename TC, typename R, typename D >
template <class I, class V, class TC, class R, class D, bool IsBidirectionalTraversal, bool IsRandomAccessTraversal> friend class iterator_facade;
template< typename I, typename V, typename TC, typename R, typename D, bool IsBidirectionalTraversal, bool IsRandomAccessTraversal >
friend class detail::iterator_facade_base; friend class detail::iterator_facade_base;
#define BOOST_ITERATOR_FACADE_RELATION(op) \ #define BOOST_ITERATOR_FACADE_RELATION(op) \
BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, boost::iterators::detail::always_bool2); BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend, op, boost::iterators::detail::always_bool_t);
BOOST_ITERATOR_FACADE_RELATION(==) BOOST_ITERATOR_FACADE_RELATION(==)
BOOST_ITERATOR_FACADE_RELATION(!=) BOOST_ITERATOR_FACADE_RELATION(!=)
@@ -492,7 +483,7 @@ namespace iterators {
#undef BOOST_ITERATOR_FACADE_RELATION #undef BOOST_ITERATOR_FACADE_RELATION
#define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op) \ #define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op) \
BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(friend,op, boost::iterators::detail::always_bool2); BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(friend, op, boost::iterators::detail::always_bool_t);
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<) BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<)
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>) BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>)
@@ -501,70 +492,62 @@ namespace iterators {
#undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION #undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION
BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD( BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(friend, -, boost::iterators::detail::choose_difference_type_t);
friend, -, boost::iterators::detail::choose_difference_type)
;
BOOST_ITERATOR_FACADE_PLUS_HEAD( BOOST_ITERATOR_FACADE_PLUS_HEAD(
friend inline friend inline,
, (iterator_facade<Derived, V, TC, R, D> const& (iterator_facade< Derived, V, TC, R, D > const&, typename Derived::difference_type)
, typename Derived::difference_type) );
)
;
BOOST_ITERATOR_FACADE_PLUS_HEAD( BOOST_ITERATOR_FACADE_PLUS_HEAD(
friend inline friend inline,
, (typename Derived::difference_type (typename Derived::difference_type, iterator_facade< Derived, V, TC, R, D > const&)
, iterator_facade<Derived, V, TC, R, D> const&) );
)
;
template <class Facade> template< typename Facade >
static typename Facade::reference dereference(Facade const& f) static typename Facade::reference dereference(Facade const& f)
{ {
return f.dereference(); return f.dereference();
} }
template <class Facade> template< typename Facade >
static void increment(Facade& f) static void increment(Facade& f)
{ {
f.increment(); f.increment();
} }
template <class Facade> template< typename Facade >
static void decrement(Facade& f) static void decrement(Facade& f)
{ {
f.decrement(); f.decrement();
} }
template <class Facade1, class Facade2> template< typename Facade1, typename Facade2 >
static bool equal(Facade1 const& f1, Facade2 const& f2, std::true_type) static bool equal(Facade1 const& f1, Facade2 const& f2, std::true_type)
{ {
return f1.equal(f2); return f1.equal(f2);
} }
template <class Facade1, class Facade2> template< typename Facade1, typename Facade2 >
static bool equal(Facade1 const& f1, Facade2 const& f2, std::false_type) static bool equal(Facade1 const& f1, Facade2 const& f2, std::false_type)
{ {
return f2.equal(f1); return f2.equal(f1);
} }
template <class Facade> template< typename Facade >
static void advance(Facade& f, typename Facade::difference_type n) static void advance(Facade& f, typename Facade::difference_type n)
{ {
f.advance(n); f.advance(n);
} }
template <class Facade1, class Facade2> template< typename Facade1, typename Facade2 >
static typename Facade1::difference_type distance_from( static typename Facade1::difference_type distance_from(Facade1 const& f1, Facade2 const& f2, std::true_type)
Facade1 const& f1, Facade2 const& f2, std::true_type)
{ {
return -f1.distance_to(f2); return -f1.distance_to(f2);
} }
template <class Facade1, class Facade2> template< typename Facade1, typename Facade2 >
static typename Facade2::difference_type distance_from( static typename Facade2::difference_type distance_from(Facade1 const& f1, Facade2 const& f2, std::false_type)
Facade1 const& f1, Facade2 const& f2, std::false_type)
{ {
return f2.distance_to(f1); return f2.distance_to(f1);
} }
@@ -572,52 +555,52 @@ namespace iterators {
// //
// Curiously Recurring Template interface. // Curiously Recurring Template interface.
// //
template <class I, class V, class TC, class R, class D> template< typename I, typename V, typename TC, typename R, typename D >
static I& derived(iterator_facade< I, V, TC, R, D >& facade) static I& derived(iterator_facade< I, V, TC, R, D >& facade)
{ {
return *static_cast< I* >(&facade); return *static_cast< I* >(&facade);
} }
template <class I, class V, class TC, class R, class D> template< typename I, typename V, typename TC, typename R, typename D >
static I const& derived(iterator_facade< I, V, TC, R, D > const& facade) static I const& derived(iterator_facade< I, V, TC, R, D > const& facade)
{ {
return *static_cast< I const* >(&facade); return *static_cast< I const* >(&facade);
} }
// objects of this class are useless // objects of this class are useless
BOOST_DELETED_FUNCTION(iterator_core_access()) iterator_core_access() = delete;
}; };
namespace detail { namespace detail {
// Implementation for forward traversal iterators // Implementation for forward traversal iterators
template< template<
class Derived typename Derived,
, class Value typename Value,
, class CategoryOrTraversal typename CategoryOrTraversal,
, class Reference typename Reference,
, class Difference typename Difference
> >
class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false > class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
{ {
private: private:
typedef boost::iterators::detail::iterator_facade_types< using associated_types = boost::iterators::detail::iterator_facade_types<
Value, CategoryOrTraversal, Reference, Difference Value, CategoryOrTraversal, Reference, Difference
> associated_types; >;
typedef boost::iterators::detail::operator_arrow_dispatch< using operator_arrow_dispatch_ = boost::iterators::detail::operator_arrow_dispatch<
Reference Reference,
, typename associated_types::pointer typename associated_types::pointer
> operator_arrow_dispatch_; >;
public: public:
typedef typename associated_types::value_type value_type; using value_type = typename associated_types::value_type;
typedef Reference reference; using reference = Reference;
typedef Difference difference_type; using difference_type = Difference;
typedef typename operator_arrow_dispatch_::result_type pointer; using pointer = typename operator_arrow_dispatch_::result_type;
typedef typename associated_types::iterator_category iterator_category; using iterator_category = typename associated_types::iterator_category;
public: public:
reference operator*() const reference operator*() const
@@ -653,11 +636,11 @@ namespace iterators {
// Implementation for bidirectional traversal iterators // Implementation for bidirectional traversal iterators
template< template<
class Derived typename Derived,
, class Value typename Value,
, class CategoryOrTraversal typename CategoryOrTraversal,
, class Reference typename Reference,
, class Difference typename Difference
> >
class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false > : class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false > :
public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false > public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
@@ -679,31 +662,29 @@ namespace iterators {
// Implementation for random access traversal iterators // Implementation for random access traversal iterators
template< template<
class Derived typename Derived,
, class Value typename Value,
, class CategoryOrTraversal typename CategoryOrTraversal,
, class Reference typename Reference,
, class Difference typename Difference
> >
class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, true > : class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, true > :
public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false > public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false >
{ {
private: private:
typedef iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false > base_type; using base_type = iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false >;
public: public:
typedef typename base_type::reference reference; using reference = typename base_type::reference;
typedef typename base_type::difference_type difference_type; using difference_type = typename base_type::difference_type;
public: public:
typename boost::iterators::detail::operator_brackets_result< Derived, Value, reference >::type typename boost::iterators::detail::operator_brackets_result< Derived, Value, reference >::type
operator[](difference_type n) const operator[](difference_type n) const
{ {
using use_proxy = boost::iterators::detail::use_operator_brackets_proxy<Value, Reference>;
return boost::iterators::detail::make_operator_brackets_result< Derived >( return boost::iterators::detail::make_operator_brackets_result< Derived >(
this->derived() + n this->derived() + n,
, std::integral_constant<bool, use_proxy::value>{} std::integral_constant< bool, boost::iterators::detail::use_operator_brackets_proxy< Value, Reference >::value >{}
); );
} }
@@ -733,11 +714,11 @@ namespace iterators {
// standard-conforming iterators. // standard-conforming iterators.
// //
template< template<
class Derived // The derived iterator type being constructed typename Derived, // The derived iterator type being constructed
, class Value typename Value,
, class CategoryOrTraversal typename CategoryOrTraversal,
, class Reference = Value& typename Reference,
, class Difference = std::ptrdiff_t typename Difference
> >
class iterator_facade : class iterator_facade :
public detail::iterator_facade_base< public detail::iterator_facade_base<
@@ -752,15 +733,12 @@ namespace iterators {
{ {
protected: protected:
// For use by derived classes // For use by derived classes
typedef iterator_facade<Derived,Value,CategoryOrTraversal,Reference,Difference> iterator_facade_; using iterator_facade_ = iterator_facade< Derived, Value, CategoryOrTraversal, Reference, Difference >;
}; };
template <class I, class V, class TC, class R, class D> template< typename I, typename V, typename TC, typename R, typename D >
inline typename boost::iterators::detail::postfix_increment_result< I, V, R, TC >::type inline typename boost::iterators::detail::postfix_increment_result< I, V, R, TC >::type
operator++( operator++(iterator_facade< I, V, TC, R, D >& i, int)
iterator_facade<I,V,TC,R,D>& i
, int
)
{ {
typename boost::iterators::detail::postfix_increment_result< I, V, R, TC >::type typename boost::iterators::detail::postfix_increment_result< I, V, R, TC >::type
tmp(*static_cast< I* >(&i)); tmp(*static_cast< I* >(&i));
@@ -842,18 +820,18 @@ namespace iterators {
BOOST_ITERATOR_FACADE_INTEROP_HEAD(inline, op, result_type) \ BOOST_ITERATOR_FACADE_INTEROP_HEAD(inline, op, result_type) \
{ \ { \
return_prefix iterator_core_access::base_op( \ return_prefix iterator_core_access::base_op( \
*static_cast<Derived1 const*>(&lhs) \ *static_cast< Derived1 const* >(&lhs), \
, *static_cast<Derived2 const*>(&rhs) \ *static_cast< Derived2 const* >(&rhs), \
, std::integral_constant<bool, std::is_convertible<Derived2, Derived1>::value>() \ std::integral_constant< bool, std::is_convertible< Derived2, Derived1 >::value >() \
); \ ); \
} }
#define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \ #define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \
BOOST_ITERATOR_FACADE_INTEROP( \ BOOST_ITERATOR_FACADE_INTEROP( \
op \ op, \
, boost::iterators::detail::always_bool2 \ boost::iterators::detail::always_bool_t, \
, return_prefix \ return_prefix, \
, base_op \ base_op \
) )
BOOST_ITERATOR_FACADE_RELATION(==, return, equal) BOOST_ITERATOR_FACADE_RELATION(==, return, equal)
@@ -865,20 +843,19 @@ namespace iterators {
#define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(op, result_type, return_prefix, base_op) \ #define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(op, result_type, return_prefix, base_op) \
BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(inline, op, result_type) \ BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(inline, op, result_type) \
{ \ { \
using boost::iterators::detail::is_traversal_at_least; \
return_prefix iterator_core_access::base_op( \ return_prefix iterator_core_access::base_op( \
*static_cast<Derived1 const*>(&lhs) \ *static_cast< Derived1 const* >(&lhs), \
, *static_cast<Derived2 const*>(&rhs) \ *static_cast< Derived2 const* >(&rhs), \
, std::integral_constant<bool, std::is_convertible<Derived2, Derived1>::value>() \ std::integral_constant< bool, std::is_convertible< Derived2, Derived1 >::value >() \
); \ ); \
} }
#define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op, return_prefix, base_op) \ #define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op, return_prefix, base_op) \
BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS( \ BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS( \
op \ op, \
, boost::iterators::detail::always_bool2 \ boost::iterators::detail::always_bool_t, \
, return_prefix \ return_prefix, \
, base_op \ base_op \
) )
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<, return 0 >, distance_from) BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<, return 0 >, distance_from)
@@ -890,10 +867,10 @@ namespace iterators {
// operator- requires an additional part in the static assertion // operator- requires an additional part in the static assertion
BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS( BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(
- -,
, boost::iterators::detail::choose_difference_type boost::iterators::detail::choose_difference_type_t,
, return return,
, distance_from distance_from
) )
#undef BOOST_ITERATOR_FACADE_INTEROP #undef BOOST_ITERATOR_FACADE_INTEROP
@@ -906,15 +883,8 @@ namespace iterators {
return tmp += n; \ return tmp += n; \
} }
BOOST_ITERATOR_FACADE_PLUS(( BOOST_ITERATOR_FACADE_PLUS((iterator_facade< Derived, V, TC, R, D > const& i, typename Derived::difference_type n))
iterator_facade<Derived, V, TC, R, D> const& i BOOST_ITERATOR_FACADE_PLUS((typename Derived::difference_type n, iterator_facade< Derived, V, TC, R, D > const& i))
, typename Derived::difference_type n
))
BOOST_ITERATOR_FACADE_PLUS((
typename Derived::difference_type n
, iterator_facade<Derived, V, TC, R, D> const& i
))
#undef BOOST_ITERATOR_FACADE_PLUS #undef BOOST_ITERATOR_FACADE_PLUS
#undef BOOST_ITERATOR_FACADE_PLUS_HEAD #undef BOOST_ITERATOR_FACADE_PLUS_HEAD