]> git.donarmstrong.com Git - rsem.git/blobdiff - boost/fusion/support/detail/segmented_fold_until_impl.hpp
Updated boost to v1.55.0
[rsem.git] / boost / fusion / support / detail / segmented_fold_until_impl.hpp
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 (file)
index 0000000..08096c1
--- /dev/null
@@ -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 <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>
+    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;
+
+            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;
+
+            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;
+
+            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;
+
+            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 <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;
+
+            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;
+
+            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;
+
+            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;
+
+            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