141 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			141 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								///////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								/// \file eval.hpp
							 | 
						||
| 
								 | 
							
								/// Contains the eval() expression evaluator.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//  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_EVAL_HPP_EAN_03_29_2007
							 | 
						||
| 
								 | 
							
								#define BOOST_PROTO_EVAL_HPP_EAN_03_29_2007
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <boost/proto/proto_fwd.hpp> // BOOST_PROTO_CALLABLE
							 | 
						||
| 
								 | 
							
								#include <boost/type_traits/remove_reference.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace boost { namespace proto
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    namespace result_of
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        /// \brief A metafunction for calculating the return type
							 | 
						||
| 
								 | 
							
								        /// of \c proto::eval() given a certain \c Expr and \c Context
							 | 
						||
| 
								 | 
							
								        /// types.
							 | 
						||
| 
								 | 
							
								        ///
							 | 
						||
| 
								 | 
							
								        /// \note The types \c Expr and \c Context should not be
							 | 
						||
| 
								 | 
							
								        /// reference types. They may be cv-qualified, but the
							 | 
						||
| 
								 | 
							
								        /// cv-qualification on the \c Context parameter is ignored.
							 | 
						||
| 
								 | 
							
								        template<typename Expr, typename Context>
							 | 
						||
| 
								 | 
							
								        struct eval
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            typedef typename Context::template eval<Expr>::result_type type;
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    namespace functional
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        /// \brief A PolymorphicFunctionObject type for
							 | 
						||
| 
								 | 
							
								        /// evaluating a given Proto expression with a given
							 | 
						||
| 
								 | 
							
								        /// context.
							 | 
						||
| 
								 | 
							
								        struct eval
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            BOOST_PROTO_CALLABLE()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            template<typename Sig>
							 | 
						||
| 
								 | 
							
								            struct result;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            template<typename This, typename Expr, typename Context>
							 | 
						||
| 
								 | 
							
								            struct result<This(Expr, Context)>
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                typedef
							 | 
						||
| 
								 | 
							
								                    typename proto::result_of::eval<
							 | 
						||
| 
								 | 
							
								                        typename remove_reference<Expr>::type
							 | 
						||
| 
								 | 
							
								                      , typename remove_reference<Context>::type
							 | 
						||
| 
								 | 
							
								                    >::type
							 | 
						||
| 
								 | 
							
								                type;
							 | 
						||
| 
								 | 
							
								            };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            /// \brief Evaluate a given Proto expression with a given
							 | 
						||
| 
								 | 
							
								            /// context.
							 | 
						||
| 
								 | 
							
								            /// \param expr The Proto expression to evaluate
							 | 
						||
| 
								 | 
							
								            /// \param context The context in which the expression should be
							 | 
						||
| 
								 | 
							
								            ///     evaluated.
							 | 
						||
| 
								 | 
							
								            /// \return <tt>typename Context::template eval<Expr>()(expr, context)</tt>
							 | 
						||
| 
								 | 
							
								            template<typename Expr, typename Context>
							 | 
						||
| 
								 | 
							
								            typename proto::result_of::eval<Expr, Context>::type
							 | 
						||
| 
								 | 
							
								            operator ()(Expr &e, Context &ctx) const
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                return typename Context::template eval<Expr>()(e, ctx);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            /// \overload
							 | 
						||
| 
								 | 
							
								            ///
							 | 
						||
| 
								 | 
							
								            template<typename Expr, typename Context>
							 | 
						||
| 
								 | 
							
								            typename proto::result_of::eval<Expr, Context>::type
							 | 
						||
| 
								 | 
							
								            operator ()(Expr &e, Context const &ctx) const
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                return typename Context::template eval<Expr>()(e, ctx);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            /// \overload
							 | 
						||
| 
								 | 
							
								            ///
							 | 
						||
| 
								 | 
							
								            template<typename Expr, typename Context>
							 | 
						||
| 
								 | 
							
								            typename proto::result_of::eval<Expr const, Context>::type
							 | 
						||
| 
								 | 
							
								            operator ()(Expr const &e, Context &ctx) const
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                return typename Context::template eval<Expr const>()(e, ctx);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            /// \overload
							 | 
						||
| 
								 | 
							
								            ///
							 | 
						||
| 
								 | 
							
								            template<typename Expr, typename Context>
							 | 
						||
| 
								 | 
							
								            typename proto::result_of::eval<Expr const, Context>::type
							 | 
						||
| 
								 | 
							
								            operator ()(Expr const &e, Context const &ctx) const
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                return typename Context::template eval<Expr const>()(e, ctx);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// \brief Evaluate a given Proto expression with a given
							 | 
						||
| 
								 | 
							
								    /// context.
							 | 
						||
| 
								 | 
							
								    /// \param expr The Proto expression to evaluate
							 | 
						||
| 
								 | 
							
								    /// \param context The context in which the expression should be
							 | 
						||
| 
								 | 
							
								    ///     evaluated.
							 | 
						||
| 
								 | 
							
								    /// \return <tt>typename Context::template eval<Expr>()(expr, context)</tt>
							 | 
						||
| 
								 | 
							
								    template<typename Expr, typename Context>
							 | 
						||
| 
								 | 
							
								    typename proto::result_of::eval<Expr, Context>::type
							 | 
						||
| 
								 | 
							
								    eval(Expr &e, Context &ctx)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return typename Context::template eval<Expr>()(e, ctx);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// \overload
							 | 
						||
| 
								 | 
							
								    ///
							 | 
						||
| 
								 | 
							
								    template<typename Expr, typename Context>
							 | 
						||
| 
								 | 
							
								    typename proto::result_of::eval<Expr, Context>::type
							 | 
						||
| 
								 | 
							
								    eval(Expr &e, Context const &ctx)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return typename Context::template eval<Expr>()(e, ctx);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// \overload
							 | 
						||
| 
								 | 
							
								    ///
							 | 
						||
| 
								 | 
							
								    template<typename Expr, typename Context>
							 | 
						||
| 
								 | 
							
								    typename proto::result_of::eval<Expr const, Context>::type
							 | 
						||
| 
								 | 
							
								    eval(Expr const &e, Context &ctx)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return typename Context::template eval<Expr const>()(e, ctx);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// \overload
							 | 
						||
| 
								 | 
							
								    ///
							 | 
						||
| 
								 | 
							
								    template<typename Expr, typename Context>
							 | 
						||
| 
								 | 
							
								    typename proto::result_of::eval<Expr const, Context>::type
							 | 
						||
| 
								 | 
							
								    eval(Expr const &e, Context const &ctx)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return typename Context::template eval<Expr const>()(e, ctx);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 |