Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:34:43

0001 /*=============================================================================
0002     Copyright (c) 2011 Eric Niebler
0003 
0004     Distributed under the Boost Software License, Version 1.0. (See accompanying
0005     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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 // fun(seq, state, context)
0028 //  seq: a non-segmented range
0029 //  state: the state of the fold so far
0030 //  context: the path to the current range
0031 //
0032 // returns: (state', fcontinue)
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         //auto push_context(cur, end, context)
0114         //{
0115         //  return push_back(context, segment_sequence(iterator_range(cur, end)));
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         //auto make_segmented_iterator(cur, end, context)
0132         //{
0133         //  return segmented_iterator(push_context(cur, end, context));
0134         //}
0135         //
0136         //auto segmented_fold_until_impl(seq, state, context, fun)
0137         //{
0138         //  if (is_segmented(seq))
0139         //  {
0140         //    segmented_fold_until_on_segments(segments(seq), state, context, fun);
0141         //  }
0142         //  else
0143         //  {
0144         //    return fun(seq, state, context);
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         //auto segmented_fold_until_on_segments(segs, state, context, fun)
0203         //{
0204         //  auto cur = begin(segs), end = end(segs);
0205         //  for (; cur != end; ++cur)
0206         //  {
0207         //    if (empty(*cur))
0208         //      continue;
0209         //    auto context` = push_context(cur, end, context);
0210         //    state = segmented_fold_until_impl(*cur, state, context`, fun);
0211         //    if (!second(state))
0212         //      return state;
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             // begin != end and !empty(*begin)
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_) // continue
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_) // break
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