/usr/include/boost/xpressive
Edit: /usr/include/boost/xpressive/regex_actions.hpp (60842B)
///////////////////////////////////////////////////////////////////////////////
/// \file regex_actions.hpp
/// Defines the syntax elements of xpressive's action expressions.
//
// 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_XPRESSIVE_ACTIONS_HPP_EAN_03_22_2007
#define BOOST_XPRESSIVE_ACTIONS_HPP_EAN_03_22_2007
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// These are very often needed by client code.
#include
#include
// Doxygen can't handle proto :-(
#ifndef BOOST_XPRESSIVE_DOXYGEN_INVOKED
# include
# include
# include
#endif
#if BOOST_MSVC
#pragma warning(push)
#pragma warning(disable : 4510) // default constructor could not be generated
#pragma warning(disable : 4512) // assignment operator could not be generated
#pragma warning(disable : 4610) // can never be instantiated - user defined constructor required
#endif
namespace boost { namespace xpressive
{
namespace detail
{
template
struct action_arg
{
typedef T type;
typedef typename add_reference::type reference;
reference cast(void *pv) const
{
return *static_cast::type *>(pv);
}
};
template
struct value_wrapper
: private noncopyable
{
value_wrapper()
: value()
{}
value_wrapper(T const &t)
: value(t)
{}
T value;
};
struct check_tag
{};
struct BindArg
{
BOOST_PROTO_CALLABLE()
template
struct result {};
template
struct result
{
typedef Expr type;
};
template
Expr const & operator ()(MatchResults &what, Expr const &expr) const
{
what.let(expr);
return expr;
}
};
struct let_tag
{};
// let(_a = b, _c = d)
struct BindArgs
: proto::function<
proto::terminal
, proto::vararg<
proto::when<
proto::assign
, proto::call
>
>
>
{};
struct let_domain
: boost::proto::domain >
{};
template
struct let_
{
BOOST_PROTO_BASIC_EXTENDS(Expr, let_, let_domain)
BOOST_PROTO_EXTENDS_FUNCTION()
};
template
void bind_args(let_ const &args, match_results &what)
{
BindArgs()(args, 0, what);
}
typedef boost::proto::functional::make_expr make_function;
}
namespace op
{
/// \brief \c at is a PolymorphicFunctionObject for indexing into a sequence
struct at
{
BOOST_PROTO_CALLABLE()
template
struct result {};
template
struct result
{
typedef typename Cont::reference type;
};
template
struct result
{
typedef typename Cont::const_reference type;
};
template
struct result
{
typedef typename Cont::const_reference type;
};
/// \pre \c Cont is a model of RandomAccessSequence
/// \param c The RandomAccessSequence to index into
/// \param idx The index
/// \return c[idx]
template
typename Cont::reference operator()(Cont &c, Idx idx BOOST_PROTO_DISABLE_IF_IS_CONST(Cont)) const
{
return c[idx];
}
/// \overload
///
template
typename Cont::const_reference operator()(Cont const &c, Idx idx) const
{
return c[idx];
}
};
/// \brief \c push is a PolymorphicFunctionObject for pushing an element into a container.
struct push
{
BOOST_PROTO_CALLABLE()
typedef void result_type;
/// \param seq The sequence into which the value should be pushed.
/// \param val The value to push into the sequence.
/// \brief Equivalent to seq.push(val).
/// \return \c void
template
void operator()(Sequence &seq, Value const &val) const
{
seq.push(val);
}
};
/// \brief \c push_back is a PolymorphicFunctionObject for pushing an element into the back of a container.
struct push_back
{
BOOST_PROTO_CALLABLE()
typedef void result_type;
/// \param seq The sequence into which the value should be pushed.
/// \param val The value to push into the sequence.
/// \brief Equivalent to seq.push_back(val).
/// \return \c void
template
void operator()(Sequence &seq, Value const &val) const
{
seq.push_back(val);
}
};
/// \brief \c push_front is a PolymorphicFunctionObject for pushing an element into the front of a container.
struct push_front
{
BOOST_PROTO_CALLABLE()
typedef void result_type;
/// \param seq The sequence into which the value should be pushed.
/// \param val The value to push into the sequence.
/// \brief Equivalent to seq.push_front(val).
/// \return \c void
template
void operator()(Sequence &seq, Value const &val) const
{
seq.push_front(val);
}
};
/// \brief \c pop is a PolymorphicFunctionObject for popping an element from a container.
struct pop
{
BOOST_PROTO_CALLABLE()
typedef void result_type;
/// \param seq The sequence from which to pop.
/// \brief Equivalent to seq.pop().
/// \return \c void
template
void operator()(Sequence &seq) const
{
seq.pop();
}
};
/// \brief \c pop_back is a PolymorphicFunctionObject for popping an element from the back of a container.
struct pop_back
{
BOOST_PROTO_CALLABLE()
typedef void result_type;
/// \param seq The sequence from which to pop.
/// \brief Equivalent to seq.pop_back().
/// \return \c void
template
void operator()(Sequence &seq) const
{
seq.pop_back();
}
};
/// \brief \c pop_front is a PolymorphicFunctionObject for popping an element from the front of a container.
struct pop_front
{
BOOST_PROTO_CALLABLE()
typedef void result_type;
/// \param seq The sequence from which to pop.
/// \brief Equivalent to seq.pop_front().
/// \return \c void
template
void operator()(Sequence &seq) const
{
seq.pop_front();
}
};
/// \brief \c front is a PolymorphicFunctionObject for fetching the front element of a container.
struct front
{
BOOST_PROTO_CALLABLE()
template
struct result {};
template
struct result
{
typedef typename remove_reference::type sequence_type;
typedef
typename mpl::if_c<
is_const::value
, typename sequence_type::const_reference
, typename sequence_type::reference
>::type
type;
};
/// \param seq The sequence from which to fetch the front.
/// \return seq.front()
template
typename result::type operator()(Sequence &seq) const
{
return seq.front();
}
};
/// \brief \c back is a PolymorphicFunctionObject for fetching the back element of a container.
struct back
{
BOOST_PROTO_CALLABLE()
template
struct result {};
template
struct result
{
typedef typename remove_reference::type sequence_type;
typedef
typename mpl::if_c<
is_const::value
, typename sequence_type::const_reference
, typename sequence_type::reference
>::type
type;
};
/// \param seq The sequence from which to fetch the back.
/// \return seq.back()
template
typename result::type operator()(Sequence &seq) const
{
return seq.back();
}
};
/// \brief \c top is a PolymorphicFunctionObject for fetching the top element of a stack.
struct top
{
BOOST_PROTO_CALLABLE()
template
struct result {};
template
struct result
{
typedef typename remove_reference::type sequence_type;
typedef
typename mpl::if_c<
is_const::value
, typename sequence_type::value_type const &
, typename sequence_type::value_type &
>::type
type;
};
/// \param seq The sequence from which to fetch the top.
/// \return seq.top()
template
typename result::type operator()(Sequence &seq) const
{
return seq.top();
}
};
/// \brief \c first is a PolymorphicFunctionObject for fetching the first element of a pair.
struct first
{
BOOST_PROTO_CALLABLE()
template
struct result {};
template
struct result
{
typedef typename remove_reference::type::first_type type;
};
/// \param p The pair from which to fetch the first element.
/// \return p.first
template
typename Pair::first_type operator()(Pair const &p) const
{
return p.first;
}
};
/// \brief \c second is a PolymorphicFunctionObject for fetching the second element of a pair.
struct second
{
BOOST_PROTO_CALLABLE()
template
struct result {};
template
struct result
{
typedef typename remove_reference::type::second_type type;
};
/// \param p The pair from which to fetch the second element.
/// \return p.second
template
typename Pair::second_type operator()(Pair const &p) const
{
return p.second;
}
};
/// \brief \c matched is a PolymorphicFunctionObject for assessing whether a \c sub_match object
/// matched or not.
struct matched
{
BOOST_PROTO_CALLABLE()
typedef bool result_type;
/// \param sub The \c sub_match object.
/// \return sub.matched
template
bool operator()(Sub const &sub) const
{
return sub.matched;
}
};
/// \brief \c length is a PolymorphicFunctionObject for fetching the length of \c sub_match.
struct length
{
BOOST_PROTO_CALLABLE()
template
struct result {};
template
struct result
{
typedef typename remove_reference::type::difference_type type;
};
/// \param sub The \c sub_match object.
/// \return sub.length()
template
typename Sub::difference_type operator()(Sub const &sub) const
{
return sub.length();
}
};
/// \brief \c str is a PolymorphicFunctionObject for turning a \c sub_match into an
/// equivalent \c std::string.
struct str
{
BOOST_PROTO_CALLABLE()
template
struct result {};
template
struct result
{
typedef typename remove_reference::type::string_type type;
};
/// \param sub The \c sub_match object.
/// \return sub.str()
template
typename Sub::string_type operator()(Sub const &sub) const
{
return sub.str();
}
};
// This codifies the return types of the various insert member
// functions found in sequence containers, the 2 flavors of
// associative containers, and strings.
//
/// \brief \c insert is a PolymorphicFunctionObject for inserting a value or a
/// sequence of values into a sequence container, an associative
/// container, or a string.
struct insert
{
BOOST_PROTO_CALLABLE()
/// INTERNAL ONLY
///
struct detail
{
template
struct result_detail
{};
// assoc containers
template
struct result_detail
{
typedef typename remove_reference::type cont_type;
typedef typename remove_reference::type value_type;
static cont_type &scont_;
static value_type &svalue_;
typedef char yes_type;
typedef char (&no_type)[2];
static yes_type check_insert_return(typename cont_type::iterator);
static no_type check_insert_return(std::pair);
BOOST_STATIC_CONSTANT(bool, is_iterator = (sizeof(yes_type) == sizeof(check_insert_return(scont_.insert(svalue_)))));
typedef
typename mpl::if_c<
is_iterator
, typename cont_type::iterator
, std::pair
>::type
type;
};
// sequence containers, assoc containers, strings
template
struct result_detail::type>::type>
, is_same<
typename remove_cv::type>::type
, typename remove_cv::type>::type
>
>
>::type
>
{
typedef typename remove_reference::type::iterator type;
};
// strings
template
struct result_detail::type>::type>
>::type
>
{
typedef typename remove_reference::type &type;
};
// assoc containers
template
struct result_detail
{
typedef void type;
};
// sequence containers, strings
template
struct result_detail::type>::type>
>::type
>
{
typedef void type;
};
// strings
template
struct result_detail::type>::type>
>::type
>
{
typedef typename remove_reference::type &type;
};
// strings
template
struct result_detail
{
typedef typename remove_reference::type &type;
};
};
template
struct result
{
typedef typename detail::result_detail::type type;
};
/// \overload
///
template
typename result::type
operator()(Cont &cont, A0 const &a0) const
{
return cont.insert(a0);
}
/// \overload
///
template
typename result::type
operator()(Cont &cont, A0 const &a0, A1 const &a1) const
{
return cont.insert(a0, a1);
}
/// \overload
///
template
typename result::type
operator()(Cont &cont, A0 const &a0, A1 const &a1, A2 const &a2) const
{
return cont.insert(a0, a1, a2);
}
/// \param cont The container into which to insert the element(s)
/// \param a0 A value, iterator, or count
/// \param a1 A value, iterator, string, count, or character
/// \param a2 A value, iterator, or count
/// \param a3 A count
/// \return \li For the form insert()(cont, a0), return cont.insert(a0).
/// \li For the form insert()(cont, a0, a1), return cont.insert(a0, a1).
/// \li For the form insert()(cont, a0, a1, a2), return cont.insert(a0, a1, a2).
/// \li For the form insert()(cont, a0, a1, a2, a3), return cont.insert(a0, a1, a2, a3).
template
typename result::type
operator()(Cont &cont, A0 const &a0, A1 const &a1, A2 const &a2, A3 const &a3) const
{
return cont.insert(a0, a1, a2, a3);
}
};
/// \brief \c make_pair is a PolymorphicFunctionObject for building a \c std::pair out of two parameters
struct make_pair
{
BOOST_PROTO_CALLABLE()
template
struct result {};
template
struct result
{
/// \brief For exposition only
typedef typename decay::type first_type;
/// \brief For exposition only
typedef typename decay::type second_type;
typedef std::pair type;
};
/// \param first The first element of the pair
/// \param second The second element of the pair
/// \return std::make_pair(first, second)
template
std::pair operator()(First const &first, Second const &second) const
{
return std::make_pair(first, second);
}
};
/// \brief \c as\<\> is a PolymorphicFunctionObject for lexically casting a parameter to a different type.
/// \tparam T The type to which to lexically cast the parameter.
template
struct as
{
BOOST_PROTO_CALLABLE()
typedef T result_type;
/// \param val The value to lexically cast.
/// \return boost::lexical_cast\(val)
template
T operator()(Value const &val) const
{
return boost::lexical_cast(val);
}
// Hack around some limitations in boost::lexical_cast
/// INTERNAL ONLY
T operator()(csub_match const &val) const
{
return val.matched
? boost::lexical_cast(boost::make_iterator_range(val.first, val.second))
: boost::lexical_cast("");
}
#ifndef BOOST_XPRESSIVE_NO_WREGEX
/// INTERNAL ONLY
T operator()(wcsub_match const &val) const
{
return val.matched
? boost::lexical_cast(boost::make_iterator_range(val.first, val.second))
: boost::lexical_cast("");
}
#endif
/// INTERNAL ONLY
template
T operator()(sub_match const &val) const
{
// If this assert fires, you're trying to coerce a sequences of non-characters
// to some other type. Xpressive doesn't know how to do that.
typedef typename iterator_value::type char_type;
BOOST_MPL_ASSERT_MSG(
(xpressive::detail::is_char::value)
, CAN_ONLY_CONVERT_FROM_CHARACTER_SEQUENCES
, (char_type)
);
return this->impl(val, xpressive::detail::is_string_iterator());
}
private:
/// INTERNAL ONLY
template
T impl(sub_match const &val, mpl::true_) const
{
return val.matched
? boost::lexical_cast(boost::make_iterator_range(&*val.first, &*val.first + (val.second - val.first)))
: boost::lexical_cast("");
}
/// INTERNAL ONLY
template
T impl(sub_match const &val, mpl::false_) const
{
return boost::lexical_cast(val.str());
}
};
/// \brief \c static_cast_\<\> is a PolymorphicFunctionObject for statically casting a parameter to a different type.
/// \tparam T The type to which to statically cast the parameter.
template
struct static_cast_
{
BOOST_PROTO_CALLABLE()
typedef T result_type;
/// \param val The value to statically cast.
/// \return static_cast\(val)
template
T operator()(Value const &val) const
{
return static_cast(val);
}
};
/// \brief \c dynamic_cast_\<\> is a PolymorphicFunctionObject for dynamically casting a parameter to a different type.
/// \tparam T The type to which to dynamically cast the parameter.
template
struct dynamic_cast_
{
BOOST_PROTO_CALLABLE()
typedef T result_type;
/// \param val The value to dynamically cast.
/// \return dynamic_cast\(val)
template
T operator()(Value const &val) const
{
return dynamic_cast(val);
}
};
/// \brief \c const_cast_\<\> is a PolymorphicFunctionObject for const-casting a parameter to a cv qualification.
/// \tparam T The type to which to const-cast the parameter.
template
struct const_cast_
{
BOOST_PROTO_CALLABLE()
typedef T result_type;
/// \param val The value to const-cast.
/// \pre Types \c T and \c Value differ only in cv-qualification.
/// \return const_cast\(val)
template
T operator()(Value const &val) const
{
return const_cast(val);
}
};
/// \brief \c construct\<\> is a PolymorphicFunctionObject for constructing a new object.
/// \tparam T The type of the object to construct.
template
struct construct
{
BOOST_PROTO_CALLABLE()
typedef T result_type;
/// \overload
T operator()() const
{
return T();
}
/// \overload
template
T operator()(A0 const &a0) const
{
return T(a0);
}
/// \overload
template
T operator()(A0 const &a0, A1 const &a1) const
{
return T(a0, a1);
}
/// \param a0 The first argument to the constructor
/// \param a1 The second argument to the constructor
/// \param a2 The third argument to the constructor
/// \return T(a0,a1,...)
template
T operator()(A0 const &a0, A1 const &a1, A2 const &a2) const
{
return T(a0, a1, a2);
}
};
/// \brief \c throw_\<\> is a PolymorphicFunctionObject for throwing an exception.
/// \tparam Except The type of the object to throw.
template
struct throw_
{
BOOST_PROTO_CALLABLE()
typedef void result_type;
/// \overload
void operator()() const
{
BOOST_THROW_EXCEPTION(Except());
}
/// \overload
template
void operator()(A0 const &a0) const
{
BOOST_THROW_EXCEPTION(Except(a0));
}
/// \overload
template
void operator()(A0 const &a0, A1 const &a1) const
{
BOOST_THROW_EXCEPTION(Except(a0, a1));
}
/// \param a0 The first argument to the constructor
/// \param a1 The second argument to the constructor
/// \param a2 The third argument to the constructor
/// \throw Except(a0,a1,...)
/// \note This function makes use of the \c BOOST_THROW_EXCEPTION macro
/// to actually throw the exception. See the documentation for the
/// Boost.Exception library.
template
void operator()(A0 const &a0, A1 const &a1, A2 const &a2) const
{
BOOST_THROW_EXCEPTION(Except(a0, a1, a2));
}
};
/// \brief \c unwrap_reference is a PolymorphicFunctionObject for unwrapping a boost::reference_wrapper\<\>.
struct unwrap_reference
{
BOOST_PROTO_CALLABLE()
template
struct result {};
template
struct result
{
typedef typename boost::unwrap_reference[::type &type;
};
template
struct result
{
typedef typename boost::unwrap_reference][::type &type;
};
/// \param r The boost::reference_wrapper\ to unwrap.
/// \return static_cast\(r)
template
T &operator()(boost::reference_wrapper r) const
{
return static_cast(r);
}
};
}
/// \brief A unary metafunction that turns an ordinary function object type into the type of
/// a deferred function object for use in xpressive semantic actions.
///
/// Use \c xpressive::function\<\> to turn an ordinary polymorphic function object type
/// into a type that can be used to declare an object for use in xpressive semantic actions.
///
/// For example, the global object \c xpressive::push_back can be used to create deferred actions
/// that have the effect of pushing a value into a container. It is defined with
/// \c xpressive::function\<\> as follows:
///
/** \code
xpressive::function::type const push_back = {};
\endcode
*/
///
/// where \c op::push_back is an ordinary function object that pushes its second argument into
/// its first. Thus defined, \c xpressive::push_back can be used in semantic actions as follows:
///
/** \code
namespace xp = boost::xpressive;
using xp::_;
std::list result;
std::string str("1 23 456 7890");
xp::sregex rx = (+_d)[ xp::push_back(xp::ref(result), xp::as(_) ]
>> *(' ' >> (+_d)[ xp::push_back(xp::ref(result), xp::as(_) ) ]);
\endcode
*/
template
struct function
{
typedef typename proto::terminal::type type;
};
/// \brief \c at is a lazy PolymorphicFunctionObject for indexing into a sequence in an
/// xpressive semantic action.
function::type const at = {{}};
/// \brief \c push is a lazy PolymorphicFunctionObject for pushing a value into a container in an
/// xpressive semantic action.
function::type const push = {{}};
/// \brief \c push_back is a lazy PolymorphicFunctionObject for pushing a value into a container in an
/// xpressive semantic action.
function::type const push_back = {{}};
/// \brief \c push_front is a lazy PolymorphicFunctionObject for pushing a value into a container in an
/// xpressive semantic action.
function::type const push_front = {{}};
/// \brief \c pop is a lazy PolymorphicFunctionObject for popping the top element from a sequence in an
/// xpressive semantic action.
function::type const pop = {{}};
/// \brief \c pop_back is a lazy PolymorphicFunctionObject for popping the back element from a sequence in an
/// xpressive semantic action.
function::type const pop_back = {{}};
/// \brief \c pop_front is a lazy PolymorphicFunctionObject for popping the front element from a sequence in an
/// xpressive semantic action.
function::type const pop_front = {{}};
/// \brief \c top is a lazy PolymorphicFunctionObject for accessing the top element from a stack in an
/// xpressive semantic action.
function::type const top = {{}};
/// \brief \c back is a lazy PolymorphicFunctionObject for fetching the back element of a sequence in an
/// xpressive semantic action.
function::type const back = {{}};
/// \brief \c front is a lazy PolymorphicFunctionObject for fetching the front element of a sequence in an
/// xpressive semantic action.
function::type const front = {{}};
/// \brief \c first is a lazy PolymorphicFunctionObject for accessing the first element of a \c std::pair\<\> in an
/// xpressive semantic action.
function::type const first = {{}};
/// \brief \c second is a lazy PolymorphicFunctionObject for accessing the second element of a \c std::pair\<\> in an
/// xpressive semantic action.
function::type const second = {{}};
/// \brief \c matched is a lazy PolymorphicFunctionObject for accessing the \c matched member of a \c xpressive::sub_match\<\> in an
/// xpressive semantic action.
function::type const matched = {{}};
/// \brief \c length is a lazy PolymorphicFunctionObject for computing the length of a \c xpressive::sub_match\<\> in an
/// xpressive semantic action.
function::type const length = {{}};
/// \brief \c str is a lazy PolymorphicFunctionObject for converting a \c xpressive::sub_match\<\> to a \c std::basic_string\<\> in an
/// xpressive semantic action.
function::type const str = {{}};
/// \brief \c insert is a lazy PolymorphicFunctionObject for inserting a value or a range of values into a sequence in an
/// xpressive semantic action.
function::type const insert = {{}};
/// \brief \c make_pair is a lazy PolymorphicFunctionObject for making a \c std::pair\<\> in an
/// xpressive semantic action.
function::type const make_pair = {{}};
/// \brief \c unwrap_reference is a lazy PolymorphicFunctionObject for unwrapping a \c boost::reference_wrapper\<\> in an
/// xpressive semantic action.
function::type const unwrap_reference = {{}};
/// \brief \c value\<\> is a lazy wrapper for a value that can be used in xpressive semantic actions.
/// \tparam T The type of the value to store.
///
/// Below is an example that shows where \c value\<\> is useful.
///
/** \code
sregex good_voodoo(boost::shared_ptr pi)
{
using namespace boost::xpressive;
// Use val() to hold the shared_ptr by value:
sregex rex = +( _d [ ++*val(pi) ] >> '!' );
// OK, rex holds a reference count to the integer.
return rex;
}
\endcode
*/
///
/// In the above code, \c xpressive::val() is a function that returns a \c value\<\> object. Had
/// \c val() not been used here, the operation ++*pi would have been evaluated eagerly
/// once, instead of lazily when the regex match happens.
template
struct value
: proto::extends::type, value >
{
/// INTERNAL ONLY
typedef proto::extends::type, value > base_type;
/// \brief Store a default-constructed \c T
value()
: base_type()
{}
/// \param t The initial value.
/// \brief Store a copy of \c t.
explicit value(T const &t)
: base_type(base_type::proto_base_expr::make(t))
{}
using base_type::operator=;
/// \overload
T &get()
{
return proto::value(*this);
}
/// \brief Fetch the stored value
T const &get() const
{
return proto::value(*this);
}
};
/// \brief \c reference\<\> is a lazy wrapper for a reference that can be used in
/// xpressive semantic actions.
///
/// \tparam T The type of the referent.
///
/// Here is an example of how to use \c reference\<\> to create a lazy reference to
/// an existing object so it can be read and written in an xpressive semantic action.
///
/** \code
using namespace boost::xpressive;
std::map result;
reference > result_ref(result);
// Match a word and an integer, separated by =>,
// and then stuff the result into a std::map<>
sregex pair = ( (s1= +_w) >> "=>" >> (s2= +_d) )
[ result_ref[s1] = as(s2) ];
\endcode
*/
template
struct reference
: proto::extends >::type, reference >
{
/// INTERNAL ONLY
typedef proto::extends >::type, reference > base_type;
/// \param t Reference to object
/// \brief Store a reference to \c t
explicit reference(T &t)
: base_type(base_type::proto_base_expr::make(boost::ref(t)))
{}
using base_type::operator=;
/// \brief Fetch the stored value
T &get() const
{
return proto::value(*this).get();
}
};
/// \brief \c local\<\> is a lazy wrapper for a reference to a value that is stored within the local itself.
/// It is for use within xpressive semantic actions.
///
/// \tparam T The type of the local variable.
///
/// Below is an example of how to use \c local\<\> in semantic actions.
///
/** \code
using namespace boost::xpressive;
local i(0);
std::string str("1!2!3?");
// count the exciting digits, but not the
// questionable ones.
sregex rex = +( _d [ ++i ] >> '!' );
regex_search(str, rex);
assert( i.get() == 2 );
\endcode
*/
///
/// \note As the name "local" suggests, \c local\<\> objects and the regexes
/// that refer to them should never leave the local scope. The value stored
/// within the local object will be destroyed at the end of the \c local\<\>'s
/// lifetime, and any regex objects still holding the \c local\<\> will be
/// left with a dangling reference.
template
struct local
: detail::value_wrapper
, proto::terminal >::type
{
/// INTERNAL ONLY
typedef typename proto::terminal >::type base_type;
/// \brief Store a default-constructed value of type \c T
local()
: detail::value_wrapper()
, base_type(base_type::make(boost::ref(detail::value_wrapper::value)))
{}
/// \param t The initial value.
/// \brief Store a default-constructed value of type \c T
explicit local(T const &t)
: detail::value_wrapper(t)
, base_type(base_type::make(boost::ref(detail::value_wrapper::value)))
{}
using base_type::operator=;
/// Fetch the wrapped value.
T &get()
{
return proto::value(*this);
}
/// \overload
T const &get() const
{
return proto::value(*this);
}
};
/// \brief \c as() is a lazy funtion for lexically casting a parameter to a different type.
/// \tparam T The type to which to lexically cast the parameter.
/// \param a The lazy value to lexically cast.
/// \return A lazy object that, when evaluated, lexically casts its argument to the desired type.
template
typename detail::make_function::impl const, A const &>::result_type const
as(A const &a)
{
return detail::make_function::impl const, A const &>()((op::as()), a);
}
/// \brief \c static_cast_ is a lazy funtion for statically casting a parameter to a different type.
/// \tparam T The type to which to statically cast the parameter.
/// \param a The lazy value to statically cast.
/// \return A lazy object that, when evaluated, statically casts its argument to the desired type.
template
typename detail::make_function::impl const, A const &>::result_type const
static_cast_(A const &a)
{
return detail::make_function::impl const, A const &>()((op::static_cast_()), a);
}
/// \brief \c dynamic_cast_ is a lazy funtion for dynamically casting a parameter to a different type.
/// \tparam T The type to which to dynamically cast the parameter.
/// \param a The lazy value to dynamically cast.
/// \return A lazy object that, when evaluated, dynamically casts its argument to the desired type.
template
typename detail::make_function::impl const, A const &>::result_type const
dynamic_cast_(A const &a)
{
return detail::make_function::impl const, A const &>()((op::dynamic_cast_]