diff options
Diffstat (limited to '3rdParty/Boost/src/boost/proto/transform/make.hpp')
-rw-r--r-- | 3rdParty/Boost/src/boost/proto/transform/make.hpp | 472 |
1 files changed, 472 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/proto/transform/make.hpp b/3rdParty/Boost/src/boost/proto/transform/make.hpp new file mode 100644 index 0000000..964886c --- /dev/null +++ b/3rdParty/Boost/src/boost/proto/transform/make.hpp @@ -0,0 +1,472 @@ +#ifndef BOOST_PP_IS_ITERATING + /////////////////////////////////////////////////////////////////////////////// + /// \file make.hpp + /// Contains definition of the make<> transform. + // + // 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_MAKE_HPP_EAN_12_02_2007 + #define BOOST_PROTO_TRANSFORM_MAKE_HPP_EAN_12_02_2007 + + #include <boost/detail/workaround.hpp> + #include <boost/preprocessor/repetition/enum.hpp> + #include <boost/preprocessor/repetition/enum_params.hpp> + #include <boost/preprocessor/repetition/enum_trailing_params.hpp> + #include <boost/preprocessor/repetition/enum_binary_params.hpp> + #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp> + #include <boost/preprocessor/repetition/repeat_from_to.hpp> + #include <boost/preprocessor/facilities/intercept.hpp> + #include <boost/preprocessor/cat.hpp> + #include <boost/preprocessor/iteration/iterate.hpp> + #include <boost/preprocessor/selection/max.hpp> + #include <boost/preprocessor/arithmetic/inc.hpp> + #include <boost/mpl/and.hpp> + #include <boost/mpl/aux_/has_type.hpp> + #include <boost/mpl/aux_/template_arity.hpp> + #include <boost/mpl/aux_/lambda_arity_param.hpp> + #include <boost/utility/result_of.hpp> + #include <boost/proto/proto_fwd.hpp> + #include <boost/proto/traits.hpp> + #include <boost/proto/args.hpp> + #include <boost/proto/transform/impl.hpp> + #include <boost/proto/detail/as_lvalue.hpp> + #include <boost/proto/detail/ignore_unused.hpp> + + namespace boost { namespace proto + { + namespace detail + { + template<typename T> + struct is_applyable + : mpl::and_<is_callable<T>, is_transform<T> > + {}; + + template<typename T, bool HasType = mpl::aux::has_type<T>::value> + struct nested_type + { + typedef typename T::type type; + }; + + template<typename T> + struct nested_type<T, false> + { + typedef T type; + }; + + template<typename T, bool Applied> + struct nested_type_if + { + typedef T type; + static bool const applied = false; + }; + + template<typename T> + struct nested_type_if<T, true> + : nested_type<T> + { + static bool const applied = true; + }; + + template< + typename R + , typename Expr, typename State, typename Data + BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(long Arity = mpl::aux::template_arity<R>::value) + > + struct make_ + { + typedef R type; + static bool const applied = false; + }; + + template< + typename R + , typename Expr, typename State, typename Data + , bool IsApplyable = is_applyable<R>::value + > + struct make_if_ + : make_<R, Expr, State, Data> + {}; + + template<typename R, typename Expr, typename State, typename Data> + struct make_if_<R, Expr, State, Data, true> + : uncvref<typename when<_, R>::template impl<Expr, State, Data>::result_type> + { + static bool const applied = true; + }; + + #if BOOST_WORKAROUND(__GNUC__, == 3) || (__GNUC__ == 4 && __GNUC_MINOR__ == 0) + // work around GCC bug + template<typename Tag, typename Args, long N, typename Expr, typename State, typename Data> + struct make_if_<proto::expr<Tag, Args, N>, Expr, State, Data, false> + { + typedef proto::expr<Tag, Args, N> type; + static bool const applied = false; + }; + + // work around GCC bug + template<typename Tag, typename Args, long N, typename Expr, typename State, typename Data> + struct make_if_<proto::basic_expr<Tag, Args, N>, Expr, State, Data, false> + { + typedef proto::basic_expr<Tag, Args, N> type; + static bool const applied = false; + }; + #endif + + template<typename Type, bool IsAggregate = is_aggregate<Type>::value> + struct construct_ + { + typedef Type result_type; + + Type operator ()() const + { + return Type(); + } + + #define TMP(Z, N, DATA) \ + template<BOOST_PP_ENUM_PARAMS_Z(Z, N, typename A)> \ + Type operator ()(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, &a)) const \ + { \ + return Type(BOOST_PP_ENUM_PARAMS_Z(Z, N, a)); \ + } + BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), TMP, ~) + #undef TMP + }; + + template<typename Type> + struct construct_<Type, true> + { + typedef Type result_type; + + Type operator ()() const + { + return Type(); + } + + #define TMP(Z, N, DATA) \ + template<BOOST_PP_ENUM_PARAMS_Z(Z, N, typename A)> \ + Type operator ()(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, &a)) const \ + { \ + Type that = {BOOST_PP_ENUM_PARAMS_Z(Z, N, a)}; \ + return that; \ + } + BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), TMP, ~) + #undef TMP + }; + + #define TMP(Z, N, DATA) \ + template<typename Type BOOST_PP_ENUM_TRAILING_PARAMS_Z(Z, N, typename A)> \ + Type construct(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, &a)) \ + { \ + return construct_<Type>()(BOOST_PP_ENUM_PARAMS_Z(Z, N, a)); \ + } + BOOST_PP_REPEAT(BOOST_PROTO_MAX_ARITY, TMP, ~) + #undef TMP + } + + /// \brief A PrimitiveTransform which prevents another PrimitiveTransform + /// from being applied in an \c ObjectTransform. + /// + /// When building higher order transforms with <tt>make\<\></tt> or + /// <tt>lazy\<\></tt>, you sometimes would like to build types that + /// are parameterized with Proto transforms. In such lambda-style + /// transforms, Proto will unhelpfully find all nested transforms + /// and apply them, even if you don't want them to be applied. Consider + /// the following transform, which will replace the \c _ in + /// <tt>Bar<_>()</tt> with <tt>proto::terminal\<int\>::type</tt>: + /// + /// \code + /// template<typename T> + /// struct Bar + /// {}; + /// + /// struct Foo + /// : proto::when<_, Bar<_>() > + /// {}; + /// + /// proto::terminal<int>::type i = {0}; + /// + /// int main() + /// { + /// Foo()(i); + /// std::cout << typeid(Foo()(i)).name() << std::endl; + /// } + /// \endcode + /// + /// If you actually wanted to default-construct an object of type + /// <tt>Bar\<_\></tt>, you would have to protect the \c _ to prevent + /// it from being applied. You can use <tt>proto::protect\<\></tt> + /// as follows: + /// + /// \code + /// // OK: replace anything with Bar<_>() + /// struct Foo + /// : proto::when<_, Bar<protect<_> >() > + /// {}; + /// \endcode + template<typename PrimitiveTransform> + struct protect : transform<protect<PrimitiveTransform> > + { + template<typename, typename, typename> + struct impl + { + typedef PrimitiveTransform result_type; + }; + }; + + /// \brief A PrimitiveTransform which computes a type by evaluating any + /// nested transforms and then constructs an object of that type. + /// + /// The <tt>make\<\></tt> transform checks to see if \c Object is a template. + /// If it is, the template type is disassembled to find nested transforms. + /// Proto considers the following types to represent transforms: + /// + /// \li Function types + /// \li Function pointer types + /// \li Types for which <tt>proto::is_callable\< type \>::value</tt> is \c true + /// + /// <tt>boost::result_of\<make\<T\<X0,X1,...\> \>(Expr, State, Data)\>::type</tt> + /// is evaluated as follows. For each \c X in <tt>X0,X1,...</tt>, do: + /// + /// \li If \c X is a template like <tt>U\<Y0,Y1,...\></tt>, then let <tt>X'</tt> + /// be <tt>boost::result_of\<make\<U\<Y0,Y1,...\> \>(Expr, State, Data)\>::type</tt> + /// (which evaluates this procedure recursively). Note whether any + /// substitutions took place during this operation. + /// \li Otherwise, if \c X is a transform, then let <tt>X'</tt> be + /// <tt>boost::result_of\<when\<_, X\>(Expr, State, Data)\>::type</tt>. + /// Note that a substitution took place. + /// \li Otherwise, let <tt>X'</tt> be \c X, and note that no substitution + /// took place. + /// \li If any substitutions took place in any of the above steps and + /// <tt>T\<X0',X1',...\></tt> has a nested <tt>::type</tt> typedef, + /// the result type is <tt>T\<X0',X1',...\>::type</tt>. + /// \li Otherwise, the result type is <tt>T\<X0',X1',...\></tt>. + /// + /// Note that <tt>when\<\></tt> is implemented in terms of <tt>call\<\></tt> + /// and <tt>make\<\></tt>, so the above procedure is evaluated recursively. + template<typename Object> + struct make : transform<make<Object> > + { + template<typename Expr, typename State, typename Data> + struct impl : transform_impl<Expr, State, Data> + { + typedef typename detail::make_if_<Object, Expr, State, Data>::type result_type; + + /// \return <tt>result_type()</tt> + result_type operator ()( + typename impl::expr_param + , typename impl::state_param + , typename impl::data_param + ) const + { + return result_type(); + } + }; + }; + + #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PROTO_MAX_ARITY, <boost/proto/transform/make.hpp>)) + #include BOOST_PP_ITERATE() + + /// INTERNAL ONLY + /// + template<typename Object> + struct is_callable<make<Object> > + : mpl::true_ + {}; + + /// INTERNAL ONLY + /// + template<typename PrimitiveTransform> + struct is_callable<protect<PrimitiveTransform> > + : mpl::true_ + {}; + + }} + + #endif + +#else + + #define N BOOST_PP_ITERATION() + + namespace detail + { + #if N > 0 + #define TMP0(Z, M, DATA) make_if_<BOOST_PP_CAT(A, M), Expr, State, Data> + #define TMP1(Z, M, DATA) typename TMP0(Z, M, DATA) ::type + #define TMP2(Z, M, DATA) TMP0(Z, M, DATA) ::applied || + + template< + template<BOOST_PP_ENUM_PARAMS(N, typename BOOST_PP_INTERCEPT)> class R + BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A) + , typename Expr, typename State, typename Data + > + struct make_< + R<BOOST_PP_ENUM_PARAMS(N, A)> + , Expr, State, Data + BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(N) + > + : nested_type_if<R<BOOST_PP_ENUM(N, TMP1, ~)>, (BOOST_PP_REPEAT(N, TMP2, ~) false)> + {}; + + template< + template<BOOST_PP_ENUM_PARAMS(N, typename BOOST_PP_INTERCEPT)> class R + BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A) + , typename Expr, typename State, typename Data + > + struct make_< + noinvoke<R<BOOST_PP_ENUM_PARAMS(N, A)> > + , Expr, State, Data + BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(1) + > + { + typedef R<BOOST_PP_ENUM(N, TMP1, ~)> type; + static bool const applied = true; + }; + + #undef TMP0 + #undef TMP1 + #undef TMP2 + #endif + + template<typename R BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)> + struct is_applyable<R(BOOST_PP_ENUM_PARAMS(N, A))> + : mpl::true_ + {}; + + template<typename R BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)> + struct is_applyable<R(*)(BOOST_PP_ENUM_PARAMS(N, A))> + : mpl::true_ + {}; + + template<typename T, typename A> + struct construct_<proto::expr<T, A, N>, true> + { + typedef proto::expr<T, A, N> result_type; + + template<BOOST_PP_ENUM_PARAMS(BOOST_PP_MAX(N, 1), typename A)> + result_type operator ()(BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_MAX(N, 1), A, &a)) const + { + return result_type::make(BOOST_PP_ENUM_PARAMS(BOOST_PP_MAX(N, 1), a)); + } + }; + + template<typename T, typename A> + struct construct_<proto::basic_expr<T, A, N>, true> + { + typedef proto::basic_expr<T, A, N> result_type; + + template<BOOST_PP_ENUM_PARAMS(BOOST_PP_MAX(N, 1), typename A)> + result_type operator ()(BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_MAX(N, 1), A, &a)) const + { + return result_type::make(BOOST_PP_ENUM_PARAMS(BOOST_PP_MAX(N, 1), a)); + } + }; + } + + /// \brief A PrimitiveTransform which computes a type by evaluating any + /// nested transforms and then constructs an object of that type with the + /// current expression, state and data, transformed according + /// to \c A0 through \c AN. + template<typename Object BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)> + struct make<Object(BOOST_PP_ENUM_PARAMS(N, A))> + : transform<make<Object(BOOST_PP_ENUM_PARAMS(N, A))> > + { + template<typename Expr, typename State, typename Data> + struct impl : transform_impl<Expr, State, Data> + { + /// \brief <tt>boost::result_of\<make\<Object\>(Expr, State, Data)\>::type</tt> + typedef typename detail::make_if_<Object, Expr, State, Data>::type result_type; + + /// Let \c ax be <tt>when\<_, Ax\>()(e, s, d)</tt> + /// for each \c x in <tt>[0,N]</tt>. + /// Return <tt>result_type(a0, a1,... aN)</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 + { + proto::detail::ignore_unused(e); + proto::detail::ignore_unused(s); + proto::detail::ignore_unused(d); + return detail::construct<result_type>( + #define TMP(Z, M, DATA) \ + detail::as_lvalue( \ + typename when<_, BOOST_PP_CAT(A, M)> \ + ::template impl<Expr, State, Data>()(e, s, d) \ + ) + BOOST_PP_ENUM(N, TMP, DATA) + #undef TMP + ); + } + }; + }; + + #if BOOST_WORKAROUND(__GNUC__, == 3) || (__GNUC__ == 4 && __GNUC_MINOR__ == 0) + // work around GCC bug + template<typename Tag, typename Args, long Arity BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)> + struct make<proto::expr<Tag, Args, Arity>(BOOST_PP_ENUM_PARAMS(N, A))> + : transform<make<proto::expr<Tag, Args, Arity>(BOOST_PP_ENUM_PARAMS(N, A))> > + { + template<typename Expr, typename State, typename Data> + struct impl : transform_impl<Expr, State, Data> + { + typedef proto::expr<Tag, Args, Arity> result_type; + + result_type operator ()( + typename impl::expr_param e + , typename impl::state_param s + , typename impl::data_param d + ) const + { + return proto::expr<Tag, Args, Arity>::make( + #define TMP(Z, M, DATA) \ + detail::as_lvalue( \ + typename when<_, BOOST_PP_CAT(A, M)> \ + ::template impl<Expr, State, Data>()(e, s, d) \ + ) + BOOST_PP_ENUM(N, TMP, DATA) + #undef TMP + ); + } + }; + }; + + template<typename Tag, typename Args, long Arity BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)> + struct make<proto::basic_expr<Tag, Args, Arity>(BOOST_PP_ENUM_PARAMS(N, A))> + : transform<make<proto::basic_expr<Tag, Args, Arity>(BOOST_PP_ENUM_PARAMS(N, A))> > + { + template<typename Expr, typename State, typename Data> + struct impl : transform_impl<Expr, State, Data> + { + typedef proto::basic_expr<Tag, Args, Arity> result_type; + + result_type operator ()( + typename impl::expr_param e + , typename impl::state_param s + , typename impl::data_param d + ) const + { + return proto::basic_expr<Tag, Args, Arity>::make( + #define TMP(Z, M, DATA) \ + detail::as_lvalue( \ + typename when<_, BOOST_PP_CAT(A, M)> \ + ::template impl<Expr, State, Data>()(e, s, d) \ + ) + BOOST_PP_ENUM(N, TMP, DATA) + #undef TMP + ); + } + }; + }; + #endif + + #undef N + +#endif |