boost/xpressive/detail/static/productions/set_compilers.hpp
////////////////////////////////////////////////////////////////////////////
// set_compilers.hpp
//
// Copyright 2004 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_PRODUCTIONS_SET_COMPILERS_HPP_EAN_10_04_2005
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_SET_COMPILERS_HPP_EAN_10_04_2005
#include <boost/xpressive/detail/detail_fwd.hpp>
#include <boost/xpressive/proto/proto.hpp>
#include <boost/xpressive/proto/compiler/fold.hpp>
#include <boost/xpressive/proto/compiler/branch.hpp>
#include <boost/xpressive/detail/utility/dont_care.hpp>
#include <boost/xpressive/detail/utility/traits_utils.hpp>
#include <boost/xpressive/detail/static/productions/domain_tags.hpp>
namespace boost { namespace xpressive { namespace detail
{
///////////////////////////////////////////////////////////////////////////////
// set_branch
//
struct set_branch
{
typedef no_next state_type;
template<typename, typename State, typename>
struct apply
{
typedef State type;
};
template<typename Op, typename State, typename Visitor>
static State const &call(Op const &op, State const &state, Visitor &)
{
return state.set(set_branch::get_matcher(op)), state;
}
private:
template<typename Matcher>
static Matcher const &get_matcher(static_xpression<Matcher, no_next> const &xpr)
{
return xpr;
}
};
///////////////////////////////////////////////////////////////////////////////
// list_branch
struct list_branch
{
typedef int state_type; // not used
template<typename Op, typename State, typename>
struct apply
{
typedef static_xpression<Op, State> type;
};
template<typename Op, typename State>
static static_xpression<Op, State>
call(Op const &op, State const &state, dont_care)
{
return make_static_xpression(op, state);
}
};
///////////////////////////////////////////////////////////////////////////////
// list_noop_compiler
struct list_noop_compiler
{
template<typename, typename State, typename>
struct apply
{
typedef typename State::next_type type;
};
template<typename Op, typename State, typename Visitor>
static typename State::next_type
call(Op const &op, State const &state, Visitor &visitor)
{
typedef typename Visitor::char_type char_type;
char_type ch = char_cast<char_type>(proto::arg(op), visitor.traits());
return state.push_back(ch, visitor.traits());
}
};
///////////////////////////////////////////////////////////////////////////////
// list_assign_compiler
struct list_assign_compiler
{
template<typename Op, typename, typename Visitor>
struct apply
{
typedef typename Visitor::traits_type traits_type;
typedef set_matcher<traits_type, 1> type;
};
template<typename Op, typename State, typename Visitor>
static typename apply<Op, State, Visitor>::type
call(Op const &op, State const &, Visitor &visitor)
{
typedef typename Visitor::char_type char_type;
char_type ch = char_cast<char_type>(proto::arg(proto::right(op)), visitor.traits());
return typename apply<Op, State, Visitor>::type(ch, visitor.traits());
}
};
}}}
namespace boost { namespace proto
{
///////////////////////////////////////////////////////////////////////////////
// compilers for sets such as set['a' | range('a','z')]
template<>
struct compiler<bitor_tag, xpressive::detail::set_tag, void>
: fold_compiler<bitor_tag, xpressive::detail::set_tag>
{
};
template<>
struct compiler<noop_tag, xpressive::detail::set_tag, void>
: branch_compiler<xpressive::detail::set_branch, xpressive::detail::seq_tag>
{
};
template<>
struct compiler<complement_tag, xpressive::detail::set_tag, void>
: branch_compiler<xpressive::detail::set_branch, xpressive::detail::seq_tag>
{
};
template<>
struct compiler<comma_tag, xpressive::detail::set_tag, void>
: branch_compiler<xpressive::detail::set_branch, xpressive::detail::seq_tag>
{
};
///////////////////////////////////////////////////////////////////////////////
// compilers for list-initialized sets such as (set='a','b','c')
template<>
struct compiler<comma_tag, xpressive::detail::seq_tag, void>
: branch_compiler<xpressive::detail::list_branch, xpressive::detail::lst_tag>
{
};
template<>
struct compiler<comma_tag, xpressive::detail::lst_tag, void>
: fold_compiler<comma_tag, xpressive::detail::lst_tag, false>
{
};
template<>
struct compiler<noop_tag, xpressive::detail::lst_tag, void>
: xpressive::detail::list_noop_compiler
{
};
template<>
struct compiler<assign_tag, xpressive::detail::lst_tag, void>
: xpressive::detail::list_assign_compiler
{
};
}}
#endif