blob: 7f5170a12c0fd98634a1d756c122eb47312f87dc [file] [log] [blame]
/*==============================================================================
Copyright (c) 2001-2010 Joel de Guzman
Copyright (c) 2010 Thomas Heller
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_PHOENIX_CORE_REFERENCE_HPP
#define BOOST_PHOENIX_CORE_REFERENCE_HPP
#include <boost/phoenix/core/limits.hpp>
#include <boost/ref.hpp>
#include <boost/phoenix/core/actor.hpp>
#include <boost/phoenix/core/terminal.hpp>
#include <boost/utility/result_of.hpp>
namespace boost { namespace phoenix
{
/////////////////////////////////////////////////////////////////////////////
//
// reference
//
// function for evaluating references, e.g. ref(123)
//
/////////////////////////////////////////////////////////////////////////////
namespace expression
{
template <typename T>
struct reference
: expression::terminal<reference_wrapper<T> >
{
typedef
typename expression::terminal<reference_wrapper<T> >::type
type;
static const type make(T & t)
{
typename reference<T>::type const e = {{boost::ref(t)}};
return e;
}
};
template <typename T>
struct reference<T const>
: expression::terminal<reference_wrapper<T const> >
{
typedef
typename expression::terminal<reference_wrapper<T const> >::type
type;
static const type make(T const & t)
{
typename reference<T const>::type const e = {{boost::cref(t)}};
return e;
}
};
}
namespace rule
{
struct reference
: expression::reference<proto::_>
{};
}
template <typename T>
inline
typename expression::reference<T>::type const
ref(T & t)
{
return expression::reference<T>::make(t);
}
template <typename T>
inline
typename expression::reference<T const>::type const
cref(T const & t)
{
return expression::reference<T const>::make(t);
}
// Call out boost::reference_wrapper for special handling
template<typename T>
struct is_custom_terminal<boost::reference_wrapper<T> >
: mpl::true_
{};
// Special handling for boost::reference_wrapper
template<typename T>
struct custom_terminal<boost::reference_wrapper<T> >
{
typedef T &result_type;
template <typename Context>
T &operator()(boost::reference_wrapper<T> r, Context &) const
{
return r;
}
};
template<typename Expr>
struct custom_terminal<boost::reference_wrapper<actor<Expr> > >
{
template <typename Sig>
struct result;
template <typename This, typename Context>
struct result<This(boost::reference_wrapper<actor<Expr> > const &, Context)>
: boost::result_of<evaluator(actor<Expr> &, Context)>
{};
template <typename This, typename Context>
struct result<This(boost::reference_wrapper<actor<Expr> > &, Context)>
: boost::result_of<evaluator(actor<Expr> &, Context)>
{};
template <typename Context>
typename boost::result_of<evaluator(actor<Expr> &, Context const &)>::type
operator()(boost::reference_wrapper<actor<Expr> > & r, Context const & ctx) const
{
return boost::phoenix::eval(r, ctx);
}
};
template<typename Expr>
struct custom_terminal<boost::reference_wrapper<actor<Expr> const> >
{
template <typename Sig>
struct result;
template <typename This, typename Context>
struct result<This(boost::reference_wrapper<actor<Expr> const> const &, Context)>
: boost::result_of<evaluator(actor<Expr> const&, Context)>
{};
template <typename This, typename Context>
struct result<This(boost::reference_wrapper<actor<Expr> const> &, Context)>
: boost::result_of<evaluator(actor<Expr> const&, Context)>
{};
template <typename Context>
typename boost::result_of<evaluator(actor<Expr> const&, Context const &)>::type
operator()(boost::reference_wrapper<actor<Expr> const> const & r, Context & ctx) const
{
return boost::phoenix::eval(unwrap_ref(r), ctx);
}
};
}}
#endif