diff options
Diffstat (limited to '3rdParty/Boost/src/boost/proto/transform/fold.hpp')
-rw-r--r-- | 3rdParty/Boost/src/boost/proto/transform/fold.hpp | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/proto/transform/fold.hpp b/3rdParty/Boost/src/boost/proto/transform/fold.hpp new file mode 100644 index 0000000..52a35e3 --- /dev/null +++ b/3rdParty/Boost/src/boost/proto/transform/fold.hpp @@ -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 |