From aadd90df458d2f49e4df8a13fff9389ce591fc47 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Wed, 5 Feb 2025 03:29:14 +0300 Subject: [PATCH] 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. --- include/boost/iterator/zip_iterator.hpp | 523 ++++++++++++------------ 1 file changed, 270 insertions(+), 253 deletions(-) diff --git a/include/boost/iterator/zip_iterator.hpp b/include/boost/iterator/zip_iterator.hpp index ea48b45..0df6602 100644 --- a/include/boost/iterator/zip_iterator.hpp +++ b/include/boost/iterator/zip_iterator.hpp @@ -6,21 +6,18 @@ // http://www.boost.org/LICENSE_1_0.txt) #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 // for std::pair #include #include #include #include -#include - -#include // for std::pair - -#include -#include -#include -#include +#include +#include +#include #include // for backward compatibility #include #include @@ -30,245 +27,276 @@ #include 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 { - // Zip iterator forward declaration for zip_iterator_base - template - class zip_iterator; +// Zip iterator forward declaration for zip_iterator_base +template< typename IteratorTuple > +class zip_iterator; - namespace detail - { +namespace detail { - // Functors to be used with tuple algorithms - // - template - class advance_iterator +// Functors to be used with tuple algorithms +// +template< typename DiffType > +class advance_iterator +{ +public: + advance_iterator(DiffType step) : + m_step(step) + {} + + template< typename Iterator > + void operator()(Iterator& it) const { it += m_step; } + +private: + DiffType m_step; +}; + +struct increment_iterator +{ + template< typename Iterator > + void operator()(Iterator& it) const { ++it; } +}; + +struct decrement_iterator +{ + template< typename Iterator > + void operator()(Iterator& it) const { --it; } +}; + +struct dereference_iterator +{ + template< typename > + struct result; + + template< typename This, typename Iterator > + struct result< This(Iterator) > { - public: - advance_iterator(DiffType step) : m_step(step) {} - - template - void operator()(Iterator& it) const - { it += m_step; } - - private: - DiffType m_step; - }; - // - struct increment_iterator - { - template - void operator()(Iterator& it) const - { ++it; } - }; - // - struct decrement_iterator - { - template - void operator()(Iterator& it) const - { --it; } - }; - // - struct dereference_iterator - { - template - struct result; - - template - struct result - { - typedef typename - std::remove_cv::type>::type - iterator; - - typedef typename iterator_reference::type type; - }; - - template - typename result::type - operator()(Iterator const& it) const - { return *it; } + using type = iterator_reference_t< + typename std::remove_cv< typename std::remove_reference< Iterator >::type >::type + >; }; - // Metafunction to obtain the type of the tuple whose element types - // are the reference types of an iterator tuple. - // - template - struct tuple_of_references - : mpl::transform< - IteratorTuple, - iterator_reference - > + template< typename Iterator > + typename result< dereference_iterator(Iterator) >::type operator()(Iterator const& it) const { - }; + return *it; + } +}; - // Specialization for std::pair - template - struct tuple_of_references > +// 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 +// are the reference types of an iterator tuple. +template< typename IteratorTuple > +struct tuple_of_references; + +template< typename IteratorTuple > +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 + > + >; +}; + +// Metafunction to obtain the minimal traversal tag in a list +// of iterators. +template< typename IteratorList > +struct minimum_traversal_category_in_iterator_list; + +template< typename IteratorList > +using minimum_traversal_category_in_iterator_list_t = typename minimum_traversal_category_in_iterator_list< IteratorList >::type; + +template< typename FrontTraversal, typename Tail > +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 Front, typename Tail > +struct minimum_traversal_category_in_iterator_list< tuples::cons< Front, Tail > > +{ + using front_traversal = pure_iterator_traversal_t< Front >; + + using type = mp11::mp_eval_if< + detail::is_trailing_null_type< Tail >, + front_traversal, + minimum_traversal_category_in_tail_t, + front_traversal, + Tail + >; +}; + +/////////////////////////////////////////////////////////////////// +// +// Class zip_iterator_base +// +// Builds and exposes the iterator facade type from which the zip +// iterator will be derived. +// +template< typename IteratorTuple > +struct zip_iterator_base +{ +private: + // Reference type is the type of the tuple obtained from the + // iterators' reference types. + using reference = detail::tuple_of_references_t< IteratorTuple >; + + // Value type is the same as reference type. + using value_type = reference; + + // Difference type is the first iterator's difference type + using difference_type = iterator_difference_t< mp11::mp_front< IteratorTuple > >; + + // Traversal catetgory is the minimum traversal category in the + // iterator tuple. + using traversal_category = detail::minimum_traversal_category_in_iterator_list_t< IteratorTuple >; + +public: + // The iterator facade type from which the zip iterator will + // be derived. + using type = iterator_facade< + zip_iterator< IteratorTuple >, + value_type, + traversal_category, + reference, + difference_type + >; +}; + +template< typename Reference > +struct converter +{ + template< typename Seq > + static Reference call(Seq seq) { - typedef std::pair< - typename iterator_reference::type - , typename iterator_reference::type - > type; - }; + using tag = typename fusion::traits::tag_of< Reference >::type; + return fusion::convert< tag >(seq); + } +}; - // Metafunction to obtain the minimal traversal tag in a tuple - // of iterators. - // - template - struct minimum_traversal_category_in_iterator_tuple +template< typename Reference1, typename Reference2 > +struct converter< std::pair< Reference1, Reference2 > > +{ + using reference = std::pair< Reference1, Reference2 >; + + template< typename Seq > + static reference call(Seq seq) { - typedef typename mpl::transform< - IteratorTuple - , pure_traversal_tag > - >::type tuple_of_traversal_tags; + return reference(fusion::at_c< 0 >(seq), fusion::at_c< 1 >(seq)); + } +}; - typedef typename mpl::fold< - tuple_of_traversal_tags - , random_access_traversal_tag - , minimum_category<> - >::type type; - }; +} // namespace detail - template - struct minimum_traversal_category_in_iterator_tuple > - { - typedef typename pure_traversal_tag< - typename iterator_traversal::type - >::type iterator1_traversal; - typedef typename pure_traversal_tag< - typename iterator_traversal::type - >::type iterator2_traversal; +///////////////////////////////////////////////////////////////////// +// +// zip_iterator class definition +// +template< typename IteratorTuple > +class zip_iterator : + public detail::zip_iterator_base< IteratorTuple >::type +{ + // Typedef super_t as our base class. + using super_t = typename detail::zip_iterator_base< IteratorTuple >::type; - typedef typename minimum_category< - iterator1_traversal - , typename minimum_category< - iterator2_traversal - , random_access_traversal_tag - >::type - >::type type; - }; - - /////////////////////////////////////////////////////////////////// - // - // Class zip_iterator_base - // - // Builds and exposes the iterator facade type from which the zip - // iterator will be derived. - // - template - struct zip_iterator_base - { - private: - // Reference type is the type of the tuple obtained from the - // iterators' reference types. - typedef typename - detail::tuple_of_references::type reference; - - // Value type is the same as reference type. - typedef reference value_type; - - // Difference type is the first iterator's difference type - typedef typename iterator_difference< - typename mpl::at_c::type - >::type difference_type; - - // Traversal catetgory is the minimum traversal category in the - // iterator tuple. - typedef typename - detail::minimum_traversal_category_in_iterator_tuple< - IteratorTuple - >::type traversal_category; - public: - - // The iterator facade type from which the zip iterator will - // be derived. - typedef iterator_facade< - zip_iterator, - value_type, - traversal_category, - reference, - difference_type - > type; - }; - - template <> - struct zip_iterator_base - { - typedef int type; - }; - - template - struct converter - { - template - static reference call(Seq seq) - { - typedef typename fusion::traits::tag_of::type tag; - return fusion::convert(seq); - } - }; - - template - struct converter > - { - typedef std::pair reference; - template - static reference call(Seq seq) - { - return reference( - fusion::at_c<0>(seq) - , fusion::at_c<1>(seq)); - } - }; - } - - ///////////////////////////////////////////////////////////////////// - // - // zip_iterator class definition - // - template - class zip_iterator : - public detail::zip_iterator_base::type - { - - // Typedef super_t as our base class. - typedef typename - detail::zip_iterator_base::type super_t; - - // iterator_core_access is the iterator's best friend. - friend class iterator_core_access; - - public: + // iterator_core_access is the iterator's best friend. + friend class iterator_core_access; +public: // Construction // ============ // Default constructor - zip_iterator() { } + zip_iterator() = default; // Constructor from iterator tuple - zip_iterator(IteratorTuple iterator_tuple) - : m_iterator_tuple(iterator_tuple) - { } + zip_iterator(IteratorTuple iterator_tuple) : + m_iterator_tuple(iterator_tuple) + {} // Copy constructor - template - zip_iterator( - const zip_iterator& other, - typename enable_if_convertible< - OtherIteratorTuple, - IteratorTuple - >::type* = 0 - ) : m_iterator_tuple(other.get_iterator_tuple()) + template< typename OtherIteratorTuple, typename = enable_if_convertible_t< OtherIteratorTuple, IteratorTuple > > + zip_iterator(zip_iterator< OtherIteratorTuple > const& other) : + m_iterator_tuple(other.get_iterator_tuple()) {} // Get method for the iterator tuple. - const IteratorTuple& get_iterator_tuple() const - { return m_iterator_tuple; } - - private: + IteratorTuple const& get_iterator_tuple() const { return m_iterator_tuple; } +private: // Implementation of Iterator Operations // ===================================== @@ -276,11 +304,9 @@ namespace iterators { // iterators in the iterator tuple. typename super_t::reference dereference() const { - typedef typename super_t::reference reference; - typedef detail::converter gen; - return gen::call(fusion::transform( - get_iterator_tuple(), - detail::dereference_iterator())); + using reference = typename super_t::reference; + using gen = detail::converter< reference >; + return gen::call(fusion::transform(get_iterator_tuple(), detail::dereference_iterator())); } // Two zip iterators are equal if all iterators in the iterator @@ -293,64 +319,55 @@ namespace iterators { // under several compilers. No point in bringing in a bunch // of #ifdefs here. // - template - bool equal(const zip_iterator& other) const + template< typename OtherIteratorTuple > + bool equal(zip_iterator< OtherIteratorTuple > const& other) const { - return fusion::equal_to( - get_iterator_tuple(), - other.get_iterator_tuple()); + return fusion::equal_to(get_iterator_tuple(), other.get_iterator_tuple()); } // Advancing a zip iterator means to advance all iterators in the // iterator tuple. void advance(typename super_t::difference_type n) { - fusion::for_each( - m_iterator_tuple, - detail::advance_iterator(n)); + fusion::for_each(m_iterator_tuple, detail::advance_iterator< typename super_t::difference_type >(n)); } + // Incrementing a zip iterator means to increment all iterators in // the iterator tuple. void increment() { - fusion::for_each( - m_iterator_tuple, - detail::increment_iterator()); + fusion::for_each(m_iterator_tuple, detail::increment_iterator()); } // Decrementing a zip iterator means to decrement all iterators in // the iterator tuple. void decrement() { - fusion::for_each( - m_iterator_tuple, - detail::decrement_iterator()); + fusion::for_each(m_iterator_tuple, detail::decrement_iterator()); } // Distance is calculated using the first iterator in the tuple. - template - typename super_t::difference_type distance_to( - const zip_iterator& other - ) const + template< typename OtherIteratorTuple > + typename super_t::difference_type distance_to(zip_iterator< OtherIteratorTuple > const& other) const { - return fusion::at_c<0>(other.get_iterator_tuple()) - - fusion::at_c<0>(this->get_iterator_tuple()); + return fusion::at_c< 0 >(other.get_iterator_tuple()) - fusion::at_c< 0 >(this->get_iterator_tuple()); } +private: // Data Members // ============ // The iterator tuple. IteratorTuple m_iterator_tuple; +}; - }; - - // Make function for zip iterator - // - template - inline zip_iterator - make_zip_iterator(IteratorTuple t) - { return zip_iterator(t); } +// Make function for zip iterator +// +template< typename IteratorTuple > +inline zip_iterator< IteratorTuple > make_zip_iterator(IteratorTuple t) +{ + return zip_iterator< IteratorTuple >(t); +} } // namespace iterators