diff DEPENDENCIES/generic/include/boost/proto/transform/fold.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DEPENDENCIES/generic/include/boost/proto/transform/fold.hpp	Tue Aug 05 11:11:38 2014 +0100
@@ -0,0 +1,250 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file fold.hpp
+/// Contains definition of the fold<> and reverse_fold<> transforms.
+//
+//  Copyright 2008 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)
+
+#ifndef BOOST_PROTO_TRANSFORM_FOLD_HPP_EAN_11_04_2007
+#define BOOST_PROTO_TRANSFORM_FOLD_HPP_EAN_11_04_2007
+
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/arithmetic/inc.hpp>
+#include <boost/preprocessor/arithmetic/sub.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/fusion/include/fold.hpp>
+#include <boost/fusion/include/reverse_fold.hpp>
+#include <boost/proto/proto_fwd.hpp>
+#include <boost/proto/traits.hpp>
+#include <boost/proto/transform/impl.hpp>
+#include <boost/proto/transform/when.hpp>
+
+namespace boost { namespace proto
+{
+    namespace detail
+    {
+        template<typename Transform, typename Data>
+        struct as_callable
+        {
+            as_callable(Data d)
+              : d_(d)
+            {}
+
+            template<typename Sig>
+            struct result;
+
+            template<typename This, typename State, typename Expr>
+            struct result<This(State, Expr)>
+            {
+                typedef
+                    typename when<_, Transform>::template impl<Expr, State, Data>::result_type
+                type;
+            };
+
+            template<typename State, typename Expr>
+            typename when<_, Transform>::template impl<Expr &, State const &, Data>::result_type
+            operator ()(State const &s, Expr &e) const
+            {
+                return typename when<_, Transform>::template impl<Expr &, State const &, Data>()(e, s, this->d_);
+            }
+
+        private:
+            Data d_;
+        };
+
+        template<
+            typename State0
+          , typename Fun
+          , typename Expr
+          , typename State
+          , typename Data
+          , long Arity = arity_of<Expr>::value
+        >
+        struct fold_impl
+        {};
+
+        template<
+            typename State0
+          , typename Fun
+          , typename Expr
+          , typename State
+          , typename Data
+          , long Arity = arity_of<Expr>::value
+        >
+        struct reverse_fold_impl
+        {};
+
+        #include <boost/proto/transform/detail/fold_impl.hpp>
+
+    } // namespace detail
+
+    /// \brief A PrimitiveTransform that invokes the <tt>fusion::fold\<\></tt>
+    /// algorithm to accumulate
+    template<typename Sequence, typename State0, typename Fun>
+    struct fold : transform<fold<Sequence, State0, Fun> >
+    {
+        template<typename Expr, typename State, typename Data>
+        struct impl : transform_impl<Expr, State, Data>
+        {
+            /// \brief A Fusion sequence.
+            typedef
+                typename remove_reference<
+                    typename when<_, Sequence>::template impl<Expr, State, Data>::result_type
+                >::type
+            sequence;
+
+            /// \brief An initial state for the fold.
+            typedef
+                typename remove_reference<
+                    typename when<_, State0>::template impl<Expr, State, Data>::result_type
+                >::type
+            state0;
+
+            /// \brief <tt>fun(d)(e,s) == when\<_,Fun\>()(e,s,d)</tt>
+            typedef
+                detail::as_callable<Fun, Data>
+            fun;
+
+            typedef
+                typename fusion::result_of::fold<
+                    sequence
+                  , state0
+                  , fun
+                >::type
+            result_type;
+
+            /// Let \c seq be <tt>when\<_, Sequence\>()(e, s, d)</tt>, let
+            /// \c state0 be <tt>when\<_, State0\>()(e, s, d)</tt>, and
+            /// let \c fun(d) be an object such that <tt>fun(d)(e, s)</tt>
+            /// is equivalent to <tt>when\<_, Fun\>()(e, s, d)</tt>. Then, this
+            /// function returns <tt>fusion::fold(seq, state0, fun(d))</tt>.
+            ///
+            /// \param e The current expression
+            /// \param s The current state
+            /// \param d An arbitrary data
+            result_type operator ()(
+                typename impl::expr_param   e
+              , typename impl::state_param  s
+              , typename impl::data_param   d
+            ) const
+            {
+                typename when<_, Sequence>::template impl<Expr, State, Data> seq;
+                detail::as_callable<Fun, Data> f(d);
+                return fusion::fold(
+                    seq(e, s, d)
+                  , typename when<_, State0>::template impl<Expr, State, Data>()(e, s, d)
+                  , f
+                );
+            }
+        };
+    };
+
+    /// \brief A PrimitiveTransform that is the same as the
+    /// <tt>fold\<\></tt> transform, except that it folds
+    /// back-to-front instead of front-to-back.
+    template<typename Sequence, typename State0, typename Fun>
+    struct reverse_fold  : transform<reverse_fold<Sequence, State0, Fun> >
+    {
+        template<typename Expr, typename State, typename Data>
+        struct impl : transform_impl<Expr, State, Data>
+        {
+            /// \brief A Fusion sequence.
+            typedef
+                typename remove_reference<
+                    typename when<_, Sequence>::template impl<Expr, State, Data>::result_type
+                >::type
+            sequence;
+
+            /// \brief An initial state for the fold.
+            typedef
+                typename remove_reference<
+                    typename when<_, State0>::template impl<Expr, State, Data>::result_type
+                >::type
+            state0;
+
+            /// \brief <tt>fun(d)(e,s) == when\<_,Fun\>()(e,s,d)</tt>
+            typedef
+                detail::as_callable<Fun, Data>
+            fun;
+
+            typedef
+                typename fusion::result_of::reverse_fold<
+                    sequence
+                  , state0
+                  , fun
+                >::type
+            result_type;
+
+            /// Let \c seq be <tt>when\<_, Sequence\>()(e, s, d)</tt>, let
+            /// \c state0 be <tt>when\<_, State0\>()(e, s, d)</tt>, and
+            /// let \c fun(d) be an object such that <tt>fun(d)(e, s)</tt>
+            /// is equivalent to <tt>when\<_, Fun\>()(e, s, d)</tt>. Then, this
+            /// function returns <tt>fusion::fold(seq, state0, fun(d))</tt>.
+            ///
+            /// \param e The current expression
+            /// \param s The current state
+            /// \param d An arbitrary data
+            result_type operator ()(
+                typename impl::expr_param   e
+              , typename impl::state_param  s
+              , typename impl::data_param   d
+            ) const
+            {
+                typename when<_, Sequence>::template impl<Expr, State, Data> seq;
+                detail::as_callable<Fun, Data> f(d);
+                return fusion::reverse_fold(
+                    seq(e, s, d)
+                  , typename when<_, State0>::template impl<Expr, State, Data>()(e, s, d)
+                  , f
+                );
+            }
+        };
+    };
+
+    // This specialization is only for improved compile-time performance
+    // in the commom case when the Sequence transform is \c proto::_.
+    //
+    /// INTERNAL ONLY
+    ///
+    template<typename State0, typename Fun>
+    struct fold<_, State0, Fun> : transform<fold<_, State0, Fun> >
+    {
+        template<typename Expr, typename State, typename Data>
+        struct impl
+          : detail::fold_impl<State0, Fun, Expr, State, Data>
+        {};
+    };
+
+    // This specialization is only for improved compile-time performance
+    // in the commom case when the Sequence transform is \c proto::_.
+    //
+    /// INTERNAL ONLY
+    ///
+    template<typename State0, typename Fun>
+    struct reverse_fold<_, State0, Fun> : transform<reverse_fold<_, State0, Fun> >
+    {
+        template<typename Expr, typename State, typename Data>
+        struct impl
+          : detail::reverse_fold_impl<State0, Fun, Expr, State, Data>
+        {};
+    };
+
+    /// INTERNAL ONLY
+    ///
+    template<typename Sequence, typename State, typename Fun>
+    struct is_callable<fold<Sequence, State, Fun> >
+      : mpl::true_
+    {};
+
+    /// INTERNAL ONLY
+    ///
+    template<typename Sequence, typename State, typename Fun>
+    struct is_callable<reverse_fold<Sequence, State, Fun> >
+      : mpl::true_
+    {};
+
+}}
+
+#endif