| /////////////////////////////////////////////////////////////////////////////// |
| /// \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 <boost/proto/proto_fwd.hpp> |
| #include <boost/proto/traits.hpp> |
| #include <boost/proto/transform/impl.hpp> |
| #include <boost/type_traits/is_array.hpp> |
| |
| namespace boost { namespace proto |
| { |
| |
| /// \brief A PrimitiveTransform that returns the current expression |
| /// unmodified |
| /// |
| /// Example: |
| /// |
| /// \code |
| /// proto::terminal<int>::type i = {42}; |
| /// proto::terminal<int>::type & j = proto::_expr()(i); |
| /// assert( boost::addressof(i) == boost::addressof(j) ); |
| /// \endcode |
| struct _expr : transform<_expr> |
| { |
| template<typename Expr, typename State, typename Data> |
| struct impl : transform_impl<Expr, State, Data> |
| { |
| typedef Expr result_type; |
| |
| /// Returns the current expression. |
| /// \param e The current expression. |
| /// \return \c e |
| /// \throw nothrow |
| #ifdef BOOST_PROTO_STRICT_RESULT_OF |
| result_type |
| #else |
| typename impl::expr_param |
| #endif |
| 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<int>::type i = {42}; |
| /// char ch = proto::_state()(i, 'a'); |
| /// assert( ch == 'a' ); |
| /// \endcode |
| struct _state : transform<_state> |
| { |
| template<typename Expr, typename State, typename Data> |
| struct impl : transform_impl<Expr, State, Data> |
| { |
| typedef State result_type; |
| |
| /// Returns the current state. |
| /// \param s The current state. |
| /// \return \c s |
| /// \throw nothrow |
| #ifdef BOOST_PROTO_STRICT_RESULT_OF |
| result_type |
| #else |
| typename impl::state_param |
| #endif |
| 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<int>::type i = {42}; |
| /// std::string str("hello"); |
| /// std::string & data = proto::_data()(i, 'a', str); |
| /// assert( &str == &data ); |
| /// \endcode |
| struct _data : transform<_data> |
| { |
| template<typename Expr, typename State, typename Data> |
| struct impl : transform_impl<Expr, State, Data> |
| { |
| typedef Data result_type; |
| |
| /// Returns the current data. |
| /// \param d The current data. |
| /// \return \c d |
| /// \throw nothrow |
| #ifdef BOOST_PROTO_STRICT_RESULT_OF |
| result_type |
| #else |
| typename impl::data_param |
| #endif |
| operator ()( |
| typename impl::expr_param |
| , typename impl::state_param |
| , typename impl::data_param d |
| ) const |
| { |
| return d; |
| } |
| }; |
| }; |
| |
| /// \brief A PrimitiveTransform that returns N-th child of the current |
| /// expression. |
| /// |
| /// Example: |
| /// |
| /// \code |
| /// proto::terminal<int>::type i = {42}; |
| /// proto::terminal<int>::type & j = proto::_child_c<0>()(-i); |
| /// assert( boost::addressof(i) == boost::addressof(j) ); |
| /// \endcode |
| template<int N> |
| struct _child_c : transform<_child_c<N> > |
| { |
| template<typename Expr, typename State, typename Data> |
| struct impl : transform_impl<Expr, State, Data> |
| { |
| typedef |
| typename result_of::child_c<Expr, N>::type |
| result_type; |
| |
| /// Returns the N-th child of \c e |
| /// \pre <tt>arity_of\<Expr\>::value \> N</tt> |
| /// \param e The current expression. |
| /// \return <tt>proto::child_c\<N\>(e)</tt> |
| /// \throw nothrow |
| #ifdef BOOST_PROTO_STRICT_RESULT_OF |
| result_type |
| #else |
| typename result_of::child_c<typename impl::expr_param, N>::type |
| #endif |
| operator ()( |
| typename impl::expr_param e |
| , typename impl::state_param |
| , typename impl::data_param |
| ) const |
| { |
| return proto::child_c<N>(e); |
| } |
| }; |
| }; |
| |
| /// \brief A PrimitiveTransform that returns the value of the |
| /// current terminal expression. |
| /// |
| /// Example: |
| /// |
| /// \code |
| /// proto::terminal<int>::type i = {42}; |
| /// int j = proto::_value()(i); |
| /// assert( 42 == j ); |
| /// \endcode |
| struct _value : transform<_value> |
| { |
| template<typename Expr, typename State, typename Data> |
| struct impl : transform_impl<Expr, State, Data> |
| { |
| typedef |
| typename result_of::value<Expr>::type |
| result_type; |
| |
| /// Returns the value of the specified terminal expression. |
| /// \pre <tt>arity_of\<Expr\>::value == 0</tt>. |
| /// \param e The current expression. |
| /// \return <tt>proto::value(e)</tt> |
| /// \throw nothrow |
| #ifdef BOOST_PROTO_STRICT_RESULT_OF |
| typename mpl::if_c<is_array<result_type>::value, result_type &, result_type>::type |
| #else |
| typename result_of::value<typename impl::expr_param>::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<typename Expr, typename State, typename Data> |
| struct impl : transform_impl<Expr, State, Data> |
| { |
| 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<int>::type i = {42}; |
| /// boost::reference_wrapper<proto::terminal<int>::type> j |
| /// = proto::when<_, proto::_byref(_)>()(i); |
| /// assert( boost::addressof(i) == boost::addressof(j.get()) ); |
| /// \endcode |
| struct _byref : callable |
| { |
| template<typename Sig> |
| struct result; |
| |
| template<typename This, typename T> |
| struct result<This(T)> |
| { |
| typedef boost::reference_wrapper<T const> const type; |
| }; |
| |
| template<typename This, typename T> |
| struct result<This(T &)> |
| { |
| typedef boost::reference_wrapper<T> const type; |
| }; |
| |
| /// Wrap the parameter \c t in a \c boost::reference_wrapper\<\> |
| /// \param t The object to wrap |
| /// \return <tt>boost::ref(t)</tt> |
| /// \throw nothrow |
| template<typename T> |
| boost::reference_wrapper<T> const operator ()(T &t) const |
| { |
| return boost::reference_wrapper<T>(t); |
| } |
| |
| /// \overload |
| /// |
| template<typename T> |
| boost::reference_wrapper<T const> const operator ()(T const &t) const |
| { |
| return boost::reference_wrapper<T const>(t); |
| } |
| }; |
| |
| /// \brief A unary CallableTransform that strips references |
| /// and \c boost::reference_wrapper\<\> from its argument. |
| /// |
| /// Example: |
| /// |
| /// \code |
| /// proto::terminal<int>::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<typename Sig> |
| struct result; |
| |
| template<typename This, typename T> |
| struct result<This(T)> |
| { |
| typedef T type; |
| }; |
| |
| template<typename This, typename T> |
| struct result<This(T &)> |
| : result<This(T)> |
| {}; |
| |
| template<typename This, typename T> |
| struct result<This(boost::reference_wrapper<T>)> |
| : result<This(T)> |
| {}; |
| |
| /// \param t The object to unref |
| /// \return <tt>t</tt> |
| /// \throw nothrow |
| template<typename T> |
| T operator ()(T const &t) const |
| { |
| return t; |
| } |
| |
| /// \overload |
| /// |
| template<typename T> |
| T operator ()(boost::reference_wrapper<T> 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<int N> |
| struct is_callable<_child_c<N> > |
| : 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 |