Removed direct usage of MPL from zip_iterator.hpp.

MPL is still used through Boost.Fusion, but that is a matter of
optimizing Boost.Fusion now.
This commit is contained in:
Andrey Semashev
2025-02-05 03:29:14 +03:00
parent dc57bcf319
commit aadd90df45

View File

@ -8,19 +8,16 @@
#ifndef BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_ #ifndef BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_
#define BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_ #define BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_
#include <utility> // for std::pair
#include <boost/iterator/iterator_traits.hpp> #include <boost/iterator/iterator_traits.hpp>
#include <boost/iterator/iterator_facade.hpp> #include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/enable_if_convertible.hpp> #include <boost/iterator/enable_if_convertible.hpp>
#include <boost/iterator/iterator_categories.hpp> #include <boost/iterator/iterator_categories.hpp>
#include <boost/iterator/minimum_category.hpp> #include <boost/iterator/min_category.hpp>
#include <utility> // for std::pair
#include <boost/mpl/at.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mp11/list.hpp>
#include <boost/mp11/utility.hpp>
#include <boost/fusion/adapted/boost_tuple.hpp> // for backward compatibility #include <boost/fusion/adapted/boost_tuple.hpp> // for backward compatibility
#include <boost/fusion/algorithm/iteration/for_each.hpp> #include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/fusion/algorithm/transformation/transform.hpp> #include <boost/fusion/algorithm/transformation/transform.hpp>
@ -30,14 +27,26 @@
#include <boost/fusion/support/tag_of_fwd.hpp> #include <boost/fusion/support/tag_of_fwd.hpp>
namespace boost { namespace boost {
// Forward declarations for Boost.Tuple support
namespace tuples {
struct null_type;
template< class, class >
struct cons;
} // namespace tuples
// Forward declarations for Boost.Fusion support
namespace fusion {
struct void_;
} // namespace fusion
namespace iterators { namespace iterators {
// Zip iterator forward declaration for zip_iterator_base // Zip iterator forward declaration for zip_iterator_base
template< typename IteratorTuple > template< typename IteratorTuple >
class zip_iterator; class zip_iterator;
namespace detail namespace detail {
{
// Functors to be used with tuple algorithms // Functors to be used with tuple algorithms
// //
@ -45,30 +54,29 @@ namespace iterators {
class advance_iterator class advance_iterator
{ {
public: public:
advance_iterator(DiffType step) : m_step(step) {} advance_iterator(DiffType step) :
m_step(step)
{}
template< typename Iterator > template< typename Iterator >
void operator()(Iterator& it) const void operator()(Iterator& it) const { it += m_step; }
{ it += m_step; }
private: private:
DiffType m_step; DiffType m_step;
}; };
//
struct increment_iterator struct increment_iterator
{ {
template< typename Iterator > template< typename Iterator >
void operator()(Iterator& it) const void operator()(Iterator& it) const { ++it; }
{ ++it; }
}; };
//
struct decrement_iterator struct decrement_iterator
{ {
template< typename Iterator > template< typename Iterator >
void operator()(Iterator& it) const void operator()(Iterator& it) const { --it; }
{ --it; }
}; };
//
struct dereference_iterator struct dereference_iterator
{ {
template< typename > template< typename >
@ -77,76 +85,118 @@ namespace iterators {
template< typename This, typename Iterator > template< typename This, typename Iterator >
struct result< This(Iterator) > struct result< This(Iterator) >
{ {
typedef typename using type = iterator_reference_t<
std::remove_cv<typename std::remove_reference<Iterator>::type>::type typename std::remove_cv< typename std::remove_reference< Iterator >::type >::type
iterator; >;
typedef typename iterator_reference<iterator>::type type;
}; };
template< typename Iterator > template< typename Iterator >
typename result<dereference_iterator(Iterator)>::type typename result< dereference_iterator(Iterator) >::type operator()(Iterator const& it) const
operator()(Iterator const& it) const {
{ return *it; } return *it;
}
}; };
// The trait checks if the type is a trailing "null" type used to indicate unused template parameters in non-variadic types
template< typename T >
struct is_trailing_null_type : std::false_type {};
template< typename T >
struct is_trailing_null_type< const T > : is_trailing_null_type< T > {};
template< >
struct is_trailing_null_type< tuples::null_type > : std::true_type {};
template< >
struct is_trailing_null_type< fusion::void_ > : std::true_type {};
// The trait checks if the tail is either an empty type list or begins with a "null" type, which indicates that the rest
// of the types in the tail are unused
template< typename... Tail >
struct is_tail_empty;
template< >
struct is_tail_empty< > : std::true_type {};
template< typename Front, typename... Tail >
struct is_tail_empty< Front, Tail... > : detail::is_trailing_null_type< Front > {};
// Metafunction to obtain the type of the tuple whose element types // Metafunction to obtain the type of the tuple whose element types
// are the reference types of an iterator tuple. // are the reference types of an iterator tuple.
//
template< typename IteratorTuple > template< typename IteratorTuple >
struct tuple_of_references struct tuple_of_references;
: mpl::transform<
IteratorTuple, template< typename IteratorTuple >
iterator_reference<mpl::_1> using tuple_of_references_t = typename tuple_of_references< IteratorTuple >::type;
template< template< typename... > class Tuple, typename... Iterators >
struct tuple_of_references< Tuple< Iterators... > >
{
// Note: non-variadic Boost.Tuple and Boost.Fusion need special handling
// to avoid instantiating iterator traits on the trailing "null" types.
// If not that, we could simply do
// mp11::mp_transform< iterator_reference_t, IteratorTuple >.
using type = Tuple<
mp11::mp_eval_if<
detail::is_trailing_null_type< Iterators >,
Iterators,
iterator_reference_t, Iterators
>...
>;
};
template< typename Front, typename Tail >
struct tuple_of_references< tuples::cons< Front, Tail > >
{
using type = tuples::cons<
iterator_reference_t< Front >,
mp11::mp_eval_if<
detail::is_trailing_null_type< Tail >,
Tail,
detail::tuple_of_references_t, Tail
> >
{ >;
}; };
// Specialization for std::pair // Metafunction to obtain the minimal traversal tag in a list
template<typename Iterator1, typename Iterator2>
struct tuple_of_references<std::pair<Iterator1, Iterator2> >
{
typedef std::pair<
typename iterator_reference<Iterator1>::type
, typename iterator_reference<Iterator2>::type
> type;
};
// Metafunction to obtain the minimal traversal tag in a tuple
// of iterators. // of iterators.
// template< typename IteratorList >
template<typename IteratorTuple> struct minimum_traversal_category_in_iterator_list;
struct minimum_traversal_category_in_iterator_tuple
{
typedef typename mpl::transform<
IteratorTuple
, pure_traversal_tag<iterator_traversal<> >
>::type tuple_of_traversal_tags;
typedef typename mpl::fold< template< typename IteratorList >
tuple_of_traversal_tags using minimum_traversal_category_in_iterator_list_t = typename minimum_traversal_category_in_iterator_list< IteratorList >::type;
, random_access_traversal_tag
, minimum_category<> template< typename FrontTraversal, typename Tail >
>::type type; using minimum_traversal_category_in_tail_t = min_category_t<
FrontTraversal,
minimum_traversal_category_in_iterator_list_t< Tail >
>;
template< template< typename... > class List, typename Front, typename... Tail >
struct minimum_traversal_category_in_iterator_list< List< Front, Tail... > >
{
using front_traversal = pure_iterator_traversal_t< Front >;
// Note: non-variadic Boost.Tuple and Boost.Fusion need special handling
// to avoid instantiating iterator traits on the trailing "null" types.
// Note 2: we rename the List to mp_list in the process of iteration to
// avoid specifying one template parameter to std::pair, if List is std::pair.
using type = mp11::mp_eval_if<
detail::is_tail_empty< Tail... >,
front_traversal,
minimum_traversal_category_in_tail_t,
front_traversal,
mp11::mp_list< Tail... >
>;
}; };
template<typename Iterator1, typename Iterator2> template< typename Front, typename Tail >
struct minimum_traversal_category_in_iterator_tuple<std::pair<Iterator1, Iterator2> > struct minimum_traversal_category_in_iterator_list< tuples::cons< Front, Tail > >
{ {
typedef typename pure_traversal_tag< using front_traversal = pure_iterator_traversal_t< Front >;
typename iterator_traversal<Iterator1>::type
>::type iterator1_traversal;
typedef typename pure_traversal_tag<
typename iterator_traversal<Iterator2>::type
>::type iterator2_traversal;
typedef typename minimum_category< using type = mp11::mp_eval_if<
iterator1_traversal detail::is_trailing_null_type< Tail >,
, typename minimum_category< front_traversal,
iterator2_traversal minimum_traversal_category_in_tail_t,
, random_access_traversal_tag front_traversal,
>::type Tail
>::type type; >;
}; };
/////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////
@ -162,49 +212,37 @@ namespace iterators {
private: private:
// Reference type is the type of the tuple obtained from the // Reference type is the type of the tuple obtained from the
// iterators' reference types. // iterators' reference types.
typedef typename using reference = detail::tuple_of_references_t< IteratorTuple >;
detail::tuple_of_references<IteratorTuple>::type reference;
// Value type is the same as reference type. // Value type is the same as reference type.
typedef reference value_type; using value_type = reference;
// Difference type is the first iterator's difference type // Difference type is the first iterator's difference type
typedef typename iterator_difference< using difference_type = iterator_difference_t< mp11::mp_front< IteratorTuple > >;
typename mpl::at_c<IteratorTuple, 0>::type
>::type difference_type;
// Traversal catetgory is the minimum traversal category in the // Traversal catetgory is the minimum traversal category in the
// iterator tuple. // iterator tuple.
typedef typename using traversal_category = detail::minimum_traversal_category_in_iterator_list_t< IteratorTuple >;
detail::minimum_traversal_category_in_iterator_tuple<
IteratorTuple
>::type traversal_category;
public:
public:
// The iterator facade type from which the zip iterator will // The iterator facade type from which the zip iterator will
// be derived. // be derived.
typedef iterator_facade< using type = iterator_facade<
zip_iterator< IteratorTuple >, zip_iterator< IteratorTuple >,
value_type, value_type,
traversal_category, traversal_category,
reference, reference,
difference_type difference_type
> type; >;
}; };
template <> template< typename Reference >
struct zip_iterator_base<int>
{
typedef int type;
};
template <typename reference>
struct converter struct converter
{ {
template< typename Seq > template< typename Seq >
static reference call(Seq seq) static Reference call(Seq seq)
{ {
typedef typename fusion::traits::tag_of<reference>::type tag; using tag = typename fusion::traits::tag_of< Reference >::type;
return fusion::convert< tag >(seq); return fusion::convert< tag >(seq);
} }
}; };
@ -212,16 +250,16 @@ namespace iterators {
template< typename Reference1, typename Reference2 > template< typename Reference1, typename Reference2 >
struct converter< std::pair< Reference1, Reference2 > > struct converter< std::pair< Reference1, Reference2 > >
{ {
typedef std::pair<Reference1, Reference2> reference; using reference = std::pair< Reference1, Reference2 >;
template< typename Seq > template< typename Seq >
static reference call(Seq seq) static reference call(Seq seq)
{ {
return reference( return reference(fusion::at_c< 0 >(seq), fusion::at_c< 1 >(seq));
fusion::at_c<0>(seq)
, fusion::at_c<1>(seq));
} }
}; };
}
} // namespace detail
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
// //
@ -231,44 +269,34 @@ namespace iterators {
class zip_iterator : class zip_iterator :
public detail::zip_iterator_base< IteratorTuple >::type public detail::zip_iterator_base< IteratorTuple >::type
{ {
// Typedef super_t as our base class. // Typedef super_t as our base class.
typedef typename using super_t = typename detail::zip_iterator_base< IteratorTuple >::type;
detail::zip_iterator_base<IteratorTuple>::type super_t;
// iterator_core_access is the iterator's best friend. // iterator_core_access is the iterator's best friend.
friend class iterator_core_access; friend class iterator_core_access;
public: public:
// Construction // Construction
// ============ // ============
// Default constructor // Default constructor
zip_iterator() { } zip_iterator() = default;
// Constructor from iterator tuple // Constructor from iterator tuple
zip_iterator(IteratorTuple iterator_tuple) zip_iterator(IteratorTuple iterator_tuple) :
: m_iterator_tuple(iterator_tuple) m_iterator_tuple(iterator_tuple)
{} {}
// Copy constructor // Copy constructor
template<typename OtherIteratorTuple> template< typename OtherIteratorTuple, typename = enable_if_convertible_t< OtherIteratorTuple, IteratorTuple > >
zip_iterator( zip_iterator(zip_iterator< OtherIteratorTuple > const& other) :
const zip_iterator<OtherIteratorTuple>& other, m_iterator_tuple(other.get_iterator_tuple())
typename enable_if_convertible<
OtherIteratorTuple,
IteratorTuple
>::type* = 0
) : m_iterator_tuple(other.get_iterator_tuple())
{} {}
// Get method for the iterator tuple. // Get method for the iterator tuple.
const IteratorTuple& get_iterator_tuple() const IteratorTuple const& get_iterator_tuple() const { return m_iterator_tuple; }
{ return m_iterator_tuple; }
private: private:
// Implementation of Iterator Operations // Implementation of Iterator Operations
// ===================================== // =====================================
@ -276,11 +304,9 @@ namespace iterators {
// iterators in the iterator tuple. // iterators in the iterator tuple.
typename super_t::reference dereference() const typename super_t::reference dereference() const
{ {
typedef typename super_t::reference reference; using reference = typename super_t::reference;
typedef detail::converter<reference> gen; using gen = detail::converter< reference >;
return gen::call(fusion::transform( return gen::call(fusion::transform(get_iterator_tuple(), detail::dereference_iterator()));
get_iterator_tuple(),
detail::dereference_iterator()));
} }
// Two zip iterators are equal if all iterators in the iterator // Two zip iterators are equal if all iterators in the iterator
@ -294,63 +320,54 @@ namespace iterators {
// of #ifdefs here. // of #ifdefs here.
// //
template< typename OtherIteratorTuple > template< typename OtherIteratorTuple >
bool equal(const zip_iterator<OtherIteratorTuple>& other) const bool equal(zip_iterator< OtherIteratorTuple > const& other) const
{ {
return fusion::equal_to( return fusion::equal_to(get_iterator_tuple(), other.get_iterator_tuple());
get_iterator_tuple(),
other.get_iterator_tuple());
} }
// Advancing a zip iterator means to advance all iterators in the // Advancing a zip iterator means to advance all iterators in the
// iterator tuple. // iterator tuple.
void advance(typename super_t::difference_type n) void advance(typename super_t::difference_type n)
{ {
fusion::for_each( fusion::for_each(m_iterator_tuple, detail::advance_iterator< typename super_t::difference_type >(n));
m_iterator_tuple,
detail::advance_iterator<BOOST_DEDUCED_TYPENAME super_t::difference_type>(n));
} }
// Incrementing a zip iterator means to increment all iterators in // Incrementing a zip iterator means to increment all iterators in
// the iterator tuple. // the iterator tuple.
void increment() void increment()
{ {
fusion::for_each( fusion::for_each(m_iterator_tuple, detail::increment_iterator());
m_iterator_tuple,
detail::increment_iterator());
} }
// Decrementing a zip iterator means to decrement all iterators in // Decrementing a zip iterator means to decrement all iterators in
// the iterator tuple. // the iterator tuple.
void decrement() void decrement()
{ {
fusion::for_each( fusion::for_each(m_iterator_tuple, detail::decrement_iterator());
m_iterator_tuple,
detail::decrement_iterator());
} }
// Distance is calculated using the first iterator in the tuple. // Distance is calculated using the first iterator in the tuple.
template< typename OtherIteratorTuple > template< typename OtherIteratorTuple >
typename super_t::difference_type distance_to( typename super_t::difference_type distance_to(zip_iterator< OtherIteratorTuple > const& other) const
const zip_iterator<OtherIteratorTuple>& other
) const
{ {
return fusion::at_c<0>(other.get_iterator_tuple()) - return fusion::at_c< 0 >(other.get_iterator_tuple()) - fusion::at_c< 0 >(this->get_iterator_tuple());
fusion::at_c<0>(this->get_iterator_tuple());
} }
private:
// Data Members // Data Members
// ============ // ============
// The iterator tuple. // The iterator tuple.
IteratorTuple m_iterator_tuple; IteratorTuple m_iterator_tuple;
}; };
// Make function for zip iterator // Make function for zip iterator
// //
template< typename IteratorTuple > template< typename IteratorTuple >
inline zip_iterator<IteratorTuple> inline zip_iterator< IteratorTuple > make_zip_iterator(IteratorTuple t)
make_zip_iterator(IteratorTuple t) {
{ return zip_iterator<IteratorTuple>(t); } return zip_iterator< IteratorTuple >(t);
}
} // namespace iterators } // namespace iterators