/usr/include/boost/xpressive/detail/core/matcher
Edit: /usr/include/boost/xpressive/detail/core/matcher/action_matcher.hpp (16313B)
///////////////////////////////////////////////////////////////////////////////
// action_matcher.hpp
//
// Copyright 2008 Eric Niebler.
// Copyright 2008 David Jenkins.
//
// 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_DETAIL_CORE_MATCHER_ACTION_MATCHER_HPP_EAN_10_04_2005
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_ACTION_MATCHER_HPP_EAN_10_04_2005
// 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 // for type_info_less
#include // for 'read_attr'
#if BOOST_VERSION >= 103500
# include
# include
# 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
{
#if BOOST_VERSION >= 103500
struct DataMember
: proto::mem_ptr >
{};
template
struct child_
: remove_reference<
typename proto::result_of::child_c::type
>
{};
///////////////////////////////////////////////////////////////////////////////
// mem_ptr_eval
// Rewrites expressions of the form x->*foo(a) into foo(x, a) and then
// evaluates them.
template::value>
struct mem_ptr_eval
{
typedef typename child_::type left_type;
typedef typename child_::type right_type;
typedef
typename proto::result_of::value<
typename proto::result_of::child_c::type
>::type
function_type;
typedef
fusion::transform_view<
typename fusion::result_of::push_front<
typename fusion::result_of::pop_front::type const
, reference_wrapper
>::type const
, proto::eval_fun
>
evaluated_args;
typedef
typename fusion::result_of::invoke::type
result_type;
result_type operator()(Expr &expr, Context &ctx) const
{
return fusion::invoke(
proto::value(proto::child_c<0>(proto::right(expr)))
, evaluated_args(
fusion::push_front(fusion::pop_front(proto::right(expr)), boost::ref(proto::left(expr)))
, proto::eval_fun(ctx)
)
);
}
};
///////////////////////////////////////////////////////////////////////////////
// mem_ptr_eval
// Rewrites expressions of the form x->*foo into foo(x) and then
// evaluates them.
template
struct mem_ptr_eval
{
typedef typename child_::type left_type;
typedef typename child_::type right_type;
typedef
typename proto::result_of::value::type
function_type;
typedef typename boost::result_of<
function_type(typename proto::result_of::eval::type)
>::type result_type;
result_type operator()(Expr &expr, Context &ctx) const
{
return proto::value(proto::right(expr))(
proto::eval(proto::left(expr), ctx)
);
}
};
#endif
struct attr_with_default_tag
{};
template
struct opt;
///////////////////////////////////////////////////////////////////////////////
// action_context
//
struct action_context
{
explicit action_context(action_args_type *action_args)
: action_args_(action_args)
{}
action_args_type const &args() const
{
return *this->action_args_;
}
// eval_terminal
template
struct eval_terminal
: proto::default_eval
{};
template
struct eval_terminal >
{
typedef Arg &result_type;
result_type operator()(Expr &expr, action_context const &) const
{
return proto::value(expr).get();
}
};
template
struct eval_terminal >
{
typedef Arg const &result_type;
result_type operator()(Expr &expr, action_context const &) const
{
return proto::value(expr);
}
};
template
struct eval_terminal >
{
typedef typename action_arg::reference result_type;
result_type operator()(Expr &expr, action_context const &ctx) const
{
action_args_type::const_iterator where_ = ctx.args().find(&typeid(proto::value(expr)));
if(where_ == ctx.args().end())
{
BOOST_THROW_EXCEPTION(
regex_error(
regex_constants::error_badarg
, "An argument to an action was unspecified"
)
);
}
return proto::value(expr).cast(where_->second);
}
};
// eval
template
struct eval
: proto::default_eval
{};
template
struct eval
: eval_terminal::type>
{};
// Evaluate attributes like a1|42
template
struct eval
{
typedef
typename proto::result_of::value<
typename proto::result_of::left<
typename proto::result_of::child<
Expr
>::type
>::type
>::type
temp_type;
typedef typename temp_type::type result_type;
result_type operator ()(Expr const &expr, action_context const &ctx) const
{
return proto::value(proto::left(proto::child(expr))).t_
? *proto::value(proto::left(proto::child(expr))).t_
: proto::eval(proto::right(proto::child(expr)), ctx);
}
};
#if BOOST_VERSION >= 103500
template
struct eval
: mem_ptr_eval
{};
#endif
private:
action_args_type *action_args_;
};
///////////////////////////////////////////////////////////////////////////////
// action
//
template
struct action
: actionable
{
action(Actor const &actor)
: actionable()
, actor_(actor)
{
}
virtual void execute(action_args_type *action_args) const
{
action_context const ctx(action_args);
proto::eval(this->actor_, ctx);
}
private:
Actor actor_;
};
///////////////////////////////////////////////////////////////////////////////
// subreg_transform
//
struct subreg_transform : proto::transform
{
template
struct impl : proto::transform_impl
{
typedef typename impl::state state_type;
typedef
typename proto::terminal >::type
result_type;
result_type operator ()(
typename impl::expr_param
, typename impl::state_param state
, typename impl::data_param data
) const
{
return result_type::make(state.sub_matches_[ data ]);
}
};
};
///////////////////////////////////////////////////////////////////////////////
// mark_transform
//
struct mark_transform : proto::transform
{
template
struct impl : proto::transform_impl
{
typedef typename impl::state state_type;
typedef
typename proto::terminal >::type
result_type;
result_type operator ()(
typename impl::expr_param expr
, typename impl::state_param state
, typename impl::data_param
) const
{
return result_type::make(state.sub_matches_[ proto::value(expr).mark_number_ ]);
}
};
};
///////////////////////////////////////////////////////////////////////////////
// opt
//
template
struct opt
{
typedef T type;
typedef T const &reference;
opt(T const *t)
: t_(t)
{}
operator reference() const
{
BOOST_XPR_ENSURE_(0 != this->t_, regex_constants::error_badattr, "Use of uninitialized regex attribute");
return *this->t_;
}
T const *t_;
};
///////////////////////////////////////////////////////////////////////////////
// attr_transform
//
struct attr_transform : proto::transform
{
template
struct impl : proto::transform_impl
{
typedef typename impl::expr expr_type;
typedef
typename expr_type::proto_child0::matcher_type::value_type::second_type
attr_type;
typedef
typename proto::terminal >::type
result_type;
result_type operator ()(
typename impl::expr_param
, typename impl::state_param state
, typename impl::data_param
) const
{
int slot = typename expr_type::proto_child0::nbr_type();
attr_type const *attr = static_cast(state.attr_context_.attr_slots_[slot-1]);
return result_type::make(opt(attr));
}
};
};
///////////////////////////////////////////////////////////////////////////////
// attr_with_default_transform
//
template
struct attr_with_default_transform : proto::transform >
{
template
struct impl : proto::transform_impl
{
typedef
typename proto::unary_expr<
attr_with_default_tag
, typename Grammar::template impl::result_type
>::type
result_type;
result_type operator ()(
typename impl::expr_param expr
, typename impl::state_param state
, typename impl::data_param data
) const
{
result_type that = {
typename Grammar::template impl()(expr, state, data)
};
return that;
}
};
};
///////////////////////////////////////////////////////////////////////////////
// by_ref_transform
//
struct by_ref_transform : proto::transform
{
template
struct impl : proto::transform_impl
{
typedef
typename proto::result_of::value::type
reference;
typedef
typename proto::terminal::type
result_type;
result_type operator ()(
typename impl::expr_param expr
, typename impl::state_param
, typename impl::data_param
) const
{
return result_type::make(proto::value(expr));
}
};
};
///////////////////////////////////////////////////////////////////////////////
// BindActionArgs
//
struct BindActionArgs
: proto::or_<
proto::when, subreg_transform>
, proto::when, mark_transform>
, proto::when >, attr_transform>
, proto::when, by_ref_transform>
, proto::when<
proto::bitwise_or >, BindActionArgs>
, attr_with_default_transform >
>
, proto::otherwise > >
>
{};
///////////////////////////////////////////////////////////////////////////////
// action_matcher
//
template
struct action_matcher
: quant_style
{
int sub_;
Actor actor_;
action_matcher(Actor const &actor, int sub)
: sub_(sub)
, actor_(actor)
{
}
template
bool match(match_state &state, Next const &next) const
{
// Bind the arguments
typedef
typename boost::result_of &
, int const &
)>::type
action_type;
action actor(BindActionArgs()(this->actor_, state, this->sub_));
// Put the action in the action list
actionable const **action_list_tail = state.action_list_tail_;
*state.action_list_tail_ = &actor;
state.action_list_tail_ = &actor.next;
// Match the rest of the pattern
if(next.match(state))
{
return true;
}
BOOST_ASSERT(0 == actor.next);
// remove action from list
*action_list_tail = 0;
state.action_list_tail_ = action_list_tail;
return false;
}
};
}}}
#if BOOST_MSVC
#pragma warning(pop)
#endif
#endif