mirror of
https://github.com/boostorg/iterator.git
synced 2025-05-09 23:23:54 +00:00
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:
parent
dc57bcf319
commit
aadd90df45
@ -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 <utility> // for std::pair
|
||||
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/iterator/enable_if_convertible.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/iterator/minimum_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/iterator/min_category.hpp>
|
||||
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <boost/fusion/adapted/boost_tuple.hpp> // for backward compatibility
|
||||
#include <boost/fusion/algorithm/iteration/for_each.hpp>
|
||||
#include <boost/fusion/algorithm/transformation/transform.hpp>
|
||||
@ -30,245 +27,276 @@
|
||||
#include <boost/fusion/support/tag_of_fwd.hpp>
|
||||
|
||||
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<typename IteratorTuple>
|
||||
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<typename DiffType>
|
||||
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<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)>
|
||||
{
|
||||
typedef typename
|
||||
std::remove_cv<typename std::remove_reference<Iterator>::type>::type
|
||||
iterator;
|
||||
|
||||
typedef typename iterator_reference<iterator>::type type;
|
||||
};
|
||||
|
||||
template<typename Iterator>
|
||||
typename result<dereference_iterator(Iterator)>::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<typename IteratorTuple>
|
||||
struct tuple_of_references
|
||||
: mpl::transform<
|
||||
IteratorTuple,
|
||||
iterator_reference<mpl::_1>
|
||||
>
|
||||
template< typename Iterator >
|
||||
typename result< dereference_iterator(Iterator) >::type operator()(Iterator const& it) const
|
||||
{
|
||||
};
|
||||
return *it;
|
||||
}
|
||||
};
|
||||
|
||||
// Specialization for std::pair
|
||||
template<typename Iterator1, typename Iterator2>
|
||||
struct tuple_of_references<std::pair<Iterator1, Iterator2> >
|
||||
// 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<Iterator1>::type
|
||||
, typename iterator_reference<Iterator2>::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<typename IteratorTuple>
|
||||
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<iterator_traversal<> >
|
||||
>::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<typename Iterator1, typename Iterator2>
|
||||
struct minimum_traversal_category_in_iterator_tuple<std::pair<Iterator1, Iterator2> >
|
||||
{
|
||||
typedef typename pure_traversal_tag<
|
||||
typename iterator_traversal<Iterator1>::type
|
||||
>::type iterator1_traversal;
|
||||
typedef typename pure_traversal_tag<
|
||||
typename iterator_traversal<Iterator2>::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<typename IteratorTuple>
|
||||
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<IteratorTuple>::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<IteratorTuple, 0>::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<IteratorTuple>,
|
||||
value_type,
|
||||
traversal_category,
|
||||
reference,
|
||||
difference_type
|
||||
> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct zip_iterator_base<int>
|
||||
{
|
||||
typedef int type;
|
||||
};
|
||||
|
||||
template <typename reference>
|
||||
struct converter
|
||||
{
|
||||
template <typename Seq>
|
||||
static reference call(Seq seq)
|
||||
{
|
||||
typedef typename fusion::traits::tag_of<reference>::type tag;
|
||||
return fusion::convert<tag>(seq);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Reference1, typename Reference2>
|
||||
struct converter<std::pair<Reference1, Reference2> >
|
||||
{
|
||||
typedef std::pair<Reference1, Reference2> reference;
|
||||
template <typename Seq>
|
||||
static reference call(Seq seq)
|
||||
{
|
||||
return reference(
|
||||
fusion::at_c<0>(seq)
|
||||
, fusion::at_c<1>(seq));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// zip_iterator class definition
|
||||
//
|
||||
template<typename IteratorTuple>
|
||||
class zip_iterator :
|
||||
public detail::zip_iterator_base<IteratorTuple>::type
|
||||
{
|
||||
|
||||
// Typedef super_t as our base class.
|
||||
typedef typename
|
||||
detail::zip_iterator_base<IteratorTuple>::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<typename OtherIteratorTuple>
|
||||
zip_iterator(
|
||||
const zip_iterator<OtherIteratorTuple>& 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<reference> 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<typename OtherIteratorTuple>
|
||||
bool equal(const zip_iterator<OtherIteratorTuple>& 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<BOOST_DEDUCED_TYPENAME super_t::difference_type>(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 OtherIteratorTuple>
|
||||
typename super_t::difference_type distance_to(
|
||||
const zip_iterator<OtherIteratorTuple>& 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<typename IteratorTuple>
|
||||
inline zip_iterator<IteratorTuple>
|
||||
make_zip_iterator(IteratorTuple t)
|
||||
{ return zip_iterator<IteratorTuple>(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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user