/////////////////////////////////////////////////////////////////////////////// | |
// attr_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_ATTR_MATCHER_HPP_EAN_06_09_2007 | |
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_ATTR_MATCHER_HPP_EAN_06_09_2007 | |
// MS compatible compilers support #pragma once | |
#if defined(_MSC_VER) && (_MSC_VER >= 1020) | |
# pragma once | |
#endif | |
#include <boost/xpressive/detail/detail_fwd.hpp> | |
#include <boost/xpressive/detail/core/quant_style.hpp> | |
#include <boost/xpressive/detail/core/state.hpp> | |
#include <boost/xpressive/detail/utility/symbols.hpp> | |
namespace boost { namespace xpressive { namespace detail | |
{ | |
/////////////////////////////////////////////////////////////////////////////// | |
// char_translate | |
// | |
template<typename Traits, bool ICase> | |
struct char_translate | |
{ | |
typedef typename Traits::char_type char_type; | |
Traits const &traits_; | |
explicit char_translate(Traits const &tr) | |
: traits_(tr) | |
{} | |
char_type operator ()(char_type ch1) const | |
{ | |
return this->traits_.translate(ch1); | |
} | |
private: | |
char_translate &operator =(char_translate const &); | |
}; | |
/////////////////////////////////////////////////////////////////////////////// | |
// char_translate | |
// | |
template<typename Traits> | |
struct char_translate<Traits, true> | |
{ | |
typedef typename Traits::char_type char_type; | |
Traits const &traits_; | |
explicit char_translate(Traits const &tr) | |
: traits_(tr) | |
{} | |
char_type operator ()(char_type ch1) const | |
{ | |
return this->traits_.translate_nocase(ch1); | |
} | |
private: | |
char_translate &operator =(char_translate const &); | |
}; | |
/////////////////////////////////////////////////////////////////////////////// | |
// attr_matcher | |
// Note: the Matcher is a std::map | |
template<typename Matcher, typename Traits, typename ICase> | |
struct attr_matcher | |
: quant_style<quant_none, 0, false> | |
{ | |
typedef typename Matcher::value_type::second_type const* result_type; | |
attr_matcher(int slot, Matcher const &matcher, Traits const& tr) | |
: slot_(slot-1) | |
{ | |
char_translate<Traits, ICase::value> trans(tr); | |
this->sym_.load(matcher, trans); | |
} | |
template<typename BidiIter, typename Next> | |
bool match(match_state<BidiIter> &state, Next const &next) const | |
{ | |
BidiIter tmp = state.cur_; | |
char_translate<Traits, ICase::value> trans(traits_cast<Traits>(state)); | |
result_type const &result = this->sym_(state.cur_, state.end_, trans); | |
if(result) | |
{ | |
void const *old_slot = state.attr_context_.attr_slots_[this->slot_]; | |
state.attr_context_.attr_slots_[this->slot_] = &*result; | |
if(next.match(state)) | |
{ | |
return true; | |
} | |
state.attr_context_.attr_slots_[this->slot_] = old_slot; | |
} | |
state.cur_ = tmp; | |
return false; | |
} | |
int slot_; | |
boost::xpressive::detail::symbols<Matcher> sym_; | |
}; | |
}}} | |
#endif |