1/*=============================================================================
2    Copyright (c) 1998-2003 Joel de Guzman
3    Copyright (c) 2003 Martin Wille
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#if !defined(BOOST_SPIRIT_PRIMITIVES_IPP)
11#define BOOST_SPIRIT_PRIMITIVES_IPP
12
13#include <cctype>
14#if !defined(BOOST_NO_CWCTYPE)
15#include <cwctype>
16#endif
17
18#include <string> // char_traits
19
20#if defined(BOOST_MSVC)
21#  pragma warning (push)
22#  pragma warning(disable:4800)
23#endif
24
25namespace boost { namespace spirit {
26
27BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
28
29    template <typename DrivedT> struct char_parser;
30
31    namespace impl
32    {
33        template <typename IteratorT>
34        inline IteratorT
35        get_last(IteratorT first)
36        {
37            while (*first)
38                first++;
39            return first;
40        }
41
42        template<
43            typename RT,
44            typename IteratorT,
45            typename ScannerT>
46        inline RT
47        string_parser_parse(
48            IteratorT str_first,
49            IteratorT str_last,
50            ScannerT& scan)
51        {
52            typedef typename ScannerT::iterator_t iterator_t;
53            iterator_t saved = scan.first;
54            std::size_t slen = str_last - str_first;
55
56            while (str_first != str_last)
57            {
58                if (scan.at_end() || (*str_first != *scan))
59                    return scan.no_match();
60                ++str_first;
61                ++scan;
62            }
63
64            return scan.create_match(slen, nil_t(), saved, scan.first);
65        }
66
67    ///////////////////////////////////////////////////////////////////////////
68    //
69    // Conversion from char_type to int_type
70    //
71    ///////////////////////////////////////////////////////////////////////////
72
73        //  Use char_traits for char and wchar_t only, as these are the only
74        //  specializations provided in the standard. Other types are on their
75        //  own.
76        //
77        //  For UDT, one may override:
78        //
79        //      isalnum
80        //      isalpha
81        //      iscntrl
82        //      isdigit
83        //      isgraph
84        //      islower
85        //      isprint
86        //      ispunct
87        //      isspace
88        //      isupper
89        //      isxdigit
90        //      isblank
91        //      isupper
92        //      tolower
93        //      toupper
94        //
95        //  in a namespace suitable for Argument Dependent lookup or in
96        //  namespace std (disallowed by the standard).
97
98        template <typename CharT>
99        struct char_type_char_traits_helper
100        {
101            typedef CharT char_type;
102            typedef typename std::char_traits<CharT>::int_type int_type;
103
104            static int_type to_int_type(CharT c)
105            {
106                return std::char_traits<CharT>::to_int_type(c);
107            }
108
109            static char_type to_char_type(int_type i)
110            {
111                return std::char_traits<CharT>::to_char_type(i);
112            }
113        };
114
115        template <typename CharT>
116        struct char_traits_helper
117        {
118            typedef CharT char_type;
119            typedef CharT int_type;
120
121            static CharT & to_int_type(CharT & c)
122            {
123                return c;
124            }
125
126            static CharT & to_char_type(CharT & c)
127            {
128                return c;
129            }
130        };
131
132        template <>
133        struct char_traits_helper<char>
134            : char_type_char_traits_helper<char>
135        {
136        };
137
138#if !defined(BOOST_NO_CWCTYPE)
139
140        template <>
141        struct char_traits_helper<wchar_t>
142            : char_type_char_traits_helper<wchar_t>
143        {
144        };
145
146#endif
147
148        template <typename CharT>
149        inline typename char_traits_helper<CharT>::int_type
150        to_int_type(CharT c)
151        {
152            return char_traits_helper<CharT>::to_int_type(c);
153        }
154
155        template <typename CharT>
156        inline CharT
157        to_char_type(typename char_traits_helper<CharT>::int_type c)
158        {
159            return char_traits_helper<CharT>::to_char_type(c);
160        }
161
162        ///////////////////////////////////////////////////////////////////////
163        //
164        //  Convenience functions
165        //
166        ///////////////////////////////////////////////////////////////////////
167
168        template <typename CharT>
169        inline bool
170        isalnum_(CharT c)
171        {
172            using namespace std;
173            return isalnum(to_int_type(c)) ? true : false;
174        }
175
176        template <typename CharT>
177        inline bool
178        isalpha_(CharT c)
179        {
180            using namespace std;
181            return isalpha(to_int_type(c)) ? true : false;
182        }
183
184        template <typename CharT>
185        inline bool
186        iscntrl_(CharT c)
187        {
188            using namespace std;
189            return iscntrl(to_int_type(c)) ? true : false;
190        }
191
192        template <typename CharT>
193        inline bool
194        isdigit_(CharT c)
195        {
196            using namespace std;
197            return isdigit(to_int_type(c)) ? true : false;
198        }
199
200        template <typename CharT>
201        inline bool
202        isgraph_(CharT c)
203        {
204            using namespace std;
205            return isgraph(to_int_type(c)) ? true : false;
206        }
207
208        template <typename CharT>
209        inline bool
210        islower_(CharT c)
211        {
212            using namespace std;
213            return islower(to_int_type(c)) ? true : false;
214        }
215
216        template <typename CharT>
217        inline bool
218        isprint_(CharT c)
219        {
220            using namespace std;
221            return isprint(to_int_type(c)) ? true : false;
222        }
223
224        template <typename CharT>
225        inline bool
226        ispunct_(CharT c)
227        {
228            using namespace std;
229            return ispunct(to_int_type(c)) ? true : false;
230        }
231
232        template <typename CharT>
233        inline bool
234        isspace_(CharT c)
235        {
236            using namespace std;
237            return isspace(to_int_type(c)) ? true : false;
238        }
239
240        template <typename CharT>
241        inline bool
242        isupper_(CharT c)
243        {
244            using namespace std;
245            return isupper(to_int_type(c)) ? true : false;
246        }
247
248        template <typename CharT>
249        inline bool
250        isxdigit_(CharT c)
251        {
252            using namespace std;
253            return isxdigit(to_int_type(c)) ? true : false;
254        }
255
256        template <typename CharT>
257        inline bool
258        isblank_(CharT c)
259        {
260            return (c == ' ' || c == '\t');
261        }
262
263        template <typename CharT>
264        inline CharT
265        tolower_(CharT c)
266        {
267            using namespace std;
268            return to_char_type<CharT>(tolower(to_int_type(c)));
269        }
270
271        template <typename CharT>
272        inline CharT
273        toupper_(CharT c)
274        {
275            using namespace std;
276            return to_char_type<CharT>(toupper(to_int_type(c)));
277        }
278
279#if !defined(BOOST_NO_CWCTYPE)
280
281        inline bool
282        isalnum_(wchar_t c)
283        {
284            using namespace std;
285            return iswalnum(to_int_type(c)) ? true : false;
286        }
287
288        inline bool
289        isalpha_(wchar_t c)
290        {
291            using namespace std;
292            return iswalpha(to_int_type(c)) ? true : false;
293        }
294
295        inline bool
296        iscntrl_(wchar_t c)
297        {
298            using namespace std;
299            return iswcntrl(to_int_type(c)) ? true : false;
300        }
301
302        inline bool
303        isdigit_(wchar_t c)
304        {
305            using namespace std;
306            return iswdigit(to_int_type(c)) ? true : false;
307        }
308
309        inline bool
310        isgraph_(wchar_t c)
311        {
312            using namespace std;
313            return iswgraph(to_int_type(c)) ? true : false;
314        }
315
316        inline bool
317        islower_(wchar_t c)
318        {
319            using namespace std;
320            return iswlower(to_int_type(c)) ? true : false;
321        }
322
323        inline bool
324        isprint_(wchar_t c)
325        {
326            using namespace std;
327            return iswprint(to_int_type(c)) ? true : false;
328        }
329
330        inline bool
331        ispunct_(wchar_t c)
332        {
333            using namespace std;
334            return iswpunct(to_int_type(c)) ? true : false;
335        }
336
337        inline bool
338        isspace_(wchar_t c)
339        {
340            using namespace std;
341            return iswspace(to_int_type(c)) ? true : false;
342        }
343
344        inline bool
345        isupper_(wchar_t c)
346        {
347            using namespace std;
348            return iswupper(to_int_type(c)) ? true : false;
349        }
350
351        inline bool
352        isxdigit_(wchar_t c)
353        {
354            using namespace std;
355            return iswxdigit(to_int_type(c)) ? true : false;
356        }
357
358        inline bool
359        isblank_(wchar_t c)
360        {
361            return (c == L' ' || c == L'\t');
362        }
363
364        inline wchar_t
365        tolower_(wchar_t c)
366        {
367            using namespace std;
368            return to_char_type<wchar_t>(towlower(to_int_type(c)));
369        }
370
371        inline wchar_t
372        toupper_(wchar_t c)
373        {
374            using namespace std;
375            return to_char_type<wchar_t>(towupper(to_int_type(c)));
376        }
377
378        inline bool
379        isblank_(bool)
380        {
381            return false;
382        }
383
384#endif // !defined(BOOST_NO_CWCTYPE)
385
386}
387
388BOOST_SPIRIT_CLASSIC_NAMESPACE_END
389
390}} // namespace boost::spirit::impl
391
392#ifdef BOOST_MSVC
393#pragma warning (pop)
394#endif
395
396#endif
397