PageRenderTime 35ms CodeModel.GetById 13ms app.highlight 19ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/proto/transform/fold.hpp

http://hadesmem.googlecode.com/
C++ Header | 250 lines | 173 code | 27 blank | 50 comment | 0 complexity | 87876689bef940f363b5b5e7ba9d172e MD5 | raw file
  1///////////////////////////////////////////////////////////////////////////////
  2/// \file fold.hpp
  3/// Contains definition of the fold<> and reverse_fold<> transforms.
  4//
  5//  Copyright 2008 Eric Niebler. Distributed under the Boost
  6//  Software License, Version 1.0. (See accompanying file
  7//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  8
  9#ifndef BOOST_PROTO_TRANSFORM_FOLD_HPP_EAN_11_04_2007
 10#define BOOST_PROTO_TRANSFORM_FOLD_HPP_EAN_11_04_2007
 11
 12#include <boost/preprocessor/cat.hpp>
 13#include <boost/preprocessor/iteration/iterate.hpp>
 14#include <boost/preprocessor/arithmetic/inc.hpp>
 15#include <boost/preprocessor/arithmetic/sub.hpp>
 16#include <boost/preprocessor/repetition/repeat.hpp>
 17#include <boost/fusion/include/fold.hpp>
 18#include <boost/fusion/include/reverse_fold.hpp>
 19#include <boost/proto/proto_fwd.hpp>
 20#include <boost/proto/traits.hpp>
 21#include <boost/proto/transform/impl.hpp>
 22#include <boost/proto/transform/when.hpp>
 23
 24namespace boost { namespace proto
 25{
 26    namespace detail
 27    {
 28        template<typename Transform, typename Data>
 29        struct as_callable
 30        {
 31            as_callable(Data d)
 32              : d_(d)
 33            {}
 34
 35            template<typename Sig>
 36            struct result;
 37
 38            template<typename This, typename State, typename Expr>
 39            struct result<This(State, Expr)>
 40            {
 41                typedef
 42                    typename when<_, Transform>::template impl<Expr, State, Data>::result_type
 43                type;
 44            };
 45
 46            template<typename State, typename Expr>
 47            typename when<_, Transform>::template impl<Expr &, State const &, Data>::result_type
 48            operator ()(State const &s, Expr &e) const
 49            {
 50                return typename when<_, Transform>::template impl<Expr &, State const &, Data>()(e, s, this->d_);
 51            }
 52
 53        private:
 54            Data d_;
 55        };
 56
 57        template<
 58            typename State0
 59          , typename Fun
 60          , typename Expr
 61          , typename State
 62          , typename Data
 63          , long Arity = arity_of<Expr>::value
 64        >
 65        struct fold_impl
 66        {};
 67
 68        template<
 69            typename State0
 70          , typename Fun
 71          , typename Expr
 72          , typename State
 73          , typename Data
 74          , long Arity = arity_of<Expr>::value
 75        >
 76        struct reverse_fold_impl
 77        {};
 78
 79        #include <boost/proto/transform/detail/fold_impl.hpp>
 80
 81    } // namespace detail
 82
 83    /// \brief A PrimitiveTransform that invokes the <tt>fusion::fold\<\></tt>
 84    /// algorithm to accumulate
 85    template<typename Sequence, typename State0, typename Fun>
 86    struct fold : transform<fold<Sequence, State0, Fun> >
 87    {
 88        template<typename Expr, typename State, typename Data>
 89        struct impl : transform_impl<Expr, State, Data>
 90        {
 91            /// \brief A Fusion sequence.
 92            typedef
 93                typename remove_reference<
 94                    typename when<_, Sequence>::template impl<Expr, State, Data>::result_type
 95                >::type
 96            sequence;
 97
 98            /// \brief An initial state for the fold.
 99            typedef
100                typename remove_reference<
101                    typename when<_, State0>::template impl<Expr, State, Data>::result_type
102                >::type
103            state0;
104
105            /// \brief <tt>fun(d)(e,s) == when\<_,Fun\>()(e,s,d)</tt>
106            typedef
107                detail::as_callable<Fun, Data>
108            fun;
109
110            typedef
111                typename fusion::result_of::fold<
112                    sequence
113                  , state0
114                  , fun
115                >::type
116            result_type;
117
118            /// Let \c seq be <tt>when\<_, Sequence\>()(e, s, d)</tt>, let
119            /// \c state0 be <tt>when\<_, State0\>()(e, s, d)</tt>, and
120            /// let \c fun(d) be an object such that <tt>fun(d)(e, s)</tt>
121            /// is equivalent to <tt>when\<_, Fun\>()(e, s, d)</tt>. Then, this
122            /// function returns <tt>fusion::fold(seq, state0, fun(d))</tt>.
123            ///
124            /// \param e The current expression
125            /// \param s The current state
126            /// \param d An arbitrary data
127            result_type operator ()(
128                typename impl::expr_param   e
129              , typename impl::state_param  s
130              , typename impl::data_param   d
131            ) const
132            {
133                typename when<_, Sequence>::template impl<Expr, State, Data> seq;
134                detail::as_callable<Fun, Data> f(d);
135                return fusion::fold(
136                    seq(e, s, d)
137                  , typename when<_, State0>::template impl<Expr, State, Data>()(e, s, d)
138                  , f
139                );
140            }
141        };
142    };
143
144    /// \brief A PrimitiveTransform that is the same as the
145    /// <tt>fold\<\></tt> transform, except that it folds
146    /// back-to-front instead of front-to-back.
147    template<typename Sequence, typename State0, typename Fun>
148    struct reverse_fold  : transform<reverse_fold<Sequence, State0, Fun> >
149    {
150        template<typename Expr, typename State, typename Data>
151        struct impl : transform_impl<Expr, State, Data>
152        {
153            /// \brief A Fusion sequence.
154            typedef
155                typename remove_reference<
156                    typename when<_, Sequence>::template impl<Expr, State, Data>::result_type
157                >::type
158            sequence;
159
160            /// \brief An initial state for the fold.
161            typedef
162                typename remove_reference<
163                    typename when<_, State0>::template impl<Expr, State, Data>::result_type
164                >::type
165            state0;
166
167            /// \brief <tt>fun(d)(e,s) == when\<_,Fun\>()(e,s,d)</tt>
168            typedef
169                detail::as_callable<Fun, Data>
170            fun;
171
172            typedef
173                typename fusion::result_of::reverse_fold<
174                    sequence
175                  , state0
176                  , fun
177                >::type
178            result_type;
179
180            /// Let \c seq be <tt>when\<_, Sequence\>()(e, s, d)</tt>, let
181            /// \c state0 be <tt>when\<_, State0\>()(e, s, d)</tt>, and
182            /// let \c fun(d) be an object such that <tt>fun(d)(e, s)</tt>
183            /// is equivalent to <tt>when\<_, Fun\>()(e, s, d)</tt>. Then, this
184            /// function returns <tt>fusion::fold(seq, state0, fun(d))</tt>.
185            ///
186            /// \param e The current expression
187            /// \param s The current state
188            /// \param d An arbitrary data
189            result_type operator ()(
190                typename impl::expr_param   e
191              , typename impl::state_param  s
192              , typename impl::data_param   d
193            ) const
194            {
195                typename when<_, Sequence>::template impl<Expr, State, Data> seq;
196                detail::as_callable<Fun, Data> f(d);
197                return fusion::reverse_fold(
198                    seq(e, s, d)
199                  , typename when<_, State0>::template impl<Expr, State, Data>()(e, s, d)
200                  , f
201                );
202            }
203        };
204    };
205
206    // This specialization is only for improved compile-time performance
207    // in the commom case when the Sequence transform is \c proto::_.
208    //
209    /// INTERNAL ONLY
210    ///
211    template<typename State0, typename Fun>
212    struct fold<_, State0, Fun> : transform<fold<_, State0, Fun> >
213    {
214        template<typename Expr, typename State, typename Data>
215        struct impl
216          : detail::fold_impl<State0, Fun, Expr, State, Data>
217        {};
218    };
219
220    // This specialization is only for improved compile-time performance
221    // in the commom case when the Sequence transform is \c proto::_.
222    //
223    /// INTERNAL ONLY
224    ///
225    template<typename State0, typename Fun>
226    struct reverse_fold<_, State0, Fun> : transform<reverse_fold<_, State0, Fun> >
227    {
228        template<typename Expr, typename State, typename Data>
229        struct impl
230          : detail::reverse_fold_impl<State0, Fun, Expr, State, Data>
231        {};
232    };
233
234    /// INTERNAL ONLY
235    ///
236    template<typename Sequence, typename State, typename Fun>
237    struct is_callable<fold<Sequence, State, Fun> >
238      : mpl::true_
239    {};
240
241    /// INTERNAL ONLY
242    ///
243    template<typename Sequence, typename State, typename Fun>
244    struct is_callable<reverse_fold<Sequence, State, Fun> >
245      : mpl::true_
246    {};
247
248}}
249
250#endif