]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
36 | explicit char_translate(Traits const &tr) | |
37 | : traits_(tr) | |
38 | {} | |
39 | ||
40 | 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 | ||
57 | explicit char_translate(Traits const &tr) | |
58 | : traits_(tr) | |
59 | {} | |
60 | ||
61 | 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 | ||
78 | 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> | |
86 | 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 |