Removed MPL usage from iterator_adaptor.hpp.

This commit is contained in:
Andrey Semashev 2025-02-01 02:03:06 +03:00
parent 4f5f61e37b
commit 1875d95019

View File

@ -7,10 +7,10 @@
#ifndef BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
#define BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
#include <boost/core/use_default.hpp>
#include <type_traits>
#include <boost/core/use_default.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/iterator_traits.hpp>
@ -25,23 +25,18 @@ namespace iterators {
// explicitly in order to specify that the default should be used.
using boost::use_default;
} // namespace iterators
namespace iterators {
namespace detail
{
namespace detail {
//
// Result type used in enable_if_convertible meta function.
// This can be an incomplete type, as only pointers to
// enable_if_convertible< ... >::type are used.
// We could have used void for this, but conversion to
// void* is just to easy.
// void* is just too easy.
//
struct enable_type;
}
} // namespace detail
//
// enable_if for use in adapted iterators constructors.
@ -82,81 +77,102 @@ namespace iterators {
// on operator implementation for consequences.
//
template< typename From, typename To >
struct enable_if_convertible
: std::enable_if<
std::is_convertible<From, To>::value
, boost::iterators::detail::enable_type
struct enable_if_convertible :
public std::enable_if<
std::is_convertible< From, To >::value,
boost::iterators::detail::enable_type
>
{};
//
// Default template argument handling for iterator_adaptor
//
namespace detail
{
namespace detail {
// If T is use_default, return the result of invoking
// DefaultNullaryFn, otherwise return T.
template <class T, class DefaultNullaryFn>
template< typename T, typename DefaultNullaryFn >
struct ia_dflt_help
: mpl::eval_if<
std::is_same<T, use_default>
, DefaultNullaryFn
, mpl::identity<T>
>
{
using type = T;
};
template< typename DefaultNullaryFn >
struct ia_dflt_help< use_default, DefaultNullaryFn >
{
using type = typename DefaultNullaryFn::type;
};
template< typename T, typename DefaultNullaryFn >
using ia_dflt_help_t = typename ia_dflt_help< T, DefaultNullaryFn >::type;
// If T is use_default, return the result of invoking
// DefaultNullaryFn, otherwise - of NondefaultNullaryFn.
template< typename T, typename DefaultNullaryFn, typename NondefaultNullaryFn >
struct ia_eval_if_default
{
using type = typename NondefaultNullaryFn::type;
};
template< typename DefaultNullaryFn, typename NondefaultNullaryFn >
struct ia_eval_if_default< use_default, DefaultNullaryFn, NondefaultNullaryFn >
{
using type = typename DefaultNullaryFn::type;
};
template< typename T, typename DefaultNullaryFn, typename NondefaultNullaryFn >
using ia_eval_if_default_t = typename ia_eval_if_default< T, DefaultNullaryFn, NondefaultNullaryFn >::type;
// A metafunction which computes an iterator_adaptor's base class,
// a specialization of iterator_facade.
template<
class Derived
, class Base
, class Value
, class Traversal
, class Reference
, class Difference
typename Derived,
typename Base,
typename Value,
typename Traversal,
typename Reference,
typename Difference
>
struct iterator_adaptor_base
{
typedef iterator_facade<
Derived
using iterator_adaptor_base_t = iterator_facade<
Derived,
#ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
, typename boost::iterators::detail::ia_dflt_help<
Value
, mpl::eval_if<
std::is_same<Reference,use_default>
, iterator_value<Base>
, std::remove_reference<Reference>
detail::ia_dflt_help_t<
Value,
detail::ia_eval_if_default<
Reference,
iterator_value< Base >,
std::remove_reference< Reference >
>
>::type
>,
#else
, typename boost::iterators::detail::ia_dflt_help<
Value, iterator_value<Base>
>::type
detail::ia_dflt_help_t<
Value,
iterator_value< Base >
>,
#endif
, typename boost::iterators::detail::ia_dflt_help<
Traversal
, iterator_traversal<Base>
>::type
detail::ia_dflt_help_t<
Traversal,
iterator_traversal< Base >
>,
, typename boost::iterators::detail::ia_dflt_help<
Reference
, mpl::eval_if<
std::is_same<Value,use_default>
, iterator_reference<Base>
, std::add_lvalue_reference<Value>
detail::ia_dflt_help_t<
Reference,
detail::ia_eval_if_default<
Value,
iterator_reference< Base >,
std::add_lvalue_reference< Value >
>
>::type
>,
, typename boost::iterators::detail::ia_dflt_help<
Difference, iterator_difference<Base>
>::type
detail::ia_dflt_help_t<
Difference,
iterator_difference< Base >
>
type;
};
}
>;
} // namespace detail
//
// Iterator Adaptor
@ -184,49 +200,46 @@ namespace iterators {
// supplied, iterator_traits<Base>::difference_type is used.
//
template<
class Derived
, class Base
, class Value = use_default
, class Traversal = use_default
, class Reference = use_default
, class Difference = use_default
typename Derived,
typename Base,
typename Value = use_default,
typename Traversal = use_default,
typename Reference = use_default,
typename Difference = use_default
>
class iterator_adaptor
: public boost::iterators::detail::iterator_adaptor_base<
class iterator_adaptor :
public detail::iterator_adaptor_base_t<
Derived, Base, Value, Traversal, Reference, Difference
>::type
>
{
friend class iterator_core_access;
protected:
typedef typename boost::iterators::detail::iterator_adaptor_base<
using super_t = detail::iterator_adaptor_base_t<
Derived, Base, Value, Traversal, Reference, Difference
>::type super_t;
public:
iterator_adaptor() {}
>;
explicit iterator_adaptor(Base const& iter)
: m_iterator(iter)
public:
using base_type = Base;
iterator_adaptor() = default;
explicit iterator_adaptor(Base const& iter) :
m_iterator(iter)
{
}
typedef Base base_type;
Base const& base() const
{ return m_iterator; }
base_type const& base() const { return m_iterator; }
protected:
// for convenience in derived classes
typedef iterator_adaptor<Derived,Base,Value,Traversal,Reference,Difference> iterator_adaptor_;
using iterator_adaptor_ = iterator_adaptor< Derived, Base, Value, Traversal, Reference, Difference >;
//
// lvalue access to the Base object for Derived
//
Base const& base_reference() const
{ return m_iterator; }
Base& base_reference()
{ return m_iterator; }
Base& base_reference() { return m_iterator; }
Base const& base_reference() const { return m_iterator; }
private:
//
@ -235,12 +248,9 @@ namespace iterators {
// will often result in an error. Derived classes should use
// base_reference(), above, to get direct access to m_iterator.
//
typename super_t::reference dereference() const
{ return *m_iterator; }
typename super_t::reference dereference() const { return *m_iterator; }
template <
class OtherDerived, class OtherIterator, class V, class C, class R, class D
>
template< typename OtherDerived, typename OtherIterator, typename V, typename C, typename R, typename D >
bool equal(iterator_adaptor< OtherDerived, OtherIterator, V, C, R, D > const& x) const
{
// Maybe readd with same_distance
@ -250,16 +260,12 @@ namespace iterators {
return m_iterator == x.base();
}
typedef typename iterator_category_to_traversal<
typename super_t::iterator_category
>::type my_traversal;
using my_traversal = typename iterator_category_to_traversal< typename super_t::iterator_category >::type;
void advance(typename super_t::difference_type n)
{
static_assert(
std::is_convertible<my_traversal, random_access_traversal_tag>::value,
"Iterator must support random access traversal."
);
static_assert(detail::is_traversal_at_least< my_traversal, random_access_traversal_tag >::value,
"Iterator must support random access traversal.");
m_iterator += n;
}
@ -267,23 +273,16 @@ namespace iterators {
void decrement()
{
static_assert(
std::is_convertible<my_traversal, bidirectional_traversal_tag>::value,
"Iterator must support bidirectional traversal."
);
static_assert(detail::is_traversal_at_least< my_traversal, bidirectional_traversal_tag >::value,
"Iterator must support bidirectional traversal.");
--m_iterator;
}
template <
class OtherDerived, class OtherIterator, class V, class C, class R, class D
>
typename super_t::difference_type distance_to(
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const
template< typename OtherDerived, typename OtherIterator, typename V, typename C, typename R, typename D >
typename super_t::difference_type distance_to(iterator_adaptor< OtherDerived, OtherIterator, V, C, R, D > const& y) const
{
static_assert(
std::is_convertible<my_traversal, random_access_traversal_tag>::value,
"Super iterator must support random access traversal."
);
static_assert(detail::is_traversal_at_least< my_traversal, random_access_traversal_tag >::value,
"Super iterator must support random access traversal.");
// Maybe readd with same_distance
// BOOST_STATIC_ASSERT(
// (detail::same_category_and_difference<Derived,OtherDerived>::value)