• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2001-2011 Joel de Guzman
3 
4     Distributed under the Boost Software License, Version 1.0. (See accompanying
5     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ==============================================================================*/
7 #if !defined(FUSION_FOR_EACH_05052005_1028)
8 #define FUSION_FOR_EACH_05052005_1028
9 
10 #include <boost/fusion/support/config.hpp>
11 #include <boost/fusion/sequence/intrinsic/begin.hpp>
12 #include <boost/fusion/sequence/intrinsic/end.hpp>
13 #include <boost/fusion/iterator/equal_to.hpp>
14 #include <boost/fusion/iterator/next.hpp>
15 #include <boost/fusion/iterator/deref.hpp>
16 #include <boost/fusion/iterator/distance.hpp>
17 #include <boost/fusion/support/category_of.hpp>
18 #include <boost/mpl/bool.hpp>
19 
20 namespace boost { namespace fusion {
21 namespace detail
22 {
23     template <typename First, typename Last, typename F>
24     BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
25     inline void
for_each_linear(First const &,Last const &,F const &,mpl::true_)26     for_each_linear(First const&, Last const&, F const&, mpl::true_)
27     {
28     }
29 
30     template <typename First, typename Last, typename F>
31     BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
32     inline void
for_each_linear(First const & first,Last const & last,F & f,mpl::false_)33     for_each_linear(First const& first, Last const& last, F& f, mpl::false_)
34     {
35         f(*first);
36         detail::for_each_linear(fusion::next(first), last, f,
37                                 result_of::equal_to<typename result_of::next<First>::type, Last>());
38     }
39 
40 
41     template <typename Sequence, typename F, typename Tag>
42     BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
43     inline void
for_each_dispatch(Sequence & seq,F & f,Tag)44     for_each_dispatch(Sequence& seq, F& f, Tag)
45     {
46         detail::for_each_linear(
47                                 fusion::begin(seq)
48                                 , fusion::end(seq)
49                                 , f
50                                 , result_of::equal_to<
51                                 typename result_of::begin<Sequence>::type
52                                 , typename result_of::end<Sequence>::type>());
53     }
54 
55     template<int N>
56     struct for_each_unrolled
57     {
58         template<typename I0, typename F>
59         BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
callboost::fusion::detail::for_each_unrolled60         static void call(I0 const& i0, F& f)
61         {
62             f(*i0);
63             typedef typename result_of::next<I0>::type I1;
64             I1 i1(fusion::next(i0));
65             f(*i1);
66             typedef typename result_of::next<I1>::type I2;
67             I2 i2(fusion::next(i1));
68             f(*i2);
69             typedef typename result_of::next<I2>::type I3;
70             I3 i3(fusion::next(i2));
71             f(*i3);
72             for_each_unrolled<N-4>::call(fusion::next(i3), f);
73         }
74     };
75 
76     template<>
77     struct for_each_unrolled<3>
78     {
79         template<typename I0, typename F>
80         BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
callboost::fusion::detail::for_each_unrolled81         static void call(I0 const& i0, F& f)
82         {
83             f(*i0);
84             typedef typename result_of::next<I0>::type I1;
85             I1 i1(fusion::next(i0));
86             f(*i1);
87             typedef typename result_of::next<I1>::type I2;
88             I2 i2(fusion::next(i1));
89             f(*i2);
90         }
91     };
92 
93     template<>
94     struct for_each_unrolled<2>
95     {
96         template<typename I0, typename F>
97         BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
callboost::fusion::detail::for_each_unrolled98         static void call(I0 const& i0, F& f)
99         {
100             f(*i0);
101             typedef typename result_of::next<I0>::type I1;
102             I1 i1(fusion::next(i0));
103             f(*i1);
104         }
105     };
106 
107     template<>
108     struct for_each_unrolled<1>
109     {
110         template<typename I0, typename F>
111         BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
callboost::fusion::detail::for_each_unrolled112         static void call(I0 const& i0, F& f)
113         {
114             f(*i0);
115         }
116     };
117 
118     template<>
119     struct for_each_unrolled<0>
120     {
121         template<typename It, typename F>
122         BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
callboost::fusion::detail::for_each_unrolled123         static void call(It const&, F const&)
124         {
125         }
126     };
127 
128     template <typename Sequence, typename F>
129     BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
130     inline void
for_each_dispatch(Sequence & seq,F & f,random_access_traversal_tag)131     for_each_dispatch(Sequence& seq, F& f, random_access_traversal_tag)
132     {
133         typedef typename result_of::begin<Sequence>::type begin;
134         typedef typename result_of::end<Sequence>::type end;
135         for_each_unrolled<result_of::distance<begin, end>::type::value>::call(fusion::begin(seq), f);
136     }
137 
138     template <typename Sequence, typename F>
139     BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
140     inline void
for_each(Sequence & seq,F & f,mpl::false_)141     for_each(Sequence& seq, F& f, mpl::false_) // unsegmented implementation
142     {
143         detail::for_each_dispatch(seq, f, typename traits::category_of<Sequence>::type());
144     }
145 }}}
146 
147 
148 #endif
149 
150