/usr/include/boost/xpressive/detail/static/transforms
Edit: /usr/include/boost/xpressive/detail/static/transforms/as_set.hpp (7578B)
///////////////////////////////////////////////////////////////////////////////
// as_set.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_STATIC_TRANSFORMS_AS_SET_HPP_EAN_04_05_2007
#define BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_SET_HPP_EAN_04_05_2007
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
#include
#include
#include
#include
#include
#include
namespace boost { namespace xpressive { namespace grammar_detail
{
///////////////////////////////////////////////////////////////////////////
// CharLiteral
template
struct CharLiteral
: or_<
terminal
, terminal
>
{};
template<>
struct CharLiteral
: terminal
{};
///////////////////////////////////////////////////////////////////////////
// ListSet
// matches expressions like (set= 'a','b','c')
// calculates the size of the set
template
struct ListSet
: or_<
when<
comma, CharLiteral >
, make(_left)> > > // TODO make a custom transform for this...
>
, when<
assign >
, make >
>
>
{};
template
void fill_list_set(Char *&, detail::set_initializer_type, Traits const &)
{}
template
void fill_list_set(Char *&buffer, Expr const &expr, Traits const &traits)
{
fill_list_set(buffer, proto::left(expr), traits);
*buffer++ = traits.translate(detail::char_cast(proto::value(proto::right(expr)), traits));
}
///////////////////////////////////////////////////////////////////////////////
// as_list_set_matcher
template
struct as_list_set_matcher : proto::transform >
{
template
struct impl : proto::transform_impl
{
typedef typename impl::data data_type;
typedef
detail::set_matcher<
typename data_type::traits_type
, typename ListSet::template impl::result_type
>
result_type;
result_type operator ()(
typename impl::expr_param expr
, typename impl::state_param
, typename impl::data_param data
) const
{
result_type set;
typedef typename impl::data data_type;
typename data_type::char_type *buffer = set.set_;
fill_list_set(buffer, expr, data.traits());
return set;
}
};
};
///////////////////////////////////////////////////////////////////////////////
// merge_charset
//
template
struct merge_charset
{
typedef typename Data::traits_type traits_type;
typedef typename CharSet::char_type char_type;
typedef typename CharSet::icase_type icase_type;
merge_charset(CharSet &charset, Data &data)
: charset_(charset)
, visitor_(data)
{}
template
void operator ()(Expr const &expr) const
{
this->call_(expr, typename Expr::proto_tag());
}
private:
merge_charset &operator =(merge_charset const &);
template
void call_(Expr const &expr, Tag) const
{
this->set_(
typename Grammar::template impl()(
expr
, detail::end_xpression()
, this->visitor_
)
);
}
template
void call_(Expr const &expr, tag::bitwise_or) const
{
(*this)(proto::left(expr));
(*this)(proto::right(expr));
}
template
void set_(detail::literal_matcher const &ch) const
{
// BUGBUG fixme!
BOOST_MPL_ASSERT_NOT((Not));
set_char(this->charset_.charset_, ch.ch_, this->visitor_.traits(), icase_type());
}
void set_(detail::range_matcher const &rg) const
{
// BUGBUG fixme!
BOOST_ASSERT(!rg.not_);
set_range(this->charset_.charset_, rg.ch_min_, rg.ch_max_, this->visitor_.traits(), icase_type());
}
template
void set_(detail::set_matcher const &set_) const
{
// BUGBUG fixme!
BOOST_ASSERT(!set_.not_);
for(int i = 0; i < Size::value; ++i)
{
set_char(this->charset_.charset_, set_.set_[i], this->visitor_.traits(), icase_type());
}
}
void set_(detail::posix_charset_matcher const &posix) const
{
set_class(this->charset_.charset_, posix.mask_, posix.not_, this->visitor_.traits());
}
CharSet &charset_;
Data &visitor_;
};
///////////////////////////////////////////////////////////////////////////////
//
template
struct as_set_matcher : proto::transform >
{
template
struct impl : proto::transform_impl
{
typedef typename impl::data data_type;
typedef typename data_type::char_type char_type;
// if sizeof(char_type)==1, merge everything into a basic_chset
// BUGBUG this is not optimal.
typedef
typename mpl::if_c<
detail::is_narrow_char::value
, detail::basic_chset
, detail::compound_charset
>::type
charset_type;
typedef
detail::charset_matcher<
typename data_type::traits_type
, typename data_type::icase_type
, charset_type
>
result_type;
result_type operator ()(
typename impl::expr_param expr
, typename impl::state_param
, typename impl::data_param data
) const
{
result_type matcher;
merge_charset merge(matcher, data);
merge(expr); // Walks the tree and fills in the charset
return matcher;
}
};
};
}}}
#endif