#ifndef BOOST_PP_IS_ITERATING /////////////////////////////////////////////////////////////////////////////// /// \file traits.hpp /// Contains definitions for arg\<\>, arg_c\<\>, left\<\>, /// right\<\>, tag_of\<\>, and the helper functions arg(), arg_c(), /// left() and right(). // // 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_ARG_TRAITS_HPP_EAN_04_01_2005 #define BOOST_PROTO_ARG_TRAITS_HPP_EAN_04_01_2005 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if BOOST_WORKAROUND( BOOST_MSVC, == 1310 ) #define BOOST_PROTO_IS_ARRAY_(T) boost::is_array::type> #else #define BOOST_PROTO_IS_ARRAY_(T) boost::is_array #endif #if BOOST_WORKAROUND( BOOST_MSVC, >= 1400 ) #pragma warning(push) #pragma warning(disable: 4180) // warning C4180: qualifier applied to function type has no meaning; ignored #endif namespace boost { namespace proto { namespace detail { template struct if_vararg {}; template struct if_vararg : T {}; template struct is_callable2_ : mpl::false_ {}; template struct is_callable2_ : mpl::true_ {}; template::value)> struct is_callable_ : is_callable2_ {}; } /// \brief Boolean metafunction which detects whether a type is /// a callable function object type or not. /// /// is_callable\<\> is used by the when\<\> transform /// to determine whether a function type R(A1,A2,...AN) is a /// callable transform or an object transform. (The former are evaluated /// using call\<\> and the later with make\<\>.) If /// is_callable\::::value is \c true, the function type is /// a callable transform; otherwise, it is an object transform. /// /// Unless specialized for a type \c T, is_callable\::::value /// is computed as follows: /// /// \li If \c T is a template type X\, where all \c Yx /// are types for \c x in [0,N], is_callable\::::value /// is is_same\::::value. /// \li If \c T has a nested type \c proto_is_callable_ that is a typedef /// for \c void, is_callable\::::value is \c true. (Note: this is /// the case for any type that derives from \c proto::callable.) /// \li Otherwise, is_callable\::::value is \c false. template struct is_callable : proto::detail::is_callable_ {}; /// INTERNAL ONLY /// template<> struct is_callable : mpl::true_ {}; /// INTERNAL ONLY /// template<> struct is_callable : mpl::false_ {}; #if BOOST_WORKAROUND(__GNUC__, == 3) // work around GCC bug template struct is_callable > : mpl::false_ {}; #endif /// \brief A Boolean metafunction that indicates whether a type requires /// aggregate initialization. /// /// is_aggregate\<\> is used by the make\<\> transform /// to determine how to construct an object of some type \c T, given some /// initialization arguments a0,a1,...aN. /// If is_aggregate\::::value is \c true, then an object of /// type T will be initialized as T t = {a0,a1,...aN};. Otherwise, /// it will be initialized as T t(a0,a1,...aN). template struct is_aggregate : is_pod {}; /// \brief Specialization of is_aggregate\<\> that indicates /// that objects of expr\<\> type require aggregate initialization. template struct is_aggregate > : mpl::true_ {}; namespace result_of { /// \brief A Boolean metafunction that indicates whether a given /// type \c T is a Proto expression type. /// /// If \c T has a nested type \c proto_is_expr_ that is a typedef /// for \c void, is_expr\::::value is \c true. (Note, this /// is the case for proto::expr\<\>, any type that is derived /// from proto::extends\<\> or that uses the /// BOOST_PROTO_EXTENDS() macro.) Otherwise, /// is_expr\::::value is \c false. template struct is_expr : mpl::false_ {}; /// \brief A Boolean metafunction that indicates whether a given /// type \c T is a Proto expression type. /// /// If \c T has a nested type \c proto_is_expr_ that is a typedef /// for \c void, is_expr\::::value is \c true. (Note, this /// is the case for proto::expr\<\>, any type that is derived /// from proto::extends\<\> or that uses the /// BOOST_PROTO_EXTENDS() macro.) Otherwise, /// is_expr\::::value is \c false. template struct is_expr : mpl::true_ {}; /// \brief A metafunction that returns the tag type of a /// Proto expression. template struct tag_of { typedef typename Expr::proto_tag type; }; /// INTERNAL ONLY /// template struct is_ref : mpl::false_ {}; /// INTERNAL ONLY /// template struct is_ref : mpl::true_ {}; /// \brief A metafunction that computes the return type of the \c as_expr() /// function. /// /// The as_expr\<\> metafunction turns types into Proto types, if /// they are not already, by making them Proto terminals held by value if /// possible. Types which are already Proto types are left alone. /// /// This specialization is selected when the type is not yet a Proto type. /// The resulting terminal type is calculated as follows: /// /// If \c T is an array type or a function type, let \c A be T &. /// Otherwise, let \c A be the type \c T stripped of cv-qualifiers. /// Then, the result type as_expr\::::type is /// Domain::apply\< expr\< tag::terminal, args0\ \> \>::::type. template< typename T , typename Domain BOOST_PROTO_FOR_DOXYGEN_ONLY(= default_domain) , typename Void BOOST_PROTO_FOR_DOXYGEN_ONLY(= void) > struct as_expr { typedef mpl::or_ > is_unstorable_; typedef typename mpl::eval_if, remove_cv >::type arg0_; typedef proto::expr > expr_; typedef typename Domain::template apply::type type; typedef type const reference; /// INTERNAL ONLY /// template static reference call(T2 &t) { return Domain::make(expr_::make(t)); } }; /// \brief A metafunction that computes the return type of the \c as_expr() /// function. /// /// The as_expr\<\> metafunction turns types into Proto types, if /// they are not already, by making them Proto terminals held by value if /// possible. Types which are already Proto types are left alone. /// /// This specialization is selected when the type is already a Proto type. /// The result type as_expr\::::type is \c T stripped /// of cv-qualifiers. template struct as_expr { typedef typename T::proto_derived_expr type; typedef T &reference; /// INTERNAL ONLY /// template static reference call(T2 &t) { return t; } }; /// \brief A metafunction that computes the return type of the \c as_arg() /// function. /// /// The as_arg\<\> metafunction turns types into Proto types, if /// they are not already, by making them Proto terminals held by reference. /// Types which are already Proto types are wrapped in proto::ref_\<\>. /// /// This specialization is selected when the type is not yet a Proto type. /// The result type as_arg\::::type is /// Domain::apply\< expr\< tag::terminal, args0\ \> \>::::type. template< typename T , typename Domain BOOST_PROTO_FOR_DOXYGEN_ONLY(= default_domain) , typename Void BOOST_PROTO_FOR_DOXYGEN_ONLY(= void) > struct as_arg { typedef proto::expr > expr_; typedef typename Domain::template apply::type type; /// INTERNAL ONLY /// template static type call(T2 &t) { return Domain::make(expr_::make(t)); } }; /// \brief A metafunction that computes the return type of the \c as_arg() /// function. /// /// The as_arg\<\> metafunction turns types into Proto types, if /// they are not already, by making them Proto terminals held by reference. /// Types which are already Proto types are wrapped in proto::ref_\<\>. /// /// This specialization is selected when the type is already a Proto type. /// The result type as_arg\::::type is /// proto::ref_\. template struct as_arg { typedef ref_ type; /// INTERNAL ONLY /// template static type call(T2 &t) { return type::make(t); } }; /// \brief A metafunction that returns the type of the Nth child /// of a Proto expression, where N is an MPL Integral Constant. /// /// result_of::arg\ is equivalent to /// result_of::arg_c\. template) > struct arg : arg_c {}; // TODO left<> and right<> force the instantiation of Expr. // Couldn't we partially specialize them on proto::expr< T, A > // and ref_< proto::expr< T, A > > and return A::arg0 / A::arg1? /// \brief A metafunction that returns the type of the left child /// of a binary Proto expression. /// /// result_of::left\ is equivalent to /// result_of::arg_c\. template struct left { typedef typename Expr::proto_arg0 wrapped_type; typedef typename unref::type type; typedef typename unref::reference reference; typedef typename unref::const_reference const_reference; }; /// \brief A metafunction that returns the type of the right child /// of a binary Proto expression. /// /// result_of::right\ is equivalent to /// result_of::arg_c\. template struct right { typedef typename Expr::proto_arg1 wrapped_type; typedef typename unref::type type; typedef typename unref::reference reference; typedef typename unref::const_reference const_reference; }; } // namespace result_of namespace op { /// \brief A metafunction for generating terminal expression types, /// a grammar element for matching terminal expressions, and a /// PrimitiveTransform that returns the current expression unchanged. template struct terminal { typedef proto::expr > type; typedef type proto_base_expr; template struct result; template struct result { typedef Expr type; }; /// \param expr The current expression /// \pre matches\ \>::::value is \c true. /// \return \c expr /// \throw nothrow template Expr const &operator ()(Expr const &expr, State const &, Visitor &) const { return expr; } /// INTERNAL ONLY typedef proto::tag::terminal proto_tag; /// INTERNAL ONLY typedef T proto_arg0; }; /// \brief A metafunction for generating ternary conditional expression types, /// a grammar element for matching ternary conditional expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct if_else_ { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::if_else_ proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; /// INTERNAL ONLY typedef V proto_arg2; }; /// \brief A metafunction for generating unary expression types with a /// specified tag type, /// a grammar element for matching unary expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. /// /// Use unary_expr\<_, _\> as a grammar element to match any /// unary expression. template struct unary_expr { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef Tag proto_tag; /// INTERNAL ONLY typedef T proto_arg0; }; /// \brief A metafunction for generating binary expression types with a /// specified tag type, /// a grammar element for matching binary expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. /// /// Use binary_expr\<_, _, _\> as a grammar element to match any /// binary expression. template struct binary_expr { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef Tag proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating unary plus expression types, /// a grammar element for matching unary plus expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct posit { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::posit proto_tag; /// INTERNAL ONLY typedef T proto_arg0; }; /// \brief A metafunction for generating unary minus expression types, /// a grammar element for matching unary minus expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct negate { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::negate proto_tag; /// INTERNAL ONLY typedef T proto_arg0; }; /// \brief A metafunction for generating defereference expression types, /// a grammar element for matching dereference expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct dereference { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::dereference proto_tag; /// INTERNAL ONLY typedef T proto_arg0; }; /// \brief A metafunction for generating complement expression types, /// a grammar element for matching complement expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct complement { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::complement proto_tag; /// INTERNAL ONLY typedef T proto_arg0; }; /// \brief A metafunction for generating address_of expression types, /// a grammar element for matching address_of expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct address_of { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::address_of proto_tag; /// INTERNAL ONLY typedef T proto_arg0; }; /// \brief A metafunction for generating logical_not expression types, /// a grammar element for matching logical_not expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct logical_not { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::logical_not proto_tag; /// INTERNAL ONLY typedef T proto_arg0; }; /// \brief A metafunction for generating pre-increment expression types, /// a grammar element for matching pre-increment expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct pre_inc { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::pre_inc proto_tag; /// INTERNAL ONLY typedef T proto_arg0; }; /// \brief A metafunction for generating pre-decrement expression types, /// a grammar element for matching pre-decrement expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct pre_dec { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::pre_dec proto_tag; /// INTERNAL ONLY typedef T proto_arg0; }; /// \brief A metafunction for generating post-increment expression types, /// a grammar element for matching post-increment expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct post_inc { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::post_inc proto_tag; /// INTERNAL ONLY typedef T proto_arg0; }; /// \brief A metafunction for generating post-decrement expression types, /// a grammar element for matching post-decrement expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct post_dec { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::post_dec proto_tag; /// INTERNAL ONLY typedef T proto_arg0; }; /// \brief A metafunction for generating left-shift expression types, /// a grammar element for matching left-shift expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct shift_left { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::shift_left proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating right-shift expression types, /// a grammar element for matching right-shift expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct shift_right { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::shift_right proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating multiplies expression types, /// a grammar element for matching multiplies expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct multiplies { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::multiplies proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating divides expression types, /// a grammar element for matching divides expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct divides { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::divides proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating modulus expression types, /// a grammar element for matching modulus expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct modulus { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::modulus proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating binary plus expression types, /// a grammar element for matching binary plus expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct plus { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::plus proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating binary minus expression types, /// a grammar element for matching binary minus expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct minus { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::minus proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating less expression types, /// a grammar element for matching less expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct less { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::less proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating greater expression types, /// a grammar element for matching greater expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct greater { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::greater proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating less-or-equal expression types, /// a grammar element for matching less-or-equal expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct less_equal { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::less_equal proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating greater-or-equal expression types, /// a grammar element for matching greater-or-equal expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct greater_equal { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::greater_equal proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating equal-to expression types, /// a grammar element for matching equal-to expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct equal_to { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::equal_to proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating not-equal-to expression types, /// a grammar element for matching not-equal-to expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct not_equal_to { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::not_equal_to proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating logical-or expression types, /// a grammar element for matching logical-or expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct logical_or { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::logical_or proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating logical-and expression types, /// a grammar element for matching logical-and expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct logical_and { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::logical_and proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating bitwise-and expression types, /// a grammar element for matching bitwise-and expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct bitwise_and { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::bitwise_and proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating bitwise-or expression types, /// a grammar element for matching bitwise-or expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct bitwise_or { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::bitwise_or proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating bitwise-xor expression types, /// a grammar element for matching bitwise-xor expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct bitwise_xor { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::bitwise_xor proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating comma expression types, /// a grammar element for matching comma expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct comma { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::comma proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; template struct mem_ptr { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::mem_ptr proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating assignment expression types, /// a grammar element for matching assignment expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct assign { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::assign proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating left-shift-assign expression types, /// a grammar element for matching left-shift-assign expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct shift_left_assign { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::shift_left_assign proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating right-shift-assign expression types, /// a grammar element for matching right-shift-assign expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct shift_right_assign { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::shift_right_assign proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating multiplies-assign expression types, /// a grammar element for matching multiplies-assign expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct multiplies_assign { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::multiplies_assign proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating divides-assign expression types, /// a grammar element for matching divides-assign expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct divides_assign { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::divides_assign proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating modulus-assign expression types, /// a grammar element for matching modulus-assign expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct modulus_assign { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::modulus_assign proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating plus-assign expression types, /// a grammar element for matching plus-assign expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct plus_assign { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::plus_assign proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating minus-assign expression types, /// a grammar element for matching minus-assign expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct minus_assign { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::minus_assign proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating bitwise-and-assign expression types, /// a grammar element for matching bitwise-and-assign expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct bitwise_and_assign { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::bitwise_and_assign proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating bitwise-or-assign expression types, /// a grammar element for matching bitwise-or-assign expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct bitwise_or_assign { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::bitwise_or_assign proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating bitwise-xor-assign expression types, /// a grammar element for matching bitwise-xor-assign expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct bitwise_xor_assign { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::bitwise_xor_assign proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; /// \brief A metafunction for generating subscript expression types, /// a grammar element for matching subscript expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct subscript { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\ \>::::value is \c true. /// \return pass_through\ \>()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::subscript proto_tag; /// INTERNAL ONLY typedef T proto_arg0; /// INTERNAL ONLY typedef U proto_arg1; }; } // namespace op #define BOOST_PROTO_ARG(z, n, data) \ /** INTERNAL ONLY */ \ typedef BOOST_PP_CAT(data, n) BOOST_PP_CAT(proto_arg, n); \ /**/ #define BOOST_PROTO_IMPLICIT_ARG(z, n, data) \ BOOST_PP_CAT(data, n) &BOOST_PP_CAT(a, n); \ /**/ #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PROTO_MAX_ARITY, )) #include BOOST_PP_ITERATE() #undef BOOST_PROTO_ARG #undef BOOST_PROTO_IMPLICIT_ARG namespace functional { /// \brief A callable PolymorphicFunctionObject that is /// equivalent to the \c as_expr() function. template struct as_expr { BOOST_PROTO_CALLABLE() template struct result; template struct result { typedef typename remove_reference::type unref_type; typedef typename result_of::as_expr::type type; }; /// \brief Wrap an object in a Proto terminal if it isn't a /// Proto expression already. /// \param t The object to wrap. /// \return proto::as_expr\(t) template typename result_of::as_expr::reference operator ()(T &t) const { return result_of::as_expr::call(t); } /// \overload /// template typename result_of::as_expr::reference operator ()(T const &t) const { return result_of::as_expr::call(t); } #if BOOST_WORKAROUND(BOOST_MSVC, == 1310) template typename result_of::as_expr::reference operator ()(T (&t)[N_]) const { return result_of::as_expr::call(t); } template typename result_of::as_expr::reference operator ()(T const (&t)[N_]) const { return result_of::as_expr::call(t); } #endif }; /// \brief A callable PolymorphicFunctionObject that is /// equivalent to the \c as_arg() function. template struct as_arg { BOOST_PROTO_CALLABLE() template struct result; template struct result { typedef typename remove_reference::type unref_type; typedef typename result_of::as_arg::type type; }; /// \brief Wrap an object in a Proto terminal if it isn't a /// Proto expression already. /// \param t The object to wrap. /// \return proto::as_arg\(t) template typename result_of::as_arg::type operator ()(T &t) const { return result_of::as_arg::call(t); } /// \overload /// template typename result_of::as_arg::type operator ()(T const &t) const { return result_of::as_arg::call(t); } }; /// \brief A callable PolymorphicFunctionObject that is /// equivalent to the \c arg_c() function. template struct arg_c { BOOST_PROTO_CALLABLE() template struct result; template struct result { typedef BOOST_PROTO_UNCVREF(Expr) uncvref_type; typedef typename result_of::arg_c::type type; }; /// \brief Return the Nth child of the given expression. /// \param expr The expression node. /// \pre is_expr\::::value is \c true /// \pre N == 0 || N \< Expr::proto_arity::value /// \return proto::arg_c\(expr) /// \throw nothrow template typename result_of::arg_c::reference operator ()(Expr &expr) const { return result_of::arg_c::call(expr); } /// \overload /// template typename result_of::arg_c::const_reference operator ()(Expr const &expr) const { return result_of::arg_c::call(expr); } }; /// \brief A callable PolymorphicFunctionObject that is /// equivalent to the \c arg() function. /// /// A callable PolymorphicFunctionObject that is /// equivalent to the \c arg() function. \c N is required /// to be an MPL Integral Constant. template) > struct arg { BOOST_PROTO_CALLABLE() template struct result; template struct result { typedef BOOST_PROTO_UNCVREF(Expr) uncvref_type; typedef typename result_of::arg::type type; }; /// \brief Return the Nth child of the given expression. /// \param expr The expression node. /// \pre is_expr\::::value is \c true /// \pre N::value == 0 || N::value \< Expr::proto_arity::value /// \return proto::arg\(expr) /// \throw nothrow template typename result_of::arg::reference operator ()(Expr &expr) const { return result_of::arg::call(expr); } /// \overload /// template typename result_of::arg::const_reference operator ()(Expr const &expr) const { return result_of::arg::call(expr); } }; /// \brief A callable PolymorphicFunctionObject that is /// equivalent to the \c left() function. struct left { BOOST_PROTO_CALLABLE() template struct result; template struct result { typedef BOOST_PROTO_UNCVREF(Expr) uncvref_type; typedef typename result_of::left::type type; }; /// \brief Return the left child of the given binary expression. /// \param expr The expression node. /// \pre is_expr\::::value is \c true /// \pre 2 == Expr::proto_arity::value /// \return proto::left(expr) /// \throw nothrow template typename result_of::left::reference operator ()(Expr &expr) const { return proto::unref(expr.proto_base().arg0); } /// \overload /// template typename result_of::left::const_reference operator ()(Expr const &expr) const { return proto::unref(expr.proto_base().arg0); } }; /// \brief A callable PolymorphicFunctionObject that is /// equivalent to the \c right() function. struct right { BOOST_PROTO_CALLABLE() template struct result; template struct result { typedef BOOST_PROTO_UNCVREF(Expr) uncvref_type; typedef typename result_of::right::type type; }; /// \brief Return the right child of the given binary expression. /// \param expr The expression node. /// \pre is_expr\::::value is \c true /// \pre 2 == Expr::proto_arity::value /// \return proto::right(expr) /// \throw nothrow template typename result_of::right::reference operator ()(Expr &expr) const { return proto::unref(expr.proto_base().arg1); } template typename result_of::right::const_reference operator ()(Expr const &expr) const { return proto::unref(expr.proto_base().arg1); } }; } /// \brief A function that wraps non-Proto expression types in Proto /// terminals and leaves Proto expression types alone. /// /// The as_expr() function turns objects into Proto terminals if /// they are not Proto expression types already. Non-Proto types are /// held by value, if possible. Types which are already Proto types are /// left alone and returned by reference. /// /// This function can be called either with an explicitly specified /// \c Domain parameter (i.e., as_expr\(t)), or /// without (i.e., as_expr(t)). If no domain is /// specified, \c default_domain is assumed. /// /// If is_expr\::::value is \c true, then the argument is /// returned unmodified, by reference. Otherwise, the argument is wrapped /// in a Proto terminal expression node according to the following rules. /// If \c T is an array type or a function type, let \c A be T &. /// Otherwise, let \c A be the type \c T stripped of cv-qualifiers. /// Then, \c as_expr() returns /// Domain::make(terminal\::::type::make(t)). /// /// \param t The object to wrap. template typename result_of::as_expr::reference as_expr(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T)) { return result_of::as_expr::call(t); } /// \overload /// template typename result_of::as_expr::reference as_expr(T const &t) { return result_of::as_expr::call(t); } /// \overload /// template typename result_of::as_expr::reference as_expr(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T)) { return result_of::as_expr::call(t); } /// \overload /// template typename result_of::as_expr::reference as_expr(T const &t) { return result_of::as_expr::call(t); } /// \brief A function that wraps non-Proto expression types in Proto /// terminals (by reference) and wraps Proto expression types in /// ref_\<\>. /// /// The as_arg() function turns objects into Proto terminals if /// they are not Proto expression types already. Non-Proto types are /// held by reference. Types which are already Proto types are wrapped /// in ref_\<\>. /// /// This function can be called either with an explicitly specified /// \c Domain parameter (i.e., as_arg\(t)), or /// without (i.e., as_arg(t)). If no domain is /// specified, \c default_domain is assumed. /// /// If is_expr\::::value is \c true, then the argument is /// wrapped in ref_\<\>, which holds the argument by reference. /// Otherwise, \c as_arg() returns /// Domain::make(terminal\::::type::make(t)). /// /// \param t The object to wrap. template typename result_of::as_arg::type as_arg(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T)) { return result_of::as_arg::call(t); } /// \overload /// template typename result_of::as_arg::type as_arg(T const &t) { return result_of::as_arg::call(t); } /// \overload /// template typename result_of::as_arg::type as_arg(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T)) { return result_of::as_arg::call(t); } /// \overload /// template typename result_of::as_arg::type as_arg(T const &t) { return result_of::as_arg::call(t); } /// \brief Return the Nth child of the specified Proto expression. /// /// Return the Nth child of the specified Proto expression. If /// \c N is not specified, as in \c arg(expr), then \c N is assumed /// to be mpl::long_\<0\>. The child is returned by /// reference. If the expression is holding the child in a /// ref_\<\> wrapper, it is unwrapped before it is returned. /// /// \param expr The Proto expression. /// \pre is_expr\::::value is \c true. /// \pre \c N is an MPL Integral Constant. /// \pre N::value == 0 || N::value \< Expr::proto_arity::value /// \throw nothrow /// \return A reference to the Nth child template typename result_of::arg::reference arg(Expr &expr BOOST_PROTO_DISABLE_IF_IS_CONST(Expr)) { return result_of::arg::call(expr); } /// \overload /// template typename result_of::arg::const_reference arg(Expr const &expr) { return result_of::arg::call(expr); } /// \overload /// template typename result_of::unref::reference arg(Expr2 &expr2 BOOST_PROTO_DISABLE_IF_IS_CONST(Expr2)) { return proto::unref(expr2.proto_base().arg0); } /// \overload /// template typename result_of::unref::const_reference arg(Expr2 const &expr2) { return proto::unref(expr2.proto_base().arg0); } /// \brief Return the Nth child of the specified Proto expression. /// /// Return the Nth child of the specified Proto expression. The child /// is returned by reference. If the expression is holding the child in /// a ref_\<\> wrapper, it is unwrapped before it is returned. /// /// \param expr The Proto expression. /// \pre is_expr\::::value is \c true. /// \pre N == 0 || N \< Expr::proto_arity::value /// \throw nothrow /// \return A reference to the Nth child template typename result_of::arg_c::reference arg_c(Expr &expr BOOST_PROTO_DISABLE_IF_IS_CONST(Expr)) { return result_of::arg_c::call(expr); } /// \overload /// template typename result_of::arg_c::const_reference arg_c(Expr const &expr) { return result_of::arg_c::call(expr); } /// \brief Return the left child of the specified binary Proto /// expression. /// /// Return the left child of the specified binary Proto expression. The /// child is returned by reference. If the expression is holding the /// child in a ref_\<\> wrapper, it is unwrapped before it is /// returned. /// /// \param expr The Proto expression. /// \pre is_expr\::::value is \c true. /// \pre 2 == Expr::proto_arity::value /// \throw nothrow /// \return A reference to the left child template typename result_of::left::reference left(Expr &expr BOOST_PROTO_DISABLE_IF_IS_CONST(Expr)) { return proto::unref(expr.proto_base().arg0); } /// \overload /// template typename result_of::left::const_reference left(Expr const &expr) { return proto::unref(expr.proto_base().arg0); } /// \brief Return the right child of the specified binary Proto /// expression. /// /// Return the right child of the specified binary Proto expression. The /// child is returned by reference. If the expression is holding the /// child in a ref_\<\> wrapper, it is unwrapped before it is /// returned. /// /// \param expr The Proto expression. /// \pre is_expr\::::value is \c true. /// \pre 2 == Expr::proto_arity::value /// \throw nothrow /// \return A reference to the right child template typename result_of::right::reference right(Expr &expr BOOST_PROTO_DISABLE_IF_IS_CONST(Expr)) { return proto::unref(expr.proto_base().arg1); } /// \overload /// template typename result_of::right::const_reference right(Expr const &expr) { return proto::unref(expr.proto_base().arg1); } /// INTERNAL ONLY /// template struct is_callable > : mpl::true_ {}; /// INTERNAL ONLY /// template struct is_callable > : mpl::true_ {}; /// INTERNAL ONLY /// template struct is_callable > : mpl::true_ {}; /// INTERNAL ONLY /// template struct is_callable > : mpl::true_ {}; }} #if BOOST_WORKAROUND( BOOST_MSVC, >= 1400 ) #pragma warning(pop) #endif #endif #else // PP_IS_ITERATING #define N BOOST_PP_ITERATION() #if N > 0 namespace op { /// \brief A metafunction for generating function-call expression types, /// a grammar element for matching function-call expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct function< BOOST_PP_ENUM_PARAMS(N, A) BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT), void > { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\::::value is \c true. /// \return pass_through\()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef proto::tag::function proto_tag; BOOST_PP_REPEAT(N, BOOST_PROTO_ARG, A) BOOST_PP_REPEAT_FROM_TO( N , BOOST_PROTO_MAX_ARITY , BOOST_PROTO_ARG , detail::if_vararg BOOST_PP_INTERCEPT ) }; /// \brief A metafunction for generating n-ary expression types with a /// specified tag type, /// a grammar element for matching n-ary expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. /// /// Use nary_expr\<_, vararg\<_\> \> as a grammar element to match any /// n-ary expression; that is, any non-terminal. template struct nary_expr< Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, A) BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT), void > { typedef proto::expr > type; typedef type proto_base_expr; template struct result { typedef typename pass_through::template result::type type; }; /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor /// \pre matches\::::value is \c true. /// \return pass_through\()(expr, state, visitor) template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { return pass_through()(expr, state, visitor); } /// INTERNAL ONLY typedef Tag proto_tag; BOOST_PP_REPEAT(N, BOOST_PROTO_ARG, A) BOOST_PP_REPEAT_FROM_TO( N , BOOST_PROTO_MAX_ARITY , BOOST_PROTO_ARG , detail::if_vararg BOOST_PP_INTERCEPT ) }; } // namespace op namespace detail { template struct BOOST_PP_CAT(implicit_expr_, N) { BOOST_PP_REPEAT(N, BOOST_PROTO_IMPLICIT_ARG, A) template operator proto::expr () const { proto::expr that = {BOOST_PP_ENUM_PARAMS(N, a)}; return that; } }; template< template class T , BOOST_PP_ENUM_PARAMS(N, typename A) > struct is_callable_ BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(N)> : is_same {}; } /// INTERNAL ONLY template detail::BOOST_PP_CAT(implicit_expr_, N) implicit_expr(BOOST_PP_ENUM_BINARY_PARAMS(N, A, &a)) { detail::BOOST_PP_CAT(implicit_expr_, N) that = {BOOST_PP_ENUM_PARAMS(N, a)}; return that; } #endif namespace result_of { /// \brief A metafunction that returns the type of the Nth child /// of a Proto expression. /// /// A metafunction that returns the type of the Nth child /// of a Proto expression. \c N must be 0 or less than /// \c Expr::proto_arity::value. template struct arg_c { /// The raw type of the Nth child as it is stored within /// \c Expr. This may be a value, a reference, or a Proto /// ref_\<\> wrapper. typedef typename Expr::BOOST_PP_CAT(proto_arg, N) wrapped_type; /// The "value" type of the child, suitable for return by value, /// computed as follows: /// \li ref_\ becomes T /// \li ref_\ becomes T /// \li T const(&)[N] becomes T const(&)[N] /// \li T(&)[N] becomes T(&)[N] /// \li R(&)(A0,...) becomes R(&)(A0,...) /// \li T const & becomes T /// \li T & becomes T /// \li T becomes T typedef typename unref::type type; /// The "reference" type of the child, suitable for return by /// reference, computed as follows: /// \li ref_\ becomes T const & /// \li ref_\ becomes T & /// \li T const(&)[N] becomes T const(&)[N] /// \li T(&)[N] becomes T(&)[N] /// \li R(&)(A0,...) becomes R(&)(A0,...) /// \li T const & becomes T const & /// \li T & becomes T & /// \li T becomes T & typedef typename unref::reference reference; /// The "const reference" type of the child, suitable for return by /// const reference, computed as follows: /// \li ref_\ becomes T const & /// \li ref_\ becomes T & /// \li T const(&)[N] becomes T const(&)[N] /// \li T(&)[N] becomes T(&)[N] /// \li R(&)(A0,...) becomes R(&)(A0,...) /// \li T const & becomes T const & /// \li T & becomes T & /// \li T becomes T const & typedef typename unref::const_reference const_reference; /// INTERNAL ONLY /// static reference call(typename Expr::proto_derived_expr &expr) { return proto::unref(expr.proto_base().BOOST_PP_CAT(arg, N)); } /// INTERNAL ONLY /// static const_reference call(typename Expr::proto_derived_expr const &expr) { return proto::unref(expr.proto_base().BOOST_PP_CAT(arg, N)); } }; } #undef N #endif