123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401 |
- /*=============================================================================
- Copyright (c) 2011 Eric Niebler
- 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(BOOST_FUSION_SEGMENTED_FOLD_UNTIL_IMPL_HPP_INCLUDED)
- #define BOOST_FUSION_SEGMENTED_FOLD_UNTIL_IMPL_HPP_INCLUDED
- #include <boost/fusion/support/config.hpp>
- #include <boost/mpl/bool.hpp>
- #include <boost/mpl/eval_if.hpp>
- #include <boost/mpl/identity.hpp>
- #include <boost/utility/result_of.hpp>
- #include <boost/type_traits/add_const.hpp>
- #include <boost/type_traits/remove_reference.hpp>
- #include <boost/fusion/support/void.hpp>
- #include <boost/fusion/container/list/cons_fwd.hpp>
- #include <boost/fusion/sequence/intrinsic_fwd.hpp>
- #include <boost/fusion/iterator/equal_to.hpp>
- #include <boost/fusion/iterator/deref.hpp>
- #include <boost/fusion/iterator/next.hpp>
- #include <boost/fusion/support/is_segmented.hpp>
- #include <boost/fusion/sequence/intrinsic/segments.hpp>
- // fun(seq, state, context)
- // seq: a non-segmented range
- // state: the state of the fold so far
- // context: the path to the current range
- //
- // returns: (state', fcontinue)
- namespace boost { namespace fusion
- {
- template <typename First, typename Last>
- struct iterator_range;
- template <typename Context>
- struct segmented_iterator;
- namespace result_of
- {
- template <typename Cur, typename Context>
- struct make_segmented_iterator
- {
- typedef
- iterator_range<
- Cur
- , typename result_of::end<
- typename remove_reference<
- typename add_const<
- typename result_of::deref<
- typename Context::car_type::begin_type
- >::type
- >::type
- >::type
- >::type
- >
- range_type;
- typedef
- segmented_iterator<cons<range_type, Context> >
- type;
- };
- }
- template <typename Cur, typename Context>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- inline typename result_of::make_segmented_iterator<Cur, Context>::type
- make_segmented_iterator(Cur const& cur, Context const& context)
- {
- typedef result_of::make_segmented_iterator<Cur, Context> impl_type;
- typedef typename impl_type::type type;
- typedef typename impl_type::range_type range_type;
- return type(cons<range_type, Context>(range_type(cur, fusion::end(*context.car.first)), context));
- }
- namespace detail
- {
- template <
- typename Begin
- , typename End
- , typename State
- , typename Context
- , typename Fun
- , bool IsEmpty
- >
- struct segmented_fold_until_iterate_skip_empty;
- template <
- typename Begin
- , typename End
- , typename State
- , typename Context
- , typename Fun
- , bool IsDone = result_of::equal_to<Begin, End>::type::value
- >
- struct segmented_fold_until_iterate;
- template <
- typename Sequence
- , typename State
- , typename Context
- , typename Fun
- , bool IsSegmented = traits::is_segmented<Sequence>::type::value
- >
- struct segmented_fold_until_impl;
- template <typename Segments, typename State, typename Context, typename Fun>
- struct segmented_fold_until_on_segments;
- //auto push_context(cur, end, context)
- //{
- // return push_back(context, segment_sequence(iterator_range(cur, end)));
- //}
- template <typename Cur, typename End, typename Context>
- struct push_context
- {
- typedef iterator_range<Cur, End> range_type;
- typedef cons<range_type, Context> type;
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- static type call(Cur const& cur, End const& end, Context const& context)
- {
- return cons<range_type, Context>(range_type(cur, end), context);
- }
- };
- //auto make_segmented_iterator(cur, end, context)
- //{
- // return segmented_iterator(push_context(cur, end, context));
- //}
- //
- //auto segmented_fold_until_impl(seq, state, context, fun)
- //{
- // if (is_segmented(seq))
- // {
- // segmented_fold_until_on_segments(segments(seq), state, context, fun);
- // }
- // else
- // {
- // return fun(seq, state, context);
- // }
- //}
- template <
- typename Sequence
- , typename State
- , typename Context
- , typename Fun
- , bool IsSegmented
- >
- struct segmented_fold_until_impl
- {
- typedef
- segmented_fold_until_on_segments<
- typename remove_reference<
- typename add_const<
- typename result_of::segments<Sequence>::type
- >::type
- >::type
- , State
- , Context
- , Fun
- >
- impl;
- typedef typename impl::type type;
- typedef typename impl::continue_type continue_type;
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- static type call(Sequence& seq, State const& state, Context const& context, Fun const& fun)
- {
- return impl::call(fusion::segments(seq), state, context, fun);
- }
- };
- template <
- typename Sequence
- , typename State
- , typename Context
- , typename Fun
- >
- struct segmented_fold_until_impl<Sequence, State, Context, Fun, false>
- {
- typedef
- typename Fun::template apply<Sequence, State, Context>
- apply_type;
- typedef typename apply_type::type type;
- typedef typename apply_type::continue_type continue_type;
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- static type call(Sequence& seq, State const& state, Context const& context, Fun const& fun)
- {
- return apply_type::call(seq, state, context, fun);
- }
- };
- //auto segmented_fold_until_on_segments(segs, state, context, fun)
- //{
- // auto cur = begin(segs), end = end(segs);
- // for (; cur != end; ++cur)
- // {
- // if (empty(*cur))
- // continue;
- // auto context` = push_context(cur, end, context);
- // state = segmented_fold_until_impl(*cur, state, context`, fun);
- // if (!second(state))
- // return state;
- // }
- //}
- template <typename Apply>
- struct continue_wrap
- {
- typedef typename Apply::continue_type type;
- };
- template <typename Begin, typename End, typename State, typename Context, typename Fun, bool IsEmpty>
- struct segmented_fold_until_iterate_skip_empty
- {
- // begin != end and !empty(*begin)
- typedef
- push_context<Begin, End, Context>
- push_context_impl;
- typedef
- typename push_context_impl::type
- next_context_type;
- typedef
- segmented_fold_until_impl<
- typename remove_reference<
- typename add_const<
- typename result_of::deref<Begin>::type
- >::type
- >::type
- , State
- , next_context_type
- , Fun
- >
- fold_recurse_impl;
- typedef
- typename fold_recurse_impl::type
- next_state_type;
- typedef
- segmented_fold_until_iterate<
- typename result_of::next<Begin>::type
- , End
- , next_state_type
- , Context
- , Fun
- >
- next_iteration_impl;
- typedef
- typename mpl::eval_if<
- typename fold_recurse_impl::continue_type
- , next_iteration_impl
- , mpl::identity<next_state_type>
- >::type
- type;
- typedef
- typename mpl::eval_if<
- typename fold_recurse_impl::continue_type
- , continue_wrap<next_iteration_impl>
- , mpl::identity<mpl::false_>
- >::type
- continue_type;
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- static type call(Begin const& beg, End const& end, State const& state
- , Context const& context, Fun const& fun)
- {
- return call(beg, end, state, context, fun, typename fold_recurse_impl::continue_type());
- }
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- static type call(Begin const& beg, End const& end, State const& state
- , Context const& context, Fun const& fun, mpl::true_) // continue
- {
- return next_iteration_impl::call(
- fusion::next(beg)
- , end
- , fold_recurse_impl::call(
- *beg
- , state
- , push_context_impl::call(beg, end, context)
- , fun)
- , context
- , fun);
- }
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- static type call(Begin const& beg, End const& end, State const& state
- , Context const& context, Fun const& fun, mpl::false_) // break
- {
- return fold_recurse_impl::call(
- *beg
- , state
- , push_context_impl::call(beg, end, context)
- , fun);
- }
- };
- template <typename Begin, typename End, typename State, typename Context, typename Fun>
- struct segmented_fold_until_iterate_skip_empty<Begin, End, State, Context, Fun, true>
- {
- typedef
- segmented_fold_until_iterate<
- typename result_of::next<Begin>::type
- , End
- , State
- , Context
- , Fun
- >
- impl;
-
- typedef typename impl::type type;
- typedef typename impl::continue_type continue_type;
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- static type call(Begin const& beg, End const& end, State const& state
- , Context const& context, Fun const& fun)
- {
- return impl::call(fusion::next(beg), end, state, context, fun);
- }
- };
- template <typename Begin, typename End, typename State, typename Context, typename Fun, bool IsDone>
- struct segmented_fold_until_iterate
- {
- typedef
- typename result_of::empty<
- typename remove_reference<
- typename result_of::deref<Begin>::type
- >::type
- >::type
- empty_type;
- typedef
- segmented_fold_until_iterate_skip_empty<Begin, End, State, Context, Fun, empty_type::value>
- impl;
-
- typedef typename impl::type type;
- typedef typename impl::continue_type continue_type;
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- static type call(Begin const& beg, End const& end, State const& state
- , Context const& context, Fun const& fun)
- {
- return impl::call(beg, end, state, context, fun);
- }
- };
- template <typename Begin, typename End, typename State, typename Context, typename Fun>
- struct segmented_fold_until_iterate<Begin, End, State, Context, Fun, true>
- {
- typedef State type;
- typedef mpl::true_ continue_type;
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- static type call(Begin const&, End const&, State const& state
- , Context const&, Fun const&)
- {
- return state;
- }
- };
- template <typename Segments, typename State, typename Context, typename Fun>
- struct segmented_fold_until_on_segments
- {
- typedef
- segmented_fold_until_iterate<
- typename result_of::begin<Segments>::type
- , typename result_of::end<Segments>::type
- , State
- , Context
- , Fun
- >
- impl;
- typedef typename impl::type type;
- typedef typename impl::continue_type continue_type;
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- static type call(Segments& segs, State const& state, Context const& context, Fun const& fun)
- {
- return impl::call(fusion::begin(segs), fusion::end(segs), state, context, fun);
- }
- };
- }
- }}
- #endif
|