File indexing completed on 2025-01-18 09:34:43
0001
0002
0003
0004
0005
0006
0007 #if !defined(BOOST_FUSION_SEGMENTED_FOLD_UNTIL_IMPL_HPP_INCLUDED)
0008 #define BOOST_FUSION_SEGMENTED_FOLD_UNTIL_IMPL_HPP_INCLUDED
0009
0010 #include <boost/fusion/support/config.hpp>
0011 #include <boost/mpl/bool.hpp>
0012 #include <boost/mpl/eval_if.hpp>
0013 #include <boost/mpl/identity.hpp>
0014 #include <boost/utility/result_of.hpp>
0015 #include <boost/type_traits/add_const.hpp>
0016 #include <boost/type_traits/remove_reference.hpp>
0017
0018 #include <boost/fusion/support/void.hpp>
0019 #include <boost/fusion/container/list/cons_fwd.hpp>
0020 #include <boost/fusion/sequence/intrinsic_fwd.hpp>
0021 #include <boost/fusion/iterator/equal_to.hpp>
0022 #include <boost/fusion/iterator/deref.hpp>
0023 #include <boost/fusion/iterator/next.hpp>
0024 #include <boost/fusion/support/is_segmented.hpp>
0025 #include <boost/fusion/sequence/intrinsic/segments.hpp>
0026
0027
0028
0029
0030
0031
0032
0033
0034 namespace boost { namespace fusion
0035 {
0036 template <typename First, typename Last>
0037 struct iterator_range;
0038
0039 template <typename Context>
0040 struct segmented_iterator;
0041
0042 namespace result_of
0043 {
0044 template <typename Cur, typename Context>
0045 struct make_segmented_iterator
0046 {
0047 typedef
0048 iterator_range<
0049 Cur
0050 , typename result_of::end<
0051 typename remove_reference<
0052 typename add_const<
0053 typename result_of::deref<
0054 typename Context::car_type::begin_type
0055 >::type
0056 >::type
0057 >::type
0058 >::type
0059 >
0060 range_type;
0061
0062 typedef
0063 segmented_iterator<cons<range_type, Context> >
0064 type;
0065 };
0066 }
0067
0068 template <typename Cur, typename Context>
0069 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0070 inline typename result_of::make_segmented_iterator<Cur, Context>::type
0071 make_segmented_iterator(Cur const& cur, Context const& context)
0072 {
0073 typedef result_of::make_segmented_iterator<Cur, Context> impl_type;
0074 typedef typename impl_type::type type;
0075 typedef typename impl_type::range_type range_type;
0076 return type(cons<range_type, Context>(range_type(cur, fusion::end(*context.car.first)), context));
0077 }
0078
0079 namespace detail
0080 {
0081 template <
0082 typename Begin
0083 , typename End
0084 , typename State
0085 , typename Context
0086 , typename Fun
0087 , bool IsEmpty
0088 >
0089 struct segmented_fold_until_iterate_skip_empty;
0090
0091 template <
0092 typename Begin
0093 , typename End
0094 , typename State
0095 , typename Context
0096 , typename Fun
0097 , bool IsDone = result_of::equal_to<Begin, End>::type::value
0098 >
0099 struct segmented_fold_until_iterate;
0100
0101 template <
0102 typename Sequence
0103 , typename State
0104 , typename Context
0105 , typename Fun
0106 , bool IsSegmented = traits::is_segmented<Sequence>::type::value
0107 >
0108 struct segmented_fold_until_impl;
0109
0110 template <typename Segments, typename State, typename Context, typename Fun>
0111 struct segmented_fold_until_on_segments;
0112
0113
0114
0115
0116
0117
0118 template <typename Cur, typename End, typename Context>
0119 struct push_context
0120 {
0121 typedef iterator_range<Cur, End> range_type;
0122 typedef cons<range_type, Context> type;
0123
0124 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0125 static type call(Cur const& cur, End const& end, Context const& context)
0126 {
0127 return cons<range_type, Context>(range_type(cur, end), context);
0128 }
0129 };
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148 template <
0149 typename Sequence
0150 , typename State
0151 , typename Context
0152 , typename Fun
0153 , bool IsSegmented
0154 >
0155 struct segmented_fold_until_impl
0156 {
0157 typedef
0158 segmented_fold_until_on_segments<
0159 typename remove_reference<
0160 typename add_const<
0161 typename result_of::segments<Sequence>::type
0162 >::type
0163 >::type
0164 , State
0165 , Context
0166 , Fun
0167 >
0168 impl;
0169
0170 typedef typename impl::type type;
0171 typedef typename impl::continue_type continue_type;
0172
0173 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0174 static type call(Sequence& seq, State const& state, Context const& context, Fun const& fun)
0175 {
0176 return impl::call(fusion::segments(seq), state, context, fun);
0177 }
0178 };
0179
0180 template <
0181 typename Sequence
0182 , typename State
0183 , typename Context
0184 , typename Fun
0185 >
0186 struct segmented_fold_until_impl<Sequence, State, Context, Fun, false>
0187 {
0188 typedef
0189 typename Fun::template apply<Sequence, State, Context>
0190 apply_type;
0191
0192 typedef typename apply_type::type type;
0193 typedef typename apply_type::continue_type continue_type;
0194
0195 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0196 static type call(Sequence& seq, State const& state, Context const& context, Fun const& fun)
0197 {
0198 return apply_type::call(seq, state, context, fun);
0199 }
0200 };
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216 template <typename Apply>
0217 struct continue_wrap
0218 {
0219 typedef typename Apply::continue_type type;
0220 };
0221
0222 template <typename Begin, typename End, typename State, typename Context, typename Fun, bool IsEmpty>
0223 struct segmented_fold_until_iterate_skip_empty
0224 {
0225
0226 typedef
0227 push_context<Begin, End, Context>
0228 push_context_impl;
0229
0230 typedef
0231 typename push_context_impl::type
0232 next_context_type;
0233
0234 typedef
0235 segmented_fold_until_impl<
0236 typename remove_reference<
0237 typename add_const<
0238 typename result_of::deref<Begin>::type
0239 >::type
0240 >::type
0241 , State
0242 , next_context_type
0243 , Fun
0244 >
0245 fold_recurse_impl;
0246
0247 typedef
0248 typename fold_recurse_impl::type
0249 next_state_type;
0250
0251 typedef
0252 segmented_fold_until_iterate<
0253 typename result_of::next<Begin>::type
0254 , End
0255 , next_state_type
0256 , Context
0257 , Fun
0258 >
0259 next_iteration_impl;
0260
0261 typedef
0262 typename mpl::eval_if<
0263 typename fold_recurse_impl::continue_type
0264 , next_iteration_impl
0265 , mpl::identity<next_state_type>
0266 >::type
0267 type;
0268
0269 typedef
0270 typename mpl::eval_if<
0271 typename fold_recurse_impl::continue_type
0272 , continue_wrap<next_iteration_impl>
0273 , mpl::identity<mpl::false_>
0274 >::type
0275 continue_type;
0276
0277 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0278 static type call(Begin const& beg, End const& end, State const& state
0279 , Context const& context, Fun const& fun)
0280 {
0281 return call(beg, end, state, context, fun, typename fold_recurse_impl::continue_type());
0282 }
0283
0284 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0285 static type call(Begin const& beg, End const& end, State const& state
0286 , Context const& context, Fun const& fun, mpl::true_)
0287 {
0288 return next_iteration_impl::call(
0289 fusion::next(beg)
0290 , end
0291 , fold_recurse_impl::call(
0292 *beg
0293 , state
0294 , push_context_impl::call(beg, end, context)
0295 , fun)
0296 , context
0297 , fun);
0298 }
0299
0300 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0301 static type call(Begin const& beg, End const& end, State const& state
0302 , Context const& context, Fun const& fun, mpl::false_)
0303 {
0304 return fold_recurse_impl::call(
0305 *beg
0306 , state
0307 , push_context_impl::call(beg, end, context)
0308 , fun);
0309 }
0310 };
0311
0312 template <typename Begin, typename End, typename State, typename Context, typename Fun>
0313 struct segmented_fold_until_iterate_skip_empty<Begin, End, State, Context, Fun, true>
0314 {
0315 typedef
0316 segmented_fold_until_iterate<
0317 typename result_of::next<Begin>::type
0318 , End
0319 , State
0320 , Context
0321 , Fun
0322 >
0323 impl;
0324
0325 typedef typename impl::type type;
0326 typedef typename impl::continue_type continue_type;
0327
0328 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0329 static type call(Begin const& beg, End const& end, State const& state
0330 , Context const& context, Fun const& fun)
0331 {
0332 return impl::call(fusion::next(beg), end, state, context, fun);
0333 }
0334 };
0335
0336 template <typename Begin, typename End, typename State, typename Context, typename Fun, bool IsDone>
0337 struct segmented_fold_until_iterate
0338 {
0339 typedef
0340 typename result_of::empty<
0341 typename remove_reference<
0342 typename result_of::deref<Begin>::type
0343 >::type
0344 >::type
0345 empty_type;
0346
0347 typedef
0348 segmented_fold_until_iterate_skip_empty<Begin, End, State, Context, Fun, empty_type::value>
0349 impl;
0350
0351 typedef typename impl::type type;
0352 typedef typename impl::continue_type continue_type;
0353
0354 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0355 static type call(Begin const& beg, End const& end, State const& state
0356 , Context const& context, Fun const& fun)
0357 {
0358 return impl::call(beg, end, state, context, fun);
0359 }
0360 };
0361
0362 template <typename Begin, typename End, typename State, typename Context, typename Fun>
0363 struct segmented_fold_until_iterate<Begin, End, State, Context, Fun, true>
0364 {
0365 typedef State type;
0366 typedef mpl::true_ continue_type;
0367
0368 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0369 static type call(Begin const&, End const&, State const& state
0370 , Context const&, Fun const&)
0371 {
0372 return state;
0373 }
0374 };
0375
0376 template <typename Segments, typename State, typename Context, typename Fun>
0377 struct segmented_fold_until_on_segments
0378 {
0379 typedef
0380 segmented_fold_until_iterate<
0381 typename result_of::begin<Segments>::type
0382 , typename result_of::end<Segments>::type
0383 , State
0384 , Context
0385 , Fun
0386 >
0387 impl;
0388
0389 typedef typename impl::type type;
0390 typedef typename impl::continue_type continue_type;
0391
0392 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0393 static type call(Segments& segs, State const& state, Context const& context, Fun const& fun)
0394 {
0395 return impl::call(fusion::begin(segs), fusion::end(segs), state, context, fun);
0396 }
0397 };
0398 }
0399 }}
0400
0401 #endif