EVOLUTION-MANAGER
Edit File: segmented_fold_until_impl.hpp
/*============================================================================= 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