/usr/include/boost/xpressive/detail/core
Edit: /usr/include/boost/xpressive/detail/core/linker.hpp (8567B)
///////////////////////////////////////////////////////////////////////////////
// linker.hpp
//
// 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_DETAIL_CORE_LINKER_HPP_EAN_10_04_2005
#define BOOST_XPRESSIVE_DETAIL_CORE_LINKER_HPP_EAN_10_04_2005
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
#include
#ifndef BOOST_NO_STD_LOCALE
# include
#endif
#include
#include
#include
#include
#include
#include
#if BOOST_VERSION >= 103500
# include
#else
# include
#endif
#include
#include
#include
#include
#include
namespace boost { namespace xpressive { namespace detail
{
///////////////////////////////////////////////////////////////////////////////
// icase_modifier
//
// wrapped by the modifier<> template and inserted into the xpression
// template with the icase() helper function. icase_modifier morphs
// a case-sensitive visitor into a case-insensitive visitor, which
// causes all matchers visited to become case-insensitive.
//
struct icase_modifier
{
template
struct apply {};
template
struct apply >
{
typedef xpression_visitor type;
};
template
static typename apply::type
call(Visitor &visitor)
{
return typename apply::type(visitor.traits(), visitor.self());
}
};
///////////////////////////////////////////////////////////////////////////////
// regex_traits_type : wrap a locale in the appropriate regex_traits
//
template
struct regex_traits_type
{
#ifndef BOOST_NO_STD_LOCALE
typedef typename iterator_value::type char_type;
// if Locale is std::locale, wrap it in a cpp_regex_traits
typedef typename mpl::if_c
<
is_same::value
, cpp_regex_traits
, Locale
>::type type;
#else
typedef Locale type;
#endif
};
///////////////////////////////////////////////////////////////////////////////
// locale_modifier
//
// wrapped by the modifier<> template and inserted into the xpression
// template with the imbue() helper function. Causes a sub-xpression to
// use the specified Locale
//
template
struct locale_modifier
{
typedef Locale locale_type;
locale_modifier(Locale const &loc)
: loc_(loc)
{
}
template
struct apply {};
template
struct apply >
{
typedef typename regex_traits_type::type traits_type;
typedef xpression_visitor type;
};
template
typename apply::type
call(Visitor &visitor) const
{
return typename apply::type(this->loc_, visitor.self());
}
Locale getloc() const
{
return this->loc_;
}
private:
Locale loc_;
};
///////////////////////////////////////////////////////////////////////////////
// xpression_linker
//
template
struct xpression_linker
{
template
explicit xpression_linker(Traits const &tr)
: back_stack_()
, traits_(&tr)
, traits_type_(&typeid(Traits))
, has_backrefs_(false)
{
}
template
void accept(Matcher const &, void const *)
{
// no-op
}
template
void accept(mark_matcher const &, void const *)
{
this->has_backrefs_ = true;
}
template
void accept(action_matcher const &, void const *)
{
this->has_backrefs_ = true;
}
template
void accept(predicate_matcher const &, void const *)
{
this->has_backrefs_ = true;
}
void accept(repeat_begin_matcher const &, void const *next)
{
this->back_stack_.push(next);
}
template
void accept(repeat_end_matcher const &matcher, void const *)
{
matcher.back_ = this->back_stack_.top();
this->back_stack_.pop();
}
template
void accept(alternate_matcher const &matcher, void const *next)
{
xpression_peeker peeker(matcher.bset_, this->get_traits());
this->alt_link(matcher.alternates_, next, &peeker);
}
void accept(alternate_end_matcher const &matcher, void const *)
{
matcher.back_ = this->back_stack_.top();
this->back_stack_.pop();
}
template
void accept(optional_matcher const &matcher, void const *next)
{
this->back_stack_.push(next);
matcher.xpr_.link(*this);
}
template
void accept(optional_mark_matcher const &matcher, void const *next)
{
this->back_stack_.push(next);
matcher.xpr_.link(*this);
}
template
void accept(keeper_matcher const &matcher, void const *)
{
matcher.xpr_.link(*this);
}
template
void accept(lookahead_matcher const &matcher, void const *)
{
matcher.xpr_.link(*this);
}
template
void accept(lookbehind_matcher const &matcher, void const *)
{
matcher.xpr_.link(*this);
}
template
void accept(simple_repeat_matcher const &matcher, void const *)
{
matcher.xpr_.link(*this);
}
// accessors
bool has_backrefs() const
{
return this->has_backrefs_;
}
// for use by alt_link_pred below
template
void alt_branch_link(Xpr const &xpr, void const *next, xpression_peeker *peeker)
{
this->back_stack_.push(next);
xpr.link(*this);
xpr.peek(*peeker);
}
private:
///////////////////////////////////////////////////////////////////////////////
// alt_link_pred
//
struct alt_link_pred
{
xpression_linker *linker_;
xpression_peeker *peeker_;
void const *next_;
alt_link_pred
(
xpression_linker *linker
, xpression_peeker *peeker
, void const *next
)
: linker_(linker)
, peeker_(peeker)
, next_(next)
{
}
template
void operator ()(Xpr const &xpr) const
{
this->linker_->alt_branch_link(xpr, this->next_, this->peeker_);
}
};
template
void alt_link
(
alternates_vector const &alternates
, void const *next
, xpression_peeker *peeker
)
{
std::for_each(alternates.begin(), alternates.end(), alt_link_pred(this, peeker, next));
}
template
void alt_link
(
fusion::sequence_base const &alternates
, void const *next
, xpression_peeker *peeker
)
{
#if BOOST_VERSION >= 103500
fusion::for_each(alternates.derived(), alt_link_pred(this, peeker, next));
#else
fusion::for_each(alternates.cast(), alt_link_pred(this, peeker, next));
#endif
}
template
Traits const &get_traits() const
{
BOOST_ASSERT(*this->traits_type_ == typeid(Traits));
return *static_cast(this->traits_);
}
std::stack back_stack_;
void const *traits_;
std::type_info const *traits_type_;
bool has_backrefs_;
};
}}} // namespace boost::xpressive::detail
#endif