blob: a5e88f1dc388dbee86b053537df1d10a2ebb68a2 [file] [log] [blame]
/*=============================================================================
Copyright (c) 2001-2007 Joel de Guzman
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 PHOENIX_CORE_ACTOR_HPP
#define PHOENIX_CORE_ACTOR_HPP
#include <boost/spirit/home/phoenix/core/limits.hpp>
#if !defined(BOOST_RESULT_OF_NUM_ARGS)
# define BOOST_RESULT_OF_NUM_ARGS PHOENIX_ACTOR_LIMIT
#elif (BOOST_RESULT_OF_NUM_ARGS < PHOENIX_ACTOR_LIMIT)
# error "BOOST_RESULT_OF_NUM_ARGS < PHOENIX_ACTOR_LIMIT"
#endif
#include <boost/spirit/home/phoenix/core/basic_environment.hpp>
#include <boost/mpl/min.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/utility/result_of.hpp>
namespace boost { namespace phoenix
{
// phoenix::void_ is the same as fusion::void_
typedef fusion::void_ void_;
namespace detail
{
// Forward declarations. These will come in when we get to the
// operator module, yet, the actor's assignment operator and index
// operator are required to be members.
template <typename T0, typename T1>
struct make_assign_composite;
template <typename T0, typename T1>
struct make_index_composite;
template <typename BaseT0, typename BaseT1>
struct comma_result;
// error no arguments supplied
struct error_expecting_arguments
{
template <typename T>
error_expecting_arguments(T const&) {}
};
}
template <typename Eval, typename Env>
struct eval_result
{
typedef typename Eval::template result<Env>::type type;
};
template <typename Eval>
struct actor : Eval
{
typedef actor<Eval> self_type;
typedef Eval eval_type;
template <class Sig> struct result {};
actor()
: Eval() {}
actor(Eval const& base)
: Eval(base) {}
template <typename T0>
explicit actor(T0 const& _0)
: Eval(_0) {}
template <typename T0, typename T1>
actor(T0 const& _0, T1 const& _1)
: Eval(_0, _1) {}
typedef typename
mpl::eval_if<
typename Eval::no_nullary // avoid calling eval_result when this is true
, mpl::identity<detail::error_expecting_arguments>
, eval_result<eval_type, basic_environment<> >
>::type
nullary_result;
nullary_result
operator()() const
{
return eval_type::eval(basic_environment<>());
}
template <class F, class A0>
struct result<F(A0)>
: eval_result<
eval_type
, basic_environment<
typename remove_reference<A0>::type
>
>
{};
template <typename T0>
typename result<actor(T0&)>::type
operator()(T0& _0) const
{
return eval_type::eval(basic_environment<T0>(_0));
}
template <class F, class A0, class A1>
struct result<F(A0,A1)>
: eval_result<
eval_type
, basic_environment<
typename remove_reference<A0>::type
, typename remove_reference<A1>::type
>
>
{};
template <typename T0, typename T1>
typename result<actor(T0&,T1&)>::type
operator()(T0& _0, T1& _1) const
{
return eval_type::eval(basic_environment<T0, T1>(_0, _1));
}
template <typename T1>
typename detail::make_assign_composite<self_type, T1>::type
operator=(T1 const& a1) const;
template <typename T1>
typename detail::make_index_composite<self_type, T1>::type
operator[](T1 const& a1) const;
// Bring in the rest of the constructors and function call operators
#include <boost/spirit/home/phoenix/core/detail/actor.hpp>
private:
// silence MSVC warning C4512: assignment operator could not be generated
actor& operator= (actor const&);
};
// Forward declaration: The intent to overload the comma must be
// stated early on to avoid the subtle problem that arises when
// the header file where the comma operator overload is defined,
// is not included by the client and the client attempts to use
// the comma anyway.
namespace detail
{
template <typename BaseT0, typename BaseT1>
struct comma_result;
}
template <typename BaseT0, typename BaseT1>
typename detail::comma_result<BaseT0, BaseT1>::type
operator,(actor<BaseT0> const& a0, actor<BaseT1> const& a1);
}}
namespace boost
{
template <typename Eval>
struct result_of<phoenix::actor<Eval>()>
{
typedef typename phoenix::actor<Eval>::nullary_result type;
};
template <typename Eval>
struct result_of<phoenix::actor<Eval> const()>
: result_of<phoenix::actor<Eval>()>
{};
}
#endif