File indexing completed on 2025-01-18 09:31:09
0001
0002
0003
0004
0005
0006
0007 #if !defined(FUSION_FOR_EACH_05052005_1028)
0008 #define FUSION_FOR_EACH_05052005_1028
0009
0010 #include <boost/fusion/support/config.hpp>
0011 #include <boost/fusion/sequence/intrinsic/begin.hpp>
0012 #include <boost/fusion/sequence/intrinsic/end.hpp>
0013 #include <boost/fusion/iterator/equal_to.hpp>
0014 #include <boost/fusion/iterator/next.hpp>
0015 #include <boost/fusion/iterator/deref.hpp>
0016 #include <boost/fusion/iterator/distance.hpp>
0017 #include <boost/fusion/support/category_of.hpp>
0018 #include <boost/mpl/bool.hpp>
0019
0020 namespace boost { namespace fusion {
0021 namespace detail
0022 {
0023 template <typename First, typename Last, typename F>
0024 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0025 inline void
0026 for_each_linear(First const&, Last const&, F const&, mpl::true_)
0027 {
0028 }
0029
0030 template <typename First, typename Last, typename F>
0031 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0032 inline void
0033 for_each_linear(First const& first, Last const& last, F& f, mpl::false_)
0034 {
0035 f(*first);
0036 detail::for_each_linear(fusion::next(first), last, f,
0037 result_of::equal_to<typename result_of::next<First>::type, Last>());
0038 }
0039
0040
0041 template <typename Sequence, typename F, typename Tag>
0042 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0043 inline void
0044 for_each_dispatch(Sequence& seq, F& f, Tag)
0045 {
0046 detail::for_each_linear(
0047 fusion::begin(seq)
0048 , fusion::end(seq)
0049 , f
0050 , result_of::equal_to<
0051 typename result_of::begin<Sequence>::type
0052 , typename result_of::end<Sequence>::type>());
0053 }
0054
0055 template<int N>
0056 struct for_each_unrolled
0057 {
0058 template<typename I0, typename F>
0059 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0060 static void call(I0 const& i0, F& f)
0061 {
0062 f(*i0);
0063 typedef typename result_of::next<I0>::type I1;
0064 I1 i1(fusion::next(i0));
0065 f(*i1);
0066 typedef typename result_of::next<I1>::type I2;
0067 I2 i2(fusion::next(i1));
0068 f(*i2);
0069 typedef typename result_of::next<I2>::type I3;
0070 I3 i3(fusion::next(i2));
0071 f(*i3);
0072 for_each_unrolled<N-4>::call(fusion::next(i3), f);
0073 }
0074 };
0075
0076 template<>
0077 struct for_each_unrolled<3>
0078 {
0079 template<typename I0, typename F>
0080 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0081 static void call(I0 const& i0, F& f)
0082 {
0083 f(*i0);
0084 typedef typename result_of::next<I0>::type I1;
0085 I1 i1(fusion::next(i0));
0086 f(*i1);
0087 typedef typename result_of::next<I1>::type I2;
0088 I2 i2(fusion::next(i1));
0089 f(*i2);
0090 }
0091 };
0092
0093 template<>
0094 struct for_each_unrolled<2>
0095 {
0096 template<typename I0, typename F>
0097 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0098 static void call(I0 const& i0, F& f)
0099 {
0100 f(*i0);
0101 typedef typename result_of::next<I0>::type I1;
0102 I1 i1(fusion::next(i0));
0103 f(*i1);
0104 }
0105 };
0106
0107 template<>
0108 struct for_each_unrolled<1>
0109 {
0110 template<typename I0, typename F>
0111 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0112 static void call(I0 const& i0, F& f)
0113 {
0114 f(*i0);
0115 }
0116 };
0117
0118 template<>
0119 struct for_each_unrolled<0>
0120 {
0121 template<typename It, typename F>
0122 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0123 static void call(It const&, F const&)
0124 {
0125 }
0126 };
0127
0128 template <typename Sequence, typename F>
0129 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0130 inline void
0131 for_each_dispatch(Sequence& seq, F& f, random_access_traversal_tag)
0132 {
0133 typedef typename result_of::begin<Sequence>::type begin;
0134 typedef typename result_of::end<Sequence>::type end;
0135 for_each_unrolled<result_of::distance<begin, end>::type::value>::call(fusion::begin(seq), f);
0136 }
0137
0138 template <typename Sequence, typename F>
0139 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0140 inline void
0141 for_each(Sequence& seq, F& f, mpl::false_)
0142 {
0143 detail::for_each_dispatch(seq, f, typename traits::category_of<Sequence>::type());
0144 }
0145 }}}
0146
0147
0148 #endif
0149