📄 fold.hpp
字号:
#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/xpressive/proto/detail/prefix.hpp> #include <boost/version.hpp> #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> #if BOOST_VERSION >= 103500 #include <boost/fusion/include/fold.hpp> #else #include <boost/spirit/fusion/algorithm/fold.hpp> #endif #include <boost/xpressive/proto/proto_fwd.hpp> #include <boost/xpressive/proto/fusion.hpp> #include <boost/xpressive/proto/traits.hpp> #include <boost/xpressive/proto/transform/call.hpp> #include <boost/xpressive/proto/detail/suffix.hpp> namespace boost { namespace proto { namespace transform { namespace detail { template<typename Transform, typename Visitor> struct as_callable { as_callable(Visitor &v) : v_(v) {} template<typename Sig> struct result; template<typename This, typename Expr, typename State> struct result<This(Expr, State)> { typedef typename when<_, Transform>::template result<void( BOOST_PROTO_UNCVREF(Expr) , BOOST_PROTO_UNCVREF(State) , Visitor )>::type type; }; #if BOOST_VERSION < 103500 template<typename Expr, typename State> struct apply : result<void(Expr, State)> {}; #endif template<typename Expr, typename State> typename when<_, Transform>::template result<void(Expr, State, Visitor)>::type operator ()(Expr const &expr, State const &state) const { return when<_, Transform>()(expr, state, this->v_); } private: Visitor &v_; }; #if BOOST_VERSION < 103500 template<typename Sequence, typename Void = void> struct as_fusion_sequence_type { typedef Sequence const type; }; template<typename Sequence> Sequence const &as_fusion_sequence(Sequence const &sequence, ...) { return sequence; } template<typename Sequence> struct as_fusion_sequence_type<Sequence, typename Sequence::proto_is_expr_> { typedef typename Sequence::proto_base_expr const type; }; template<typename Sequence> typename Sequence::proto_base_expr const &as_fusion_sequence(Sequence const &sequence, int) { return sequence.proto_base(); } #define BOOST_PROTO_AS_FUSION_SEQUENCE_TYPE(X) typename detail::as_fusion_sequence_type<X>::type #define BOOST_PROTO_AS_FUSION_SEQUENCE(X) detail::as_fusion_sequence(X, 0) #else #define BOOST_PROTO_AS_FUSION_SEQUENCE_TYPE(X) X #define BOOST_PROTO_AS_FUSION_SEQUENCE(X) X #endif template<typename Fun, typename Expr, typename State, typename Visitor, long Arity = Expr::proto_arity::value> struct fold_impl {}; template<typename Fun, typename Expr, typename State, typename Visitor, long Arity = Expr::proto_arity::value> struct reverse_fold_impl {}; #define BOOST_PROTO_ARG_N_TYPE(n)\ BOOST_PP_CAT(proto_arg, n)\ /**/ #define BOOST_PROTO_FOLD_STATE_TYPE(z, n, data)\ typedef\ typename when<_, Fun>::template result<void(\ typename Expr::BOOST_PROTO_ARG_N_TYPE(n)::proto_base_expr\ , BOOST_PP_CAT(state, n)\ , Visitor\ )>::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)) const &BOOST_PP_CAT(s, BOOST_PP_INC(n)) =\ when<_, Fun>()(expr.BOOST_PP_CAT(arg, n).proto_base(), BOOST_PP_CAT(s, n), visitor);\ /**/ #define BOOST_PROTO_REVERSE_FOLD_STATE_TYPE(z, n, data)\ typedef\ typename when<_, Fun>::template result<void(\ typename Expr::BOOST_PROTO_ARG_N_TYPE(BOOST_PP_SUB(data, BOOST_PP_INC(n)))::proto_base_expr\ , BOOST_PP_CAT(state, BOOST_PP_SUB(data, n))\ , Visitor\ )>::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))) const &BOOST_PP_CAT(s, BOOST_PP_SUB(data, BOOST_PP_INC(n))) =\ when<_, Fun>()(expr.BOOST_PP_CAT(arg, BOOST_PP_SUB(data, BOOST_PP_INC(n))).proto_base(), BOOST_PP_CAT(s, BOOST_PP_SUB(data, n)), visitor);\ /**/ #define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/xpressive/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_ARG_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 : proto::callable { template<typename Sig> struct result; template<typename This, typename Expr, typename State, typename Visitor> struct result<This(Expr, State, Visitor)> { /// \brief A Fusion sequence. typedef typename when<_, Sequence>::template result<void(Expr, State, Visitor)>::type sequence; /// \brief An initial state for the fold. typedef typename when<_, State0>::template result<void(Expr, State, Visitor)>::type state0; /// \brief <tt>fun(v)(e,s) == when\<_,Fun\>()(e,s,v)</tt> typedef detail::as_callable<Fun, Visitor> fun;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -