mirror of
https://github.com/boostorg/iterator.git
synced 2025-07-22 00:52:08 +02:00
Reimplement zip_iterator based on Boost.Fusion
By default, backward compatibility for Boost.Tuple is presented. Signed-off-by: Kohei Takahashi <flast@flast.jp>
This commit is contained in:
@ -1,6 +1,8 @@
|
|||||||
// Copyright David Abrahams and Thomas Becker 2000-2006. Distributed
|
// Copyright David Abrahams and Thomas Becker 2000-2006.
|
||||||
// under the Boost Software License, Version 1.0. (See accompanying
|
// Copyright Kohei Takahashi 2012-2014.
|
||||||
// file LICENSE_1_0.txt or copy at
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
#ifndef BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_
|
#ifndef BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_
|
||||||
@ -16,40 +18,30 @@
|
|||||||
|
|
||||||
#include <boost/iterator/detail/minimum_category.hpp>
|
#include <boost/iterator/detail/minimum_category.hpp>
|
||||||
|
|
||||||
#include <boost/tuple/tuple.hpp>
|
#include <boost/fusion/adapted/boost_tuple.hpp> // for backward compatibility
|
||||||
|
|
||||||
#include <boost/type_traits/is_same.hpp>
|
#include <boost/type_traits/remove_reference.hpp>
|
||||||
#include <boost/mpl/and.hpp>
|
#include <boost/type_traits/remove_cv.hpp>
|
||||||
#include <boost/mpl/apply.hpp>
|
|
||||||
#include <boost/mpl/eval_if.hpp>
|
#include <boost/mpl/at.hpp>
|
||||||
#include <boost/mpl/lambda.hpp>
|
#include <boost/mpl/fold.hpp>
|
||||||
|
#include <boost/mpl/transform.hpp>
|
||||||
#include <boost/mpl/placeholders.hpp>
|
#include <boost/mpl/placeholders.hpp>
|
||||||
#include <boost/mpl/aux_/lambda_support.hpp>
|
#include <boost/mpl/aux_/lambda_support.hpp>
|
||||||
|
|
||||||
|
#include <boost/fusion/algorithm/iteration/for_each.hpp>
|
||||||
|
#include <boost/fusion/algorithm/transformation/transform.hpp>
|
||||||
|
#include <boost/fusion/sequence/convert.hpp>
|
||||||
|
#include <boost/fusion/sequence/intrinsic/at_c.hpp>
|
||||||
|
#include <boost/fusion/sequence/comparison/equal_to.hpp>
|
||||||
|
#include <boost/fusion/support/tag_of_fwd.hpp>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
// 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;
|
||||||
|
|
||||||
// One important design goal of the zip_iterator is to isolate all
|
|
||||||
// functionality whose implementation relies on the current tuple
|
|
||||||
// implementation. This goal has been achieved as follows: Inside
|
|
||||||
// the namespace detail there is a namespace tuple_impl_specific.
|
|
||||||
// This namespace encapsulates all functionality that is specific
|
|
||||||
// to the current Boost tuple implementation. More precisely, the
|
|
||||||
// namespace tuple_impl_specific provides the following tuple
|
|
||||||
// algorithms and meta-algorithms for the current Boost tuple
|
|
||||||
// implementation:
|
|
||||||
//
|
|
||||||
// tuple_meta_transform
|
|
||||||
// tuple_meta_accumulate
|
|
||||||
// tuple_transform
|
|
||||||
// tuple_for_each
|
|
||||||
//
|
|
||||||
// If the tuple implementation changes, all that needs to be
|
|
||||||
// replaced is the implementation of these four (meta-)algorithms.
|
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -60,7 +52,7 @@ namespace boost {
|
|||||||
{
|
{
|
||||||
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; }
|
||||||
@ -72,250 +64,39 @@ namespace boost {
|
|||||||
struct increment_iterator
|
struct increment_iterator
|
||||||
{
|
{
|
||||||
template<typename Iterator>
|
template<typename Iterator>
|
||||||
void operator()(Iterator& it)
|
void operator()(Iterator& it) const
|
||||||
{ ++it; }
|
{ ++it; }
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
struct decrement_iterator
|
struct decrement_iterator
|
||||||
{
|
{
|
||||||
template<typename Iterator>
|
template<typename Iterator>
|
||||||
void operator()(Iterator& it)
|
void operator()(Iterator& it) const
|
||||||
{ --it; }
|
{ --it; }
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
struct dereference_iterator
|
struct dereference_iterator
|
||||||
{
|
{
|
||||||
template<typename Iterator>
|
template<typename>
|
||||||
struct apply
|
struct result;
|
||||||
{
|
|
||||||
|
template<typename This, typename Iterator>
|
||||||
|
struct result<This(Iterator)>
|
||||||
|
{
|
||||||
typedef typename
|
typedef typename
|
||||||
iterator_traits<Iterator>::reference
|
remove_reference<typename remove_cv<Iterator>::type>::type
|
||||||
|
iterator;
|
||||||
|
|
||||||
|
typedef typename
|
||||||
|
iterator_traits<iterator>::reference
|
||||||
type;
|
type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Iterator>
|
template<typename Iterator>
|
||||||
typename apply<Iterator>::type operator()(Iterator const& it)
|
typename result<dereference_iterator(Iterator)>::type
|
||||||
|
operator()(Iterator const& it) const
|
||||||
{ return *it; }
|
{ return *it; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// The namespace tuple_impl_specific provides two meta-
|
|
||||||
// algorithms and two algorithms for tuples.
|
|
||||||
//
|
|
||||||
namespace tuple_impl_specific
|
|
||||||
{
|
|
||||||
// Meta-transform algorithm for tuples
|
|
||||||
//
|
|
||||||
template<typename Tuple, class UnaryMetaFun>
|
|
||||||
struct tuple_meta_transform;
|
|
||||||
|
|
||||||
template<typename Tuple, class UnaryMetaFun>
|
|
||||||
struct tuple_meta_transform_impl
|
|
||||||
{
|
|
||||||
typedef tuples::cons<
|
|
||||||
typename mpl::apply1<
|
|
||||||
typename mpl::lambda<UnaryMetaFun>::type
|
|
||||||
, typename Tuple::head_type
|
|
||||||
>::type
|
|
||||||
, typename tuple_meta_transform<
|
|
||||||
typename Tuple::tail_type
|
|
||||||
, UnaryMetaFun
|
|
||||||
>::type
|
|
||||||
> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Tuple, class UnaryMetaFun>
|
|
||||||
struct tuple_meta_transform
|
|
||||||
: mpl::eval_if<
|
|
||||||
boost::is_same<Tuple, tuples::null_type>
|
|
||||||
, mpl::identity<tuples::null_type>
|
|
||||||
, tuple_meta_transform_impl<Tuple, UnaryMetaFun>
|
|
||||||
>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
// Meta-accumulate algorithm for tuples. Note: The template
|
|
||||||
// parameter StartType corresponds to the initial value in
|
|
||||||
// ordinary accumulation.
|
|
||||||
//
|
|
||||||
template<class Tuple, class BinaryMetaFun, class StartType>
|
|
||||||
struct tuple_meta_accumulate;
|
|
||||||
|
|
||||||
template<
|
|
||||||
typename Tuple
|
|
||||||
, class BinaryMetaFun
|
|
||||||
, typename StartType
|
|
||||||
>
|
|
||||||
struct tuple_meta_accumulate_impl
|
|
||||||
{
|
|
||||||
typedef typename mpl::apply2<
|
|
||||||
typename mpl::lambda<BinaryMetaFun>::type
|
|
||||||
, typename Tuple::head_type
|
|
||||||
, typename tuple_meta_accumulate<
|
|
||||||
typename Tuple::tail_type
|
|
||||||
, BinaryMetaFun
|
|
||||||
, StartType
|
|
||||||
>::type
|
|
||||||
>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<
|
|
||||||
typename Tuple
|
|
||||||
, class BinaryMetaFun
|
|
||||||
, typename StartType
|
|
||||||
>
|
|
||||||
struct tuple_meta_accumulate
|
|
||||||
: mpl::eval_if<
|
|
||||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
|
||||||
mpl::or_<
|
|
||||||
#endif
|
|
||||||
boost::is_same<Tuple, tuples::null_type>
|
|
||||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
|
||||||
, boost::is_same<Tuple,int>
|
|
||||||
>
|
|
||||||
#endif
|
|
||||||
, mpl::identity<StartType>
|
|
||||||
, tuple_meta_accumulate_impl<
|
|
||||||
Tuple
|
|
||||||
, BinaryMetaFun
|
|
||||||
, StartType
|
|
||||||
>
|
|
||||||
>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \
|
|
||||||
|| ( \
|
|
||||||
BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, != 0) && defined(_MSC_VER) \
|
|
||||||
)
|
|
||||||
// Not sure why intel's partial ordering fails in this case, but I'm
|
|
||||||
// assuming int's an MSVC bug-compatibility feature.
|
|
||||||
|
|
||||||
# define BOOST_TUPLE_ALGO_DISPATCH
|
|
||||||
# define BOOST_TUPLE_ALGO(algo) algo##_impl
|
|
||||||
# define BOOST_TUPLE_ALGO_TERMINATOR , int
|
|
||||||
# define BOOST_TUPLE_ALGO_RECURSE , ...
|
|
||||||
#else
|
|
||||||
# define BOOST_TUPLE_ALGO(algo) algo
|
|
||||||
# define BOOST_TUPLE_ALGO_TERMINATOR
|
|
||||||
# define BOOST_TUPLE_ALGO_RECURSE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// transform algorithm for tuples. The template parameter Fun
|
|
||||||
// must be a unary functor which is also a unary metafunction
|
|
||||||
// class that computes its return type based on its argument
|
|
||||||
// type. For example:
|
|
||||||
//
|
|
||||||
// struct to_ptr
|
|
||||||
// {
|
|
||||||
// template <class Arg>
|
|
||||||
// struct apply
|
|
||||||
// {
|
|
||||||
// typedef Arg* type;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// template <class Arg>
|
|
||||||
// Arg* operator()(Arg x);
|
|
||||||
// };
|
|
||||||
template<typename Fun>
|
|
||||||
tuples::null_type BOOST_TUPLE_ALGO(tuple_transform)
|
|
||||||
(tuples::null_type const&, Fun BOOST_TUPLE_ALGO_TERMINATOR)
|
|
||||||
{ return tuples::null_type(); }
|
|
||||||
|
|
||||||
template<typename Tuple, typename Fun>
|
|
||||||
typename tuple_meta_transform<
|
|
||||||
Tuple
|
|
||||||
, Fun
|
|
||||||
>::type
|
|
||||||
|
|
||||||
BOOST_TUPLE_ALGO(tuple_transform)(
|
|
||||||
const Tuple& t,
|
|
||||||
Fun f
|
|
||||||
BOOST_TUPLE_ALGO_RECURSE
|
|
||||||
)
|
|
||||||
{
|
|
||||||
typedef typename tuple_meta_transform<
|
|
||||||
BOOST_DEDUCED_TYPENAME Tuple::tail_type
|
|
||||||
, Fun
|
|
||||||
>::type transformed_tail_type;
|
|
||||||
|
|
||||||
return tuples::cons<
|
|
||||||
BOOST_DEDUCED_TYPENAME mpl::apply1<
|
|
||||||
Fun, BOOST_DEDUCED_TYPENAME Tuple::head_type
|
|
||||||
>::type
|
|
||||||
, transformed_tail_type
|
|
||||||
>(
|
|
||||||
f(boost::tuples::get<0>(t)), tuple_transform(t.get_tail(), f)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef BOOST_TUPLE_ALGO_DISPATCH
|
|
||||||
template<typename Tuple, typename Fun>
|
|
||||||
typename tuple_meta_transform<
|
|
||||||
Tuple
|
|
||||||
, Fun
|
|
||||||
>::type
|
|
||||||
|
|
||||||
tuple_transform(
|
|
||||||
const Tuple& t,
|
|
||||||
Fun f
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return tuple_transform_impl(t, f, 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// for_each algorithm for tuples.
|
|
||||||
//
|
|
||||||
template<typename Fun>
|
|
||||||
Fun BOOST_TUPLE_ALGO(tuple_for_each)(
|
|
||||||
tuples::null_type
|
|
||||||
, Fun f BOOST_TUPLE_ALGO_TERMINATOR
|
|
||||||
)
|
|
||||||
{ return f; }
|
|
||||||
|
|
||||||
|
|
||||||
template<typename Tuple, typename Fun>
|
|
||||||
Fun BOOST_TUPLE_ALGO(tuple_for_each)(
|
|
||||||
Tuple& t
|
|
||||||
, Fun f BOOST_TUPLE_ALGO_RECURSE)
|
|
||||||
{
|
|
||||||
f( t.get_head() );
|
|
||||||
return tuple_for_each(t.get_tail(), f);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef BOOST_TUPLE_ALGO_DISPATCH
|
|
||||||
template<typename Tuple, typename Fun>
|
|
||||||
Fun
|
|
||||||
tuple_for_each(
|
|
||||||
Tuple& t,
|
|
||||||
Fun f
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return tuple_for_each_impl(t, f, 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Equality of tuples. NOTE: "==" for tuples currently (7/2003)
|
|
||||||
// has problems under some compilers, so I just do my own.
|
|
||||||
// No point in bringing in a bunch of #ifdefs here. This is
|
|
||||||
// going to go away with the next tuple implementation anyway.
|
|
||||||
//
|
|
||||||
inline bool tuple_equal(tuples::null_type, tuples::null_type)
|
|
||||||
{ return true; }
|
|
||||||
|
|
||||||
template<typename Tuple1, typename Tuple2>
|
|
||||||
bool tuple_equal(
|
|
||||||
Tuple1 const& t1,
|
|
||||||
Tuple2 const& t2
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return t1.get_head() == t2.get_head() &&
|
|
||||||
tuple_equal(t1.get_tail(), t2.get_tail());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// end namespace tuple_impl_specific
|
|
||||||
|
|
||||||
template<typename Iterator>
|
template<typename Iterator>
|
||||||
struct iterator_reference
|
struct iterator_reference
|
||||||
@ -336,14 +117,14 @@ namespace boost {
|
|||||||
struct apply : iterator_reference<T> {};
|
struct apply : iterator_reference<T> {};
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 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
|
||||||
: tuple_impl_specific::tuple_meta_transform<
|
: mpl::transform<
|
||||||
IteratorTuple,
|
IteratorTuple,
|
||||||
iterator_reference<mpl::_1>
|
iterator_reference<mpl::_1>
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
@ -355,54 +136,23 @@ namespace boost {
|
|||||||
template<typename IteratorTuple>
|
template<typename IteratorTuple>
|
||||||
struct minimum_traversal_category_in_iterator_tuple
|
struct minimum_traversal_category_in_iterator_tuple
|
||||||
{
|
{
|
||||||
typedef typename tuple_impl_specific::tuple_meta_transform<
|
typedef typename mpl::transform<
|
||||||
IteratorTuple
|
IteratorTuple
|
||||||
, pure_traversal_tag<iterator_traversal<> >
|
, pure_traversal_tag<iterator_traversal<> >
|
||||||
>::type tuple_of_traversal_tags;
|
>::type tuple_of_traversal_tags;
|
||||||
|
|
||||||
typedef typename tuple_impl_specific::tuple_meta_accumulate<
|
typedef typename mpl::fold<
|
||||||
tuple_of_traversal_tags
|
tuple_of_traversal_tags
|
||||||
, minimum_category<>
|
|
||||||
, random_access_traversal_tag
|
, random_access_traversal_tag
|
||||||
|
, minimum_category<>
|
||||||
>::type type;
|
>::type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround
|
|
||||||
template <>
|
|
||||||
struct minimum_traversal_category_in_iterator_tuple<int>
|
|
||||||
{
|
|
||||||
typedef int type;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// We need to call tuple_meta_accumulate with mpl::and_ as the
|
|
||||||
// accumulating functor. To this end, we need to wrap it into
|
|
||||||
// a struct that has exactly two arguments (that is, template
|
|
||||||
// parameters) and not five, like mpl::and_ does.
|
|
||||||
//
|
|
||||||
template<typename Arg1, typename Arg2>
|
|
||||||
struct and_with_two_args
|
|
||||||
: mpl::and_<Arg1, Arg2>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
# ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT
|
|
||||||
// Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work
|
|
||||||
// out well. In this case I think it's an MPL bug
|
|
||||||
template<>
|
|
||||||
struct and_with_two_args<mpl::_1,mpl::_2>
|
|
||||||
{
|
|
||||||
template <class A1, class A2>
|
|
||||||
struct apply : mpl::and_<A1,A2>
|
|
||||||
{};
|
|
||||||
};
|
|
||||||
# endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Class zip_iterator_base
|
// Class zip_iterator_base
|
||||||
//
|
//
|
||||||
// Builds and exposes the iterator facade type from which the zip
|
// Builds and exposes the iterator facade type from which the zip
|
||||||
// iterator will be derived.
|
// iterator will be derived.
|
||||||
//
|
//
|
||||||
template<typename IteratorTuple>
|
template<typename IteratorTuple>
|
||||||
@ -411,30 +161,30 @@ namespace boost {
|
|||||||
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
|
typedef typename
|
||||||
detail::tuple_of_references<IteratorTuple>::type reference;
|
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;
|
typedef reference value_type;
|
||||||
|
|
||||||
// Difference type is the first iterator's difference type
|
// Difference type is the first iterator's difference type
|
||||||
typedef typename iterator_traits<
|
typedef typename iterator_traits<
|
||||||
typename tuples::element<0, IteratorTuple>::type
|
typename mpl::at_c<IteratorTuple, 0>::type
|
||||||
>::difference_type difference_type;
|
>::difference_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
|
typedef typename
|
||||||
detail::minimum_traversal_category_in_iterator_tuple<
|
detail::minimum_traversal_category_in_iterator_tuple<
|
||||||
IteratorTuple
|
IteratorTuple
|
||||||
>::type traversal_category;
|
>::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<
|
typedef iterator_facade<
|
||||||
zip_iterator<IteratorTuple>,
|
zip_iterator<IteratorTuple>,
|
||||||
value_type,
|
value_type,
|
||||||
traversal_category,
|
traversal_category,
|
||||||
reference,
|
reference,
|
||||||
difference_type
|
difference_type
|
||||||
@ -447,34 +197,34 @@ namespace boost {
|
|||||||
typedef int type;
|
typedef int type;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// zip_iterator class definition
|
// zip_iterator class definition
|
||||||
//
|
//
|
||||||
template<typename IteratorTuple>
|
template<typename IteratorTuple>
|
||||||
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
|
typedef typename
|
||||||
detail::zip_iterator_base<IteratorTuple>::type super_t;
|
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() { }
|
||||||
|
|
||||||
// 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
|
||||||
@ -493,18 +243,19 @@ namespace boost {
|
|||||||
{ return m_iterator_tuple; }
|
{ return m_iterator_tuple; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Implementation of Iterator Operations
|
// Implementation of Iterator Operations
|
||||||
// =====================================
|
// =====================================
|
||||||
|
|
||||||
// Dereferencing returns a tuple built from the dereferenced
|
// Dereferencing returns a tuple built from the dereferenced
|
||||||
// iterators in the iterator tuple.
|
// iterators in the iterator tuple.
|
||||||
typename super_t::reference dereference() const
|
typename super_t::reference dereference() const
|
||||||
{
|
{
|
||||||
return detail::tuple_impl_specific::tuple_transform(
|
typedef typename super_t::reference reference;
|
||||||
get_iterator_tuple(),
|
typedef typename fusion::traits::tag_of<reference>::type tag;
|
||||||
detail::dereference_iterator()
|
return fusion::convert<tag>(fusion::transform(
|
||||||
);
|
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
|
||||||
@ -517,66 +268,62 @@ namespace boost {
|
|||||||
// under several compilers. No point in bringing in a bunch
|
// under several compilers. No point in bringing in a bunch
|
||||||
// of #ifdefs here.
|
// of #ifdefs here.
|
||||||
//
|
//
|
||||||
template<typename OtherIteratorTuple>
|
template<typename OtherIteratorTuple>
|
||||||
bool equal(const zip_iterator<OtherIteratorTuple>& other) const
|
bool equal(const zip_iterator<OtherIteratorTuple>& other) const
|
||||||
{
|
{
|
||||||
return detail::tuple_impl_specific::tuple_equal(
|
return fusion::equal_to(
|
||||||
get_iterator_tuple(),
|
get_iterator_tuple(),
|
||||||
other.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)
|
||||||
{
|
{
|
||||||
detail::tuple_impl_specific::tuple_for_each(
|
fusion::for_each(
|
||||||
m_iterator_tuple,
|
m_iterator_tuple,
|
||||||
detail::advance_iterator<BOOST_DEDUCED_TYPENAME super_t::difference_type>(n)
|
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()
|
||||||
{
|
{
|
||||||
detail::tuple_impl_specific::tuple_for_each(
|
fusion::for_each(
|
||||||
m_iterator_tuple,
|
m_iterator_tuple,
|
||||||
detail::increment_iterator()
|
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()
|
||||||
{
|
{
|
||||||
detail::tuple_impl_specific::tuple_for_each(
|
fusion::for_each(
|
||||||
m_iterator_tuple,
|
m_iterator_tuple,
|
||||||
detail::decrement_iterator()
|
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(
|
||||||
const zip_iterator<OtherIteratorTuple>& other
|
const zip_iterator<OtherIteratorTuple>& other
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
return boost::tuples::get<0>(other.get_iterator_tuple()) -
|
return fusion::at_c<0>(other.get_iterator_tuple()) -
|
||||||
boost::tuples::get<0>(this->get_iterator_tuple());
|
fusion::at_c<0>(this->get_iterator_tuple());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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>
|
||||||
zip_iterator<IteratorTuple>
|
zip_iterator<IteratorTuple>
|
||||||
make_zip_iterator(IteratorTuple t)
|
make_zip_iterator(IteratorTuple t)
|
||||||
{ return zip_iterator<IteratorTuple>(t); }
|
{ return zip_iterator<IteratorTuple>(t); }
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user