1 /*=============================================================================
2     Copyright (c) 2001-2011 Joel de Guzman
3     Copyright (c) 2001-2009 Daniel Nuffer
4     http://spirit.sourceforge.net/
5 
6   Distributed under the Boost Software License, Version 1.0. (See accompanying
7   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 =============================================================================*/
9 #ifndef BOOST_SPIRIT_BASIC_CHSET_APRIL_17_2008
10 #define BOOST_SPIRIT_BASIC_CHSET_APRIL_17_2008
11 
12 #if defined(_MSC_VER)
13 #pragma once
14 #endif
15 
16 ///////////////////////////////////////////////////////////////////////////////
17 #include <bitset>
18 #include <climits>
19 #include <boost/spirit/home/support/char_set/range_run.hpp>
20 
21 namespace boost { namespace spirit { namespace support { namespace detail
22 {
23     ///////////////////////////////////////////////////////////////////////////
24     //
25     //  basic_chset: basic character set implementation using range_run
26     //
27     ///////////////////////////////////////////////////////////////////////////
28     template <typename Char>
29     struct basic_chset
30     {
basic_chsetboost::spirit::support::detail::basic_chset31         basic_chset() {}
basic_chsetboost::spirit::support::detail::basic_chset32         basic_chset(basic_chset const& arg_)
33           : rr(arg_.rr) {}
34 
35         bool
testboost::spirit::support::detail::basic_chset36         test(Char v) const
37         {
38             return rr.test(v);
39         }
40 
41         void
setboost::spirit::support::detail::basic_chset42         set(Char from, Char to)
43         {
44             rr.set(range<Char>(from, to));
45         }
46 
47         void
setboost::spirit::support::detail::basic_chset48         set(Char c)
49         {
50             rr.set(range<Char>(c, c));
51         }
52 
53         void
clearboost::spirit::support::detail::basic_chset54         clear(Char from, Char to)
55         {
56             rr.clear(range<Char>(from, to));
57         }
58 
59         void
clearboost::spirit::support::detail::basic_chset60         clear(Char c)
61         {
62             rr.clear(range<Char>(c, c));
63         }
64 
65         void
clearboost::spirit::support::detail::basic_chset66         clear()
67         {
68             rr.clear();
69         }
70 
71         void
inverseboost::spirit::support::detail::basic_chset72         inverse()
73         {
74             basic_chset inv;
75             inv.set(
76                 (std::numeric_limits<Char>::min)(),
77                 (std::numeric_limits<Char>::max)()
78             );
79             inv -= *this;
80             swap(inv);
81         }
82 
83         void
swapboost::spirit::support::detail::basic_chset84         swap(basic_chset& x)
85         {
86             rr.swap(x.rr);
87         }
88 
89 
90         basic_chset&
operator |=boost::spirit::support::detail::basic_chset91         operator|=(basic_chset const& x)
92         {
93             typedef typename range_run<Char>::const_iterator const_iterator;
94             for (const_iterator iter = x.rr.begin(); iter != x.rr.end(); ++iter)
95                 rr.set(*iter);
96             return *this;
97         }
98 
99         basic_chset&
operator &=boost::spirit::support::detail::basic_chset100         operator&=(basic_chset const& x)
101         {
102             basic_chset inv;
103             inv.set(
104                 (std::numeric_limits<Char>::min)(),
105                 (std::numeric_limits<Char>::max)()
106             );
107             inv -= x;
108             *this -= inv;
109             return *this;
110         }
111 
112         basic_chset&
operator -=boost::spirit::support::detail::basic_chset113         operator-=(basic_chset const& x)
114         {
115             typedef typename range_run<Char>::const_iterator const_iterator;
116             for (const_iterator iter = x.rr.begin(); iter != x.rr.end(); ++iter)
117                 rr.clear(*iter);
118             return *this;
119         }
120 
121         basic_chset&
operator ^=boost::spirit::support::detail::basic_chset122         operator^=(basic_chset const& x)
123         {
124             basic_chset bma = x;
125             bma -= *this;
126             *this -= x;
127             *this |= bma;
128             return *this;
129         }
130 
131         private: range_run<Char> rr;
132     };
133 
134 #if (CHAR_BIT == 8)
135 
136     ///////////////////////////////////////////////////////////////////////////
137     //
138     //  basic_chset: specializations for 8 bit chars using std::bitset
139     //
140     ///////////////////////////////////////////////////////////////////////////
141     template <typename Char>
142     struct basic_chset_8bit
143     {
basic_chset_8bitboost::spirit::support::detail::basic_chset_8bit144         basic_chset_8bit() {}
basic_chset_8bitboost::spirit::support::detail::basic_chset_8bit145         basic_chset_8bit(basic_chset_8bit const& arg_)
146           : bset(arg_.bset) {}
147 
148         bool
testboost::spirit::support::detail::basic_chset_8bit149         test(Char v) const
150         {
151             return bset.test((unsigned char)v);
152         }
153 
154         void
setboost::spirit::support::detail::basic_chset_8bit155         set(Char from, Char to)
156         {
157             for (int i = from; i <= to; ++i)
158                 bset.set((unsigned char)i);
159         }
160 
161         void
setboost::spirit::support::detail::basic_chset_8bit162         set(Char c)
163         {
164             bset.set((unsigned char)c);
165         }
166 
167         void
clearboost::spirit::support::detail::basic_chset_8bit168         clear(Char from, Char to)
169         {
170             for (int i = from; i <= to; ++i)
171                 bset.reset((unsigned char)i);
172         }
173 
174         void
clearboost::spirit::support::detail::basic_chset_8bit175         clear(Char c)
176         {
177             bset.reset((unsigned char)c);
178         }
179 
180         void
clearboost::spirit::support::detail::basic_chset_8bit181         clear()
182         {
183             bset.reset();
184         }
185 
186         void
inverseboost::spirit::support::detail::basic_chset_8bit187         inverse()
188         {
189             bset.flip();
190         }
191 
192         void
swapboost::spirit::support::detail::basic_chset_8bit193         swap(basic_chset_8bit& x)
194         {
195             std::swap(bset, x.bset);
196         }
197 
198         basic_chset_8bit&
operator |=boost::spirit::support::detail::basic_chset_8bit199         operator|=(basic_chset_8bit const& x)
200         {
201             bset |= x.bset;
202             return *this;
203         }
204 
205         basic_chset_8bit&
operator &=boost::spirit::support::detail::basic_chset_8bit206         operator&=(basic_chset_8bit const& x)
207         {
208             bset &= x.bset;
209             return *this;
210         }
211 
212         basic_chset_8bit&
operator -=boost::spirit::support::detail::basic_chset_8bit213         operator-=(basic_chset_8bit const& x)
214         {
215             bset &= ~x.bset;
216             return *this;
217         }
218 
219         basic_chset_8bit&
operator ^=boost::spirit::support::detail::basic_chset_8bit220         operator^=(basic_chset_8bit const& x)
221         {
222             bset ^= x.bset;
223             return *this;
224         }
225 
226         private: std::bitset<256> bset;
227     };
228 
229     /////////////////////////////////
230     template <>
231     struct basic_chset<char>
232       : basic_chset_8bit<char> {};
233 
234     /////////////////////////////////
235     template <>
236     struct basic_chset<signed char>
237       : basic_chset_8bit<signed char> {};
238 
239     /////////////////////////////////
240     template <>
241     struct basic_chset<unsigned char>
242       : basic_chset_8bit<unsigned char> {};
243 
244 #endif // #if (CHAR_BIT == 8)
245 
246 }}}}
247 
248 #endif
249 
250