1 ///////////////////////////////////////////////////////////////////////////////
2 // set.hpp
3 //
4 //  Copyright 2008 Eric Niebler. Distributed under the Boost
5 //  Software License, Version 1.0. (See accompanying file
6 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 
8 #ifndef BOOST_XPRESSIVE_DETAIL_SET_HPP_EAN_10_04_2005
9 #define BOOST_XPRESSIVE_DETAIL_SET_HPP_EAN_10_04_2005
10 
11 // MS compatible compilers support #pragma once
12 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
13 # pragma once
14 # pragma warning(push)
15 # pragma warning(disable : 4127) // conditional expression constant
16 # pragma warning(disable : 4100) // unreferenced formal parameter
17 # pragma warning(disable : 4351) // vc8 new behavior: elements of array 'foo' will be default initialized
18 #endif
19 
20 #include <algorithm>
21 #include <boost/mpl/assert.hpp>
22 #include <boost/type_traits/same_traits.hpp>
23 #include <boost/xpressive/detail/detail_fwd.hpp>
24 #include <boost/xpressive/detail/core/quant_style.hpp>
25 #include <boost/xpressive/detail/core/state.hpp>
26 
27 namespace boost { namespace xpressive { namespace detail
28 {
29 
30 ///////////////////////////////////////////////////////////////////////////////
31 // set_matcher
32 //
33 template<typename Traits, typename Size>
34 struct set_matcher
35   : quant_style_fixed_width<1>
36 {
37     typedef typename Traits::char_type char_type;
38     char_type set_[ Size::value ];
39     bool not_;
40     bool icase_;
41 
set_matcherboost::xpressive::detail::set_matcher42     set_matcher()
43       : set_()
44       , not_(false)
45       , icase_(false)
46     {
47     }
48 
inverseboost::xpressive::detail::set_matcher49     void inverse()
50     {
51         this->not_ = !this->not_;
52     }
53 
nocaseboost::xpressive::detail::set_matcher54     void nocase(Traits const &traits)
55     {
56         this->icase_ = true;
57 
58         for(int i = 0; i < Size::value; ++i)
59         {
60             this->set_[i] = traits.translate_nocase(this->set_[i]);
61         }
62     }
63 
in_setboost::xpressive::detail::set_matcher64     bool in_set(Traits const &traits, char_type ch) const
65     {
66         char_type const *begin = &this->set_[0], *end = begin + Size::value;
67         ch = this->icase_ ? traits.translate_nocase(ch) : traits.translate(ch);
68         return end != std::find(begin, end, ch);
69     }
70 
71     template<typename BidiIter, typename Next>
matchboost::xpressive::detail::set_matcher72     bool match(match_state<BidiIter> &state, Next const &next) const
73     {
74         if(state.eos() || this->not_ == this->in_set(traits_cast<Traits>(state), *state.cur_))
75         {
76             return false;
77         }
78 
79         if(++state.cur_, next.match(state))
80         {
81             return true;
82         }
83 
84         return --state.cur_, false;
85     }
86 };
87 
88 ///////////////////////////////////////////////////////////////////////////////
89 // set_initializer
90 struct set_initializer
91 {
92 };
93 
94 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
95 # pragma warning(pop)
96 #endif
97 
98 }}} // namespace boost::xpressive::detail
99 
100 #endif
101