/////////////////////////////////////////////////////////////////////////////// /// \file arg.hpp /// Contains definition of the argN 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_ARG_HPP_EAN_11_01_2007 #define BOOST_PROTO_TRANSFORM_ARG_HPP_EAN_11_01_2007 #include #include #include #include #include #include namespace boost { namespace proto { /// \brief A PrimitiveTransform that returns the current expression /// unmodified /// /// Example: /// /// \code /// proto::terminal::type i = {42}; /// proto::terminal::type & j = proto::_expr()(i); /// assert( boost::addressof(i) == boost::addressof(j) ); /// \endcode struct _expr : transform<_expr> { template struct impl : transform_impl { typedef Expr result_type; /// Returns the current expression. /// \param e The current expression. /// \return \c e /// \throw nothrow BOOST_PROTO_RETURN_TYPE_STRICT_LOOSE(result_type, typename impl::expr_param) operator()( typename impl::expr_param e , typename impl::state_param , typename impl::data_param ) const { return e; } }; }; /// \brief A PrimitiveTransform that returns the current state /// unmodified /// /// Example: /// /// \code /// proto::terminal::type i = {42}; /// char ch = proto::_state()(i, 'a'); /// assert( ch == 'a' ); /// \endcode struct _state : transform<_state> { template struct impl : transform_impl { typedef State result_type; /// Returns the current state. /// \param s The current state. /// \return \c s /// \throw nothrow BOOST_PROTO_RETURN_TYPE_STRICT_LOOSE(result_type, typename impl::state_param) operator ()( typename impl::expr_param , typename impl::state_param s , typename impl::data_param ) const { return s; } }; }; /// \brief A PrimitiveTransform that returns the current data /// unmodified /// /// Example: /// /// \code /// proto::terminal::type i = {42}; /// std::string str("hello"); /// std::string & data = proto::_data()(i, 'a', str); /// assert( &str == &data ); /// \endcode struct _data : transform<_data> { template struct impl : mpl::if_c< is_env::value , _env_var , _env >::type::template impl {}; }; /// \brief A PrimitiveTransform that returns N-th child of the current /// expression. /// /// Example: /// /// \code /// proto::terminal::type i = {42}; /// proto::terminal::type & j = proto::_child_c<0>()(-i); /// assert( boost::addressof(i) == boost::addressof(j) ); /// \endcode template struct _child_c : transform<_child_c > { template struct impl : transform_impl { typedef typename result_of::child_c::type result_type; /// Returns the N-th child of \c e /// \pre arity_of\::value \> N /// \param e The current expression. /// \return proto::child_c\(e) /// \throw nothrow #ifdef BOOST_PROTO_STRICT_RESULT_OF result_type #else typename result_of::child_c::type #endif operator ()( typename impl::expr_param e , typename impl::state_param , typename impl::data_param ) const { return proto::child_c(e); } }; }; /// \brief A PrimitiveTransform that returns the value of the /// current terminal expression. /// /// Example: /// /// \code /// proto::terminal::type i = {42}; /// int j = proto::_value()(i); /// assert( 42 == j ); /// \endcode struct _value : transform<_value> { template struct impl : transform_impl { typedef typename result_of::value::type result_type; /// Returns the value of the specified terminal expression. /// \pre arity_of\::value == 0. /// \param e The current expression. /// \return proto::value(e) /// \throw nothrow #ifdef BOOST_PROTO_STRICT_RESULT_OF typename mpl::if_c::value, result_type &, result_type>::type #else typename result_of::value::type #endif operator ()( typename impl::expr_param e , typename impl::state_param , typename impl::data_param ) const { return proto::value(e); } }; }; /// \brief A PrimitiveTransform that does nothing /// and returns void. struct _void : transform<_void> { template struct impl : transform_impl { typedef void result_type; /// Does nothing and returns void void operator ()( typename impl::expr_param , typename impl::state_param , typename impl::data_param ) const {} }; }; /// \brief A unary CallableTransform that wraps its argument /// in a \c boost::reference_wrapper\<\>. /// /// Example: /// /// \code /// proto::terminal::type i = {42}; /// boost::reference_wrapper::type> j /// = proto::when<_, proto::_byref(_)>()(i); /// assert( boost::addressof(i) == boost::addressof(j.get()) ); /// \endcode struct _byref : callable { template struct result; template struct result { typedef boost::reference_wrapper const type; }; template struct result { typedef boost::reference_wrapper const type; }; /// Wrap the parameter \c t in a \c boost::reference_wrapper\<\> /// \param t The object to wrap /// \return boost::ref(t) /// \throw nothrow template boost::reference_wrapper const operator ()(T &t) const { return boost::reference_wrapper(t); } /// \overload /// template boost::reference_wrapper const operator ()(T const &t) const { return boost::reference_wrapper(t); } }; /// \brief A unary CallableTransform that strips references /// and \c boost::reference_wrapper\<\> from its argument. /// /// Example: /// /// \code /// proto::terminal::type i = {42}; /// int j = 67; /// int k = proto::when<_, proto::_byval(proto::_state)>()(i, boost::ref(j)); /// assert( 67 == k ); /// \endcode struct _byval : callable { template struct result; template struct result { typedef T type; }; template struct result : result {}; template struct result)> : result {}; /// \param t The object to unref /// \return t /// \throw nothrow template T operator ()(T const &t) const { return t; } /// \overload /// template T operator ()(boost::reference_wrapper const &t) const { return t; } }; /// INTERNAL ONLY /// template<> struct is_callable<_expr> : mpl::true_ {}; /// INTERNAL ONLY /// template<> struct is_callable<_state> : mpl::true_ {}; /// INTERNAL ONLY /// template<> struct is_callable<_data> : mpl::true_ {}; /// INTERNAL ONLY /// template struct is_callable<_child_c > : mpl::true_ {}; /// INTERNAL ONLY /// template<> struct is_callable<_value> : mpl::true_ {}; /// INTERNAL ONLY /// template<> struct is_callable<_byref> : mpl::true_ {}; /// INTERNAL ONLY /// template<> struct is_callable<_byval> : mpl::true_ {}; }} #endif