/////////////////////////////////////////////////////////////////////////////// | |
/// \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 |