1/*=============================================================================
2    Copyright (c) 2001-2003 Joel de Guzman
3    Copyright (c) 2001-2003 Daniel Nuffer
4    http://spirit.sourceforge.net/
5
6    Use, modification and distribution is subject to the Boost Software
7    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8    http://www.boost.org/LICENSE_1_0.txt)
9=============================================================================*/
10#ifndef BOOST_SPIRIT_CHSET_IPP
11#define BOOST_SPIRIT_CHSET_IPP
12
13///////////////////////////////////////////////////////////////////////////////
14#include <boost/limits.hpp>
15#include <boost/spirit/home/classic/utility/chset.hpp>
16
17///////////////////////////////////////////////////////////////////////////////
18namespace boost { namespace spirit {
19
20BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
21
22///////////////////////////////////////////////////////////////////////////////
23//
24//  chset class
25//
26///////////////////////////////////////////////////////////////////////////////
27namespace utility { namespace impl {
28    template <typename CharT>
29    inline void
30    detach(boost::shared_ptr<basic_chset<CharT> >& ptr)
31    {
32        if (!ptr.unique())
33            ptr = boost::shared_ptr<basic_chset<CharT> >
34                (new basic_chset<CharT>(*ptr));
35    }
36
37    template <typename CharT>
38    inline void
39    detach_clear(boost::shared_ptr<basic_chset<CharT> >& ptr)
40    {
41        if (ptr.unique())
42            ptr->clear();
43        else
44            ptr.reset(new basic_chset<CharT>());
45    }
46
47    template <typename CharT, typename CharT2>
48    void construct_chset(boost::shared_ptr<basic_chset<CharT> >& ptr,
49            CharT2 const* definition)
50    {
51        CharT2 ch = *definition++;
52        while (ch)
53        {
54            CharT2 next = *definition++;
55            if (next == '-')
56            {
57                next = *definition++;
58                if (next == 0)
59                {
60                    ptr->set(ch);
61                    ptr->set('-');
62                    break;
63                }
64                ptr->set(ch, next);
65            }
66            else
67            {
68                ptr->set(ch);
69            }
70            ch = next;
71        }
72    }
73
74}} // namespace utility::impl
75
76template <typename CharT>
77inline chset<CharT>::chset()
78: ptr(new basic_chset<CharT>()) {}
79
80template <typename CharT>
81inline chset<CharT>::chset(chset const& arg_)
82: ptr(new basic_chset<CharT>(*arg_.ptr)) {}
83
84template <typename CharT>
85inline chset<CharT>::chset(CharT arg_)
86: ptr(new basic_chset<CharT>())
87{ ptr->set(arg_); }
88
89template <typename CharT>
90inline chset<CharT>::chset(anychar_parser /*arg*/)
91: ptr(new basic_chset<CharT>())
92{
93    ptr->set(
94        (std::numeric_limits<CharT>::min)(),
95        (std::numeric_limits<CharT>::max)()
96    );
97}
98
99template <typename CharT>
100inline chset<CharT>::chset(nothing_parser /*arg_*/)
101: ptr(new basic_chset<CharT>()) {}
102
103template <typename CharT>
104inline chset<CharT>::chset(chlit<CharT> const& arg_)
105: ptr(new basic_chset<CharT>())
106{ ptr->set(arg_.ch); }
107
108template <typename CharT>
109inline chset<CharT>::chset(range<CharT> const& arg_)
110: ptr(new basic_chset<CharT>())
111{ ptr->set(arg_.first, arg_.last); }
112
113template <typename CharT>
114inline chset<CharT>::chset(negated_char_parser<chlit<CharT> > const& arg_)
115: ptr(new basic_chset<CharT>())
116{
117    set(arg_);
118}
119
120template <typename CharT>
121inline chset<CharT>::chset(negated_char_parser<range<CharT> > const& arg_)
122: ptr(new basic_chset<CharT>())
123{
124    set(arg_);
125}
126
127template <typename CharT>
128inline chset<CharT>::~chset() {}
129
130template <typename CharT>
131inline chset<CharT>&
132chset<CharT>::operator=(chset const& rhs)
133{
134    ptr = rhs.ptr;
135    return *this;
136}
137
138template <typename CharT>
139inline chset<CharT>&
140chset<CharT>::operator=(CharT rhs)
141{
142    utility::impl::detach_clear(ptr);
143    ptr->set(rhs);
144    return *this;
145}
146
147template <typename CharT>
148inline chset<CharT>&
149chset<CharT>::operator=(anychar_parser /*rhs*/)
150{
151    utility::impl::detach_clear(ptr);
152    ptr->set(
153        (std::numeric_limits<CharT>::min)(),
154        (std::numeric_limits<CharT>::max)()
155    );
156    return *this;
157}
158
159template <typename CharT>
160inline chset<CharT>&
161chset<CharT>::operator=(nothing_parser /*rhs*/)
162{
163    utility::impl::detach_clear(ptr);
164    return *this;
165}
166
167template <typename CharT>
168inline chset<CharT>&
169chset<CharT>::operator=(chlit<CharT> const& rhs)
170{
171    utility::impl::detach_clear(ptr);
172    ptr->set(rhs.ch);
173    return *this;
174}
175
176template <typename CharT>
177inline chset<CharT>&
178chset<CharT>::operator=(range<CharT> const& rhs)
179{
180    utility::impl::detach_clear(ptr);
181    ptr->set(rhs.first, rhs.last);
182    return *this;
183}
184
185template <typename CharT>
186inline chset<CharT>&
187chset<CharT>::operator=(negated_char_parser<chlit<CharT> > const& rhs)
188{
189    utility::impl::detach_clear(ptr);
190    set(rhs);
191    return *this;
192}
193
194template <typename CharT>
195inline chset<CharT>&
196chset<CharT>::operator=(negated_char_parser<range<CharT> > const& rhs)
197{
198    utility::impl::detach_clear(ptr);
199    set(rhs);
200    return *this;
201}
202
203template <typename CharT>
204inline void
205chset<CharT>::set(range<CharT> const& arg_)
206{
207    utility::impl::detach(ptr);
208    ptr->set(arg_.first, arg_.last);
209}
210
211template <typename CharT>
212inline void
213chset<CharT>::set(negated_char_parser<chlit<CharT> > const& arg_)
214{
215    utility::impl::detach(ptr);
216
217    if(arg_.positive.ch != (std::numeric_limits<CharT>::min)()) {
218        ptr->set((std::numeric_limits<CharT>::min)(), arg_.positive.ch - 1);
219    }
220    if(arg_.positive.ch != (std::numeric_limits<CharT>::max)()) {
221        ptr->set(arg_.positive.ch + 1, (std::numeric_limits<CharT>::max)());
222    }
223}
224
225template <typename CharT>
226inline void
227chset<CharT>::set(negated_char_parser<range<CharT> > const& arg_)
228{
229    utility::impl::detach(ptr);
230
231    if(arg_.positive.first != (std::numeric_limits<CharT>::min)()) {
232        ptr->set((std::numeric_limits<CharT>::min)(), arg_.positive.first - 1);
233    }
234    if(arg_.positive.last != (std::numeric_limits<CharT>::max)()) {
235        ptr->set(arg_.positive.last + 1, (std::numeric_limits<CharT>::max)());
236    }
237}
238
239template <typename CharT>
240inline void
241chset<CharT>::clear(range<CharT> const& arg_)
242{
243    utility::impl::detach(ptr);
244    ptr->clear(arg_.first, arg_.last);
245}
246
247template <typename CharT>
248inline void
249chset<CharT>::clear(negated_char_parser<range<CharT> > const& arg_)
250{
251    utility::impl::detach(ptr);
252
253    if(arg_.positive.first != (std::numeric_limits<CharT>::min)()) {
254        ptr->clear((std::numeric_limits<CharT>::min)(), arg_.positive.first - 1);
255    }
256    if(arg_.positive.last != (std::numeric_limits<CharT>::max)()) {
257        ptr->clear(arg_.positive.last + 1, (std::numeric_limits<CharT>::max)());
258    }
259}
260
261template <typename CharT>
262inline bool
263chset<CharT>::test(CharT ch) const
264{ return ptr->test(ch); }
265
266template <typename CharT>
267inline chset<CharT>&
268chset<CharT>::inverse()
269{
270    utility::impl::detach(ptr);
271    ptr->inverse();
272    return *this;
273}
274
275template <typename CharT>
276inline void
277chset<CharT>::swap(chset& x)
278{ ptr.swap(x.ptr); }
279
280template <typename CharT>
281inline chset<CharT>&
282chset<CharT>::operator|=(chset const& x)
283{
284    utility::impl::detach(ptr);
285    *ptr |= *x.ptr;
286    return *this;
287}
288
289template <typename CharT>
290inline chset<CharT>&
291chset<CharT>::operator&=(chset const& x)
292{
293    utility::impl::detach(ptr);
294    *ptr &= *x.ptr;
295    return *this;
296}
297
298template <typename CharT>
299inline chset<CharT>&
300chset<CharT>::operator-=(chset const& x)
301{
302    utility::impl::detach(ptr);
303    *ptr -= *x.ptr;
304    return *this;
305}
306
307template <typename CharT>
308inline chset<CharT>&
309chset<CharT>::operator^=(chset const& x)
310{
311    utility::impl::detach(ptr);
312    *ptr ^= *x.ptr;
313    return *this;
314}
315
316///////////////////////////////////////////////////////////////////////////////
317BOOST_SPIRIT_CLASSIC_NAMESPACE_END
318
319}} // namespace boost::spirit
320
321#endif
322
323