/*============================================================================= 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include // 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 struct iterator_range; template struct segmented_iterator; namespace result_of { template 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 > type; }; } template BOOST_FUSION_GPU_ENABLED typename result_of::make_segmented_iterator::type make_segmented_iterator(Cur const& cur, Context const& context) { typedef result_of::make_segmented_iterator impl_type; typedef typename impl_type::type type; typedef typename impl_type::range_type range_type; return type(cons(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::type::value > struct segmented_fold_until_iterate; template < typename Sequence , typename State , typename Context , typename Fun , bool IsSegmented = traits::is_segmented::type::value > struct segmented_fold_until_impl; template struct segmented_fold_until_on_segments; //auto push_context(cur, end, context) //{ // return push_back(context, segment_sequence(iterator_range(cur, end))); //} template struct push_context { typedef iterator_range range_type; typedef cons type; BOOST_FUSION_GPU_ENABLED static type call(Cur const& cur, End const& end, Context const& context) { return cons(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::type >::type >::type , State , Context , Fun > impl; typedef typename impl::type type; typedef typename impl::continue_type continue_type; 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 { typedef typename Fun::template apply apply_type; typedef typename apply_type::type type; typedef typename apply_type::continue_type continue_type; 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 struct continue_wrap { typedef typename Apply::continue_type type; }; template struct segmented_fold_until_iterate_skip_empty { // begin != end and !empty(*begin) typedef push_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::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::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 >::type type; typedef typename mpl::eval_if< typename fold_recurse_impl::continue_type , continue_wrap , mpl::identity >::type continue_type; 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_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_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 struct segmented_fold_until_iterate_skip_empty { typedef segmented_fold_until_iterate< typename result_of::next::type , End , State , Context , Fun > impl; typedef typename impl::type type; typedef typename impl::continue_type continue_type; 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 struct segmented_fold_until_iterate { typedef typename result_of::empty< typename remove_reference< typename result_of::deref::type >::type >::type empty_type; typedef segmented_fold_until_iterate_skip_empty impl; typedef typename impl::type type; typedef typename impl::continue_type continue_type; 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 struct segmented_fold_until_iterate { typedef State type; typedef mpl::true_ continue_type; BOOST_FUSION_GPU_ENABLED static type call(Begin const&, End const&, State const& state , Context const&, Fun const&) { return state; } }; template struct segmented_fold_until_on_segments { typedef segmented_fold_until_iterate< typename result_of::begin::type , typename result_of::end::type , State , Context , Fun > impl; typedef typename impl::type type; typedef typename impl::continue_type continue_type; 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