1 /////////////////////////////////////////////////////////////////////////////// 2 // attr_matcher.hpp 3 // 4 // Copyright 2008 Eric Niebler. 5 // Copyright 2008 David Jenkins. 6 // 7 // Distributed under the Boost Software License, Version 1.0. (See 8 // accompanying file LICENSE_1_0.txt or copy at 9 // http://www.boost.org/LICENSE_1_0.txt) 10 11 #ifndef BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_ATTR_MATCHER_HPP_EAN_06_09_2007 12 #define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_ATTR_MATCHER_HPP_EAN_06_09_2007 13 14 // MS compatible compilers support #pragma once 15 #if defined(_MSC_VER) 16 # pragma once 17 #endif 18 19 #include <boost/xpressive/detail/detail_fwd.hpp> 20 #include <boost/xpressive/detail/core/quant_style.hpp> 21 #include <boost/xpressive/detail/core/state.hpp> 22 #include <boost/xpressive/detail/utility/symbols.hpp> 23 24 namespace boost { namespace xpressive { namespace detail 25 { 26 27 /////////////////////////////////////////////////////////////////////////////// 28 // char_translate 29 // 30 template<typename Traits, bool ICase> 31 struct char_translate 32 { 33 typedef typename Traits::char_type char_type; 34 Traits const &traits_; 35 char_translateboost::xpressive::detail::char_translate36 explicit char_translate(Traits const &tr) 37 : traits_(tr) 38 {} 39 operator ()boost::xpressive::detail::char_translate40 char_type operator ()(char_type ch1) const 41 { 42 return this->traits_.translate(ch1); 43 } 44 private: 45 char_translate &operator =(char_translate const &); 46 }; 47 48 /////////////////////////////////////////////////////////////////////////////// 49 // char_translate 50 // 51 template<typename Traits> 52 struct char_translate<Traits, true> 53 { 54 typedef typename Traits::char_type char_type; 55 Traits const &traits_; 56 char_translateboost::xpressive::detail::char_translate57 explicit char_translate(Traits const &tr) 58 : traits_(tr) 59 {} 60 operator ()boost::xpressive::detail::char_translate61 char_type operator ()(char_type ch1) const 62 { 63 return this->traits_.translate_nocase(ch1); 64 } 65 private: 66 char_translate &operator =(char_translate const &); 67 }; 68 69 /////////////////////////////////////////////////////////////////////////////// 70 // attr_matcher 71 // Note: the Matcher is a std::map 72 template<typename Matcher, typename Traits, typename ICase> 73 struct attr_matcher 74 : quant_style<quant_none, 0, false> 75 { 76 typedef typename Matcher::value_type::second_type const* result_type; 77 attr_matcherboost::xpressive::detail::attr_matcher78 attr_matcher(int slot, Matcher const &matcher, Traits const& tr) 79 : slot_(slot-1) 80 { 81 char_translate<Traits, ICase::value> trans(tr); 82 this->sym_.load(matcher, trans); 83 } 84 85 template<typename BidiIter, typename Next> matchboost::xpressive::detail::attr_matcher86 bool match(match_state<BidiIter> &state, Next const &next) const 87 { 88 BidiIter tmp = state.cur_; 89 char_translate<Traits, ICase::value> trans(traits_cast<Traits>(state)); 90 result_type const &result = this->sym_(state.cur_, state.end_, trans); 91 if(result) 92 { 93 void const *old_slot = state.attr_context_.attr_slots_[this->slot_]; 94 state.attr_context_.attr_slots_[this->slot_] = &*result; 95 if(next.match(state)) 96 { 97 return true; 98 } 99 state.attr_context_.attr_slots_[this->slot_] = old_slot; 100 } 101 state.cur_ = tmp; 102 return false; 103 } 104 105 int slot_; 106 boost::xpressive::detail::symbols<Matcher> sym_; 107 }; 108 109 }}} 110 111 #endif 112