/*============================================================================= | |
Copyright (c) 2001-2006 Joel de Guzman | |
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) | |
==============================================================================*/ | |
#if !defined(FUSION_FOR_EACH_05052005_1028) | |
#define FUSION_FOR_EACH_05052005_1028 | |
#include <boost/fusion/sequence/intrinsic/begin.hpp> | |
#include <boost/fusion/sequence/intrinsic/end.hpp> | |
#include <boost/fusion/iterator/equal_to.hpp> | |
#include <boost/fusion/iterator/next.hpp> | |
#include <boost/fusion/iterator/deref.hpp> | |
#include <boost/fusion/iterator/distance.hpp> | |
#include <boost/mpl/bool.hpp> | |
namespace boost { namespace fusion { | |
namespace detail | |
{ | |
template <typename First, typename Last, typename F> | |
inline void | |
for_each_linear(First const&, Last const&, F const&, mpl::true_) | |
{ | |
} | |
template <typename First, typename Last, typename F> | |
inline void | |
for_each_linear(First const& first, Last const& last, F const& f, mpl::false_) | |
{ | |
f(*first); | |
detail::for_each_linear(fusion::next(first), last, f, | |
result_of::equal_to<typename result_of::next<First>::type, Last>()); | |
} | |
template <typename Sequence, typename F, typename Tag> | |
inline void | |
for_each(Sequence& seq, F const& f, Tag) | |
{ | |
detail::for_each_linear( | |
fusion::begin(seq) | |
, fusion::end(seq) | |
, f | |
, result_of::equal_to< | |
typename result_of::begin<Sequence>::type | |
, typename result_of::end<Sequence>::type>()); | |
} | |
template<int N> | |
struct for_each_unrolled | |
{ | |
template<typename I0, typename F> | |
static void call(I0 const& i0, F const& f) | |
{ | |
f(*i0); | |
typedef typename result_of::next<I0>::type I1; | |
I1 i1(fusion::next(i0)); | |
f(*i1); | |
typedef typename result_of::next<I1>::type I2; | |
I2 i2(fusion::next(i1)); | |
f(*i2); | |
typedef typename result_of::next<I2>::type I3; | |
I3 i3(fusion::next(i2)); | |
f(*i3); | |
for_each_unrolled<N-4>::call(fusion::next(i3), f); | |
} | |
}; | |
template<> | |
struct for_each_unrolled<3> | |
{ | |
template<typename I0, typename F> | |
static void call(I0 const& i0, F const& f) | |
{ | |
f(*i0); | |
typedef typename result_of::next<I0>::type I1; | |
I1 i1(fusion::next(i0)); | |
f(*i1); | |
typedef typename result_of::next<I1>::type I2; | |
I2 i2(fusion::next(i1)); | |
f(*i2); | |
} | |
}; | |
template<> | |
struct for_each_unrolled<2> | |
{ | |
template<typename I0, typename F> | |
static void call(I0 const& i0, F const& f) | |
{ | |
f(*i0); | |
typedef typename result_of::next<I0>::type I1; | |
I1 i1(fusion::next(i0)); | |
f(*i1); | |
} | |
}; | |
template<> | |
struct for_each_unrolled<1> | |
{ | |
template<typename I0, typename F> | |
static void call(I0 const& i0, F const& f) | |
{ | |
f(*i0); | |
} | |
}; | |
template<> | |
struct for_each_unrolled<0> | |
{ | |
template<typename It, typename F> | |
static void call(It const&, F const&) | |
{ | |
} | |
}; | |
template <typename Sequence, typename F> | |
inline void | |
for_each(Sequence& seq, F const& f, random_access_traversal_tag) | |
{ | |
typedef typename result_of::begin<Sequence>::type begin; | |
typedef typename result_of::end<Sequence>::type end; | |
for_each_unrolled<result_of::distance<begin, end>::type::value>::call(fusion::begin(seq), f); | |
} | |
}}} | |
#endif | |