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