X-Git-Url: https://git.donarmstrong.com/?p=rsem.git;a=blobdiff_plain;f=boost%2Ffusion%2Fsupport%2Fdetail%2Fsegmented_fold_until_impl.hpp;fp=boost%2Ffusion%2Fsupport%2Fdetail%2Fsegmented_fold_until_impl.hpp;h=08096c16ae3839de6877d974a0bd949c68691c25;hp=0000000000000000000000000000000000000000;hb=2d71eb92104693ca9baa5a2e1c23eeca776d8fd3;hpb=da57529b92adbb7ae74a89861cb39fb35ac7c62d diff --git a/boost/fusion/support/detail/segmented_fold_until_impl.hpp b/boost/fusion/support/detail/segmented_fold_until_impl.hpp new file mode 100644 index 0000000..08096c1 --- /dev/null +++ b/boost/fusion/support/detail/segmented_fold_until_impl.hpp @@ -0,0 +1,389 @@ +/*============================================================================= + 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 + +// 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 + 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; + + 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; + + 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; + + 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; + + 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()); + } + + 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); + } + + 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; + + 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; + + 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; + + 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; + + 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