Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / xpressive / detail / core / matcher / attr_matcher.hpp
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