|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r62440 - sandbox/SOC/2009/fusion/boost/proto/transform
From: mr.chr.schmidt_at_[hidden]
Date: 2010-06-05 09:33:15
Author: cschmidt
Date: 2010-06-05 09:33:14 EDT (Sat, 05 Jun 2010)
New Revision: 62440
URL: http://svn.boost.org/trac/boost/changeset/62440
Log:
added /proto/transform/fold.hpp
Added:
sandbox/SOC/2009/fusion/boost/proto/transform/
sandbox/SOC/2009/fusion/boost/proto/transform/fold.hpp (contents, props changed)
Added: sandbox/SOC/2009/fusion/boost/proto/transform/fold.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2009/fusion/boost/proto/transform/fold.hpp 2010-06-05 09:33:14 EDT (Sat, 05 Jun 2010)
@@ -0,0 +1,315 @@
+#ifndef BOOST_PP_IS_ITERATING
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \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/proto/proto_fwd.hpp>
+ #include <boost/proto/fusion.hpp>
+ #include <boost/proto/traits.hpp>
+ #include <boost/proto/transform/call.hpp>
+ #include <boost/proto/transform/impl.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
+ {};
+
+ #define BOOST_PROTO_CHILD_N_TYPE(N)\
+ BOOST_PP_CAT(proto_child, N)\
+ /**/
+
+ #define BOOST_PROTO_FOLD_STATE_TYPE(Z, N, DATA) \
+ typedef \
+ typename when<_, Fun>::template impl< \
+ typename result_of::child_c<Expr, N>::type \
+ , BOOST_PP_CAT(state, N) \
+ , Data \
+ >::result_type \
+ BOOST_PP_CAT(state, BOOST_PP_INC(N)); \
+ /**/
+
+ #define BOOST_PROTO_FOLD_STATE(Z, N, DATA) \
+ BOOST_PP_CAT(state, BOOST_PP_INC(N)) \
+ BOOST_PP_CAT(s, BOOST_PP_INC(N)) \
+ = typename when<_, Fun>::template impl< \
+ typename result_of::child_c<Expr, N>::type \
+ , BOOST_PP_CAT(state, N) \
+ , Data \
+ >()( \
+ proto::child_c<N>(e) \
+ , BOOST_PP_CAT(s, N) \
+ , d \
+ ); \
+ /**/
+
+ #define BOOST_PROTO_REVERSE_FOLD_STATE_TYPE(Z, N, DATA) \
+ typedef \
+ typename when<_, Fun>::template impl< \
+ typename result_of::child_c< \
+ Expr \
+ , BOOST_PP_SUB(DATA, BOOST_PP_INC(N)) \
+ >::type \
+ , BOOST_PP_CAT(state, BOOST_PP_SUB(DATA, N)) \
+ , Data \
+ >::result_type \
+ BOOST_PP_CAT(state, BOOST_PP_SUB(DATA, BOOST_PP_INC(N))); \
+ /**/
+
+ #define BOOST_PROTO_REVERSE_FOLD_STATE(Z, N, DATA) \
+ BOOST_PP_CAT(state, BOOST_PP_SUB(DATA, BOOST_PP_INC(N))) \
+ BOOST_PP_CAT(s, BOOST_PP_SUB(DATA, BOOST_PP_INC(N))) \
+ = typename when<_, Fun>::template impl< \
+ typename result_of::child_c< \
+ Expr \
+ , BOOST_PP_SUB(DATA, BOOST_PP_INC(N)) \
+ >::type \
+ , BOOST_PP_CAT(state, BOOST_PP_SUB(DATA, N)) \
+ , Data \
+ >()( \
+ proto::child_c<BOOST_PP_SUB(DATA, BOOST_PP_INC(N))>(e) \
+ , BOOST_PP_CAT(s, BOOST_PP_SUB(DATA, N)) \
+ , d \
+ ); \
+ /**/
+
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/transform/fold.hpp>))
+ #include BOOST_PP_ITERATE()
+
+ #undef BOOST_PROTO_REVERSE_FOLD_STATE
+ #undef BOOST_PROTO_REVERSE_FOLD_STATE_TYPE
+ #undef BOOST_PROTO_FOLD_STATE
+ #undef BOOST_PROTO_FOLD_STATE_TYPE
+ #undef BOOST_PROTO_CHILD_N_TYPE
+
+ } // 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. It uses
+ /// the \c _reverse callable PolymorphicFunctionObject
+ /// to create a <tt>fusion::reverse_view\<\></tt> of the
+ /// sequence before invoking <tt>fusion::fold\<\></tt>.
+ template<typename Sequence, typename State0, typename Fun>
+ struct reverse_fold
+ : fold<call<_reverse(Sequence)>, State0, Fun>
+ {};
+
+ // 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
+
+#else
+
+ #define N BOOST_PP_ITERATION()
+
+ template<typename State0, typename Fun, typename Expr, typename State, typename Data>
+ struct fold_impl<State0, Fun, Expr, State, Data, N>
+ : transform_impl<Expr, State, Data>
+ {
+ typedef typename when<_, State0>::template impl<Expr, State, Data>::result_type state0;
+ BOOST_PP_REPEAT(N, BOOST_PROTO_FOLD_STATE_TYPE, N)
+ typedef BOOST_PP_CAT(state, N) result_type;
+
+ result_type operator ()(
+ typename fold_impl::expr_param e
+ , typename fold_impl::state_param s
+ , typename fold_impl::data_param d
+ ) const
+ {
+ state0 s0 =
+ typename when<_, State0>::template impl<Expr, State, Data>()(e, s, d);
+ BOOST_PP_REPEAT(N, BOOST_PROTO_FOLD_STATE, N)
+ return BOOST_PP_CAT(s, N);
+ }
+ };
+
+ template<typename State0, typename Fun, typename Expr, typename State, typename Data>
+ struct reverse_fold_impl<State0, Fun, Expr, State, Data, N>
+ : transform_impl<Expr, State, Data>
+ {
+ typedef typename when<_, State0>::template impl<Expr, State, Data>::result_type BOOST_PP_CAT(state, N);
+ BOOST_PP_REPEAT(N, BOOST_PROTO_REVERSE_FOLD_STATE_TYPE, N)
+ typedef state0 result_type;
+
+ result_type operator ()(
+ typename reverse_fold_impl::expr_param e
+ , typename reverse_fold_impl::state_param s
+ , typename reverse_fold_impl::data_param d
+ ) const
+ {
+ BOOST_PP_CAT(state, N) BOOST_PP_CAT(s, N) =
+ typename when<_, State0>::template impl<Expr, State, Data>()(e, s, d);
+ BOOST_PP_REPEAT(N, BOOST_PROTO_REVERSE_FOLD_STATE, N)
+ return s0;
+ }
+ };
+
+ #undef N
+
+#endif
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk