Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:07:34

0001 ///////////////////////////////////////////////////////////////////////////////
0002 /// \file arg.hpp
0003 /// Contains definition of the argN transforms.
0004 //
0005 //  Copyright 2008 Eric Niebler. Distributed under the Boost
0006 //  Software License, Version 1.0. (See accompanying file
0007 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0008 
0009 #ifndef BOOST_PROTO_TRANSFORM_ARG_HPP_EAN_11_01_2007
0010 #define BOOST_PROTO_TRANSFORM_ARG_HPP_EAN_11_01_2007
0011 
0012 #include <boost/mpl/if.hpp>
0013 #include <boost/proto/proto_fwd.hpp>
0014 #include <boost/proto/traits.hpp>
0015 #include <boost/proto/transform/impl.hpp>
0016 #include <boost/type_traits/is_array.hpp>
0017 #include <boost/proto/transform/env.hpp>
0018 
0019 namespace boost { namespace proto
0020 {
0021 
0022     /// \brief A PrimitiveTransform that returns the current expression
0023     /// unmodified
0024     ///
0025     /// Example:
0026     ///
0027     /// \code
0028     /// proto::terminal<int>::type i = {42};
0029     /// proto::terminal<int>::type & j = proto::_expr()(i);
0030     /// assert( boost::addressof(i) == boost::addressof(j) );
0031     /// \endcode
0032     struct _expr : transform<_expr>
0033     {
0034         template<typename Expr, typename State, typename Data>
0035         struct impl : transform_impl<Expr, State, Data>
0036         {
0037             typedef Expr result_type;
0038 
0039             /// Returns the current expression.
0040             /// \param e The current expression.
0041             /// \return \c e
0042             /// \throw nothrow
0043             BOOST_PROTO_RETURN_TYPE_STRICT_LOOSE(result_type, typename impl::expr_param)
0044             operator()(
0045                 typename impl::expr_param e
0046               , typename impl::state_param
0047               , typename impl::data_param
0048             ) const
0049             {
0050                 return e;
0051             }
0052         };
0053     };
0054 
0055     /// \brief A PrimitiveTransform that returns the current state
0056     /// unmodified
0057     ///
0058     /// Example:
0059     ///
0060     /// \code
0061     /// proto::terminal<int>::type i = {42};
0062     /// char ch = proto::_state()(i, 'a');
0063     /// assert( ch == 'a' );
0064     /// \endcode
0065     struct _state : transform<_state>
0066     {
0067         template<typename Expr, typename State, typename Data>
0068         struct impl : transform_impl<Expr, State, Data>
0069         {
0070             typedef State result_type;
0071 
0072             /// Returns the current state.
0073             /// \param s The current state.
0074             /// \return \c s
0075             /// \throw nothrow
0076             BOOST_PROTO_RETURN_TYPE_STRICT_LOOSE(result_type, typename impl::state_param)
0077             operator ()(
0078                 typename impl::expr_param
0079               , typename impl::state_param s
0080               , typename impl::data_param
0081             ) const
0082             {
0083                 return s;
0084             }
0085         };
0086     };
0087 
0088     /// \brief A PrimitiveTransform that returns the current data
0089     /// unmodified
0090     ///
0091     /// Example:
0092     ///
0093     /// \code
0094     /// proto::terminal<int>::type i = {42};
0095     /// std::string str("hello");
0096     /// std::string & data = proto::_data()(i, 'a', str);
0097     /// assert( &str == &data );
0098     /// \endcode
0099     struct _data : transform<_data>
0100     {
0101         template<typename Expr, typename State, typename Data>
0102         struct impl
0103           : mpl::if_c<
0104                 is_env<Data>::value
0105               , _env_var<data_type>
0106               , _env
0107             >::type::template impl<Expr, State, Data>
0108         {};
0109     };
0110 
0111     /// \brief A PrimitiveTransform that returns N-th child of the current
0112     /// expression.
0113     ///
0114     /// Example:
0115     ///
0116     /// \code
0117     /// proto::terminal<int>::type i = {42};
0118     /// proto::terminal<int>::type & j = proto::_child_c<0>()(-i);
0119     /// assert( boost::addressof(i) == boost::addressof(j) );
0120     /// \endcode
0121     template<int N>
0122     struct _child_c : transform<_child_c<N> >
0123     {
0124         template<typename Expr, typename State, typename Data>
0125         struct impl : transform_impl<Expr, State, Data>
0126         {
0127             typedef
0128                 typename result_of::child_c<Expr, N>::type
0129             result_type;
0130 
0131             /// Returns the N-th child of \c e
0132             /// \pre <tt>arity_of\<Expr\>::value \> N</tt> 
0133             /// \param e The current expression.
0134             /// \return <tt>proto::child_c\<N\>(e)</tt>
0135             /// \throw nothrow
0136             #ifdef BOOST_PROTO_STRICT_RESULT_OF
0137             result_type
0138             #else
0139             typename result_of::child_c<typename impl::expr_param, N>::type
0140             #endif
0141             operator ()(
0142                 typename impl::expr_param e
0143               , typename impl::state_param
0144               , typename impl::data_param
0145             ) const
0146             {
0147                 return proto::child_c<N>(e);
0148             }
0149         };
0150     };
0151 
0152     /// \brief A PrimitiveTransform that returns the value of the
0153     /// current terminal expression.
0154     ///
0155     /// Example:
0156     ///
0157     /// \code
0158     /// proto::terminal<int>::type i = {42};
0159     /// int j = proto::_value()(i);
0160     /// assert( 42 == j );
0161     /// \endcode
0162     struct _value : transform<_value>
0163     {
0164         template<typename Expr, typename State, typename Data>
0165         struct impl : transform_impl<Expr, State, Data>
0166         {
0167             typedef
0168                 typename result_of::value<Expr>::type
0169             result_type;
0170 
0171             /// Returns the value of the specified terminal expression.
0172             /// \pre <tt>arity_of\<Expr\>::value == 0</tt>.
0173             /// \param e The current expression.
0174             /// \return <tt>proto::value(e)</tt>
0175             /// \throw nothrow
0176             #ifdef BOOST_PROTO_STRICT_RESULT_OF
0177             typename mpl::if_c<is_array<result_type>::value, result_type &, result_type>::type
0178             #else
0179             typename result_of::value<typename impl::expr_param>::type
0180             #endif
0181             operator ()(
0182                 typename impl::expr_param e
0183               , typename impl::state_param
0184               , typename impl::data_param
0185             ) const
0186             {
0187                 return proto::value(e);
0188             }
0189         };
0190     };
0191 
0192     /// \brief A PrimitiveTransform that does nothing
0193     /// and returns void.
0194     struct _void : transform<_void>
0195     {
0196         template<typename Expr, typename State, typename Data>
0197         struct impl : transform_impl<Expr, State, Data>
0198         {
0199             typedef void result_type;
0200 
0201             /// Does nothing and returns void
0202             void operator ()(
0203                 typename impl::expr_param
0204               , typename impl::state_param
0205               , typename impl::data_param
0206             ) const
0207             {}
0208         };
0209     };
0210 
0211     /// \brief A unary CallableTransform that wraps its argument
0212     /// in a \c boost::reference_wrapper\<\>.
0213     ///
0214     /// Example:
0215     ///
0216     /// \code
0217     /// proto::terminal<int>::type i = {42};
0218     /// boost::reference_wrapper<proto::terminal<int>::type> j
0219     ///     = proto::when<_, proto::_byref(_)>()(i);
0220     /// assert( boost::addressof(i) == boost::addressof(j.get()) );
0221     /// \endcode
0222     struct _byref : callable
0223     {
0224         template<typename Sig>
0225         struct result;
0226 
0227         template<typename This, typename T>
0228         struct result<This(T)>
0229         {
0230             typedef boost::reference_wrapper<T const> const type;
0231         };
0232 
0233         template<typename This, typename T>
0234         struct result<This(T &)>
0235         {
0236             typedef boost::reference_wrapper<T> const type;
0237         };
0238 
0239         /// Wrap the parameter \c t in a \c boost::reference_wrapper\<\>
0240         /// \param t The object to wrap
0241         /// \return <tt>boost::ref(t)</tt>
0242         /// \throw nothrow
0243         template<typename T>
0244         boost::reference_wrapper<T> const operator ()(T &t) const
0245         {
0246             return boost::reference_wrapper<T>(t);
0247         }
0248 
0249         /// \overload
0250         ///
0251         template<typename T>
0252         boost::reference_wrapper<T const> const operator ()(T const &t) const
0253         {
0254             return boost::reference_wrapper<T const>(t);
0255         }
0256     };
0257 
0258     /// \brief A unary CallableTransform that strips references
0259     /// and \c boost::reference_wrapper\<\> from its argument.
0260     ///
0261     /// Example:
0262     ///
0263     /// \code
0264     /// proto::terminal<int>::type i = {42};
0265     /// int j = 67;
0266     /// int k = proto::when<_, proto::_byval(proto::_state)>()(i, boost::ref(j));
0267     /// assert( 67 == k );
0268     /// \endcode
0269     struct _byval : callable
0270     {
0271         template<typename Sig>
0272         struct result;
0273 
0274         template<typename This, typename T>
0275         struct result<This(T)>
0276         {
0277             typedef T type;
0278         };
0279 
0280         template<typename This, typename T>
0281         struct result<This(T &)>
0282           : result<This(T)>
0283         {};
0284 
0285         template<typename This, typename T>
0286         struct result<This(boost::reference_wrapper<T>)>
0287           : result<This(T)>
0288         {};
0289 
0290         /// \param t The object to unref
0291         /// \return <tt>t</tt>
0292         /// \throw nothrow
0293         template<typename T>
0294         T operator ()(T const &t) const
0295         {
0296             return t;
0297         }
0298 
0299         /// \overload
0300         ///
0301         template<typename T>
0302         T operator ()(boost::reference_wrapper<T> const &t) const
0303         {
0304             return t;
0305         }
0306     };
0307 
0308     /// INTERNAL ONLY
0309     ///
0310     template<>
0311     struct is_callable<_expr>
0312       : mpl::true_
0313     {};
0314 
0315     /// INTERNAL ONLY
0316     ///
0317     template<>
0318     struct is_callable<_state>
0319       : mpl::true_
0320     {};
0321 
0322     /// INTERNAL ONLY
0323     ///
0324     template<>
0325     struct is_callable<_data>
0326       : mpl::true_
0327     {};
0328 
0329     /// INTERNAL ONLY
0330     ///
0331     template<int N>
0332     struct is_callable<_child_c<N> >
0333       : mpl::true_
0334     {};
0335 
0336     /// INTERNAL ONLY
0337     ///
0338     template<>
0339     struct is_callable<_value>
0340       : mpl::true_
0341     {};
0342 
0343     /// INTERNAL ONLY
0344     ///
0345     template<>
0346     struct is_callable<_byref>
0347       : mpl::true_
0348     {};
0349 
0350     /// INTERNAL ONLY
0351     ///
0352     template<>
0353     struct is_callable<_byval>
0354       : mpl::true_
0355     {};
0356 
0357 }}
0358 
0359 #endif