1 /*=============================================================================
2     Copyright (c) 2001-2011 Hartmut Kaiser
3     Copyright (c) 2001-2011 Joel de Guzman
4 
5     Distributed under the Boost Software License, Version 1.0. (See accompanying
6     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 =============================================================================*/
8 #if !defined(BOOST_SPIRIT_STANDARD_WIDE_NOVEMBER_10_2006_0913AM)
9 #define BOOST_SPIRIT_STANDARD_WIDE_NOVEMBER_10_2006_0913AM
10 
11 #if defined(_MSC_VER)
12 #pragma once
13 #endif
14 
15 #include <cwctype>
16 #include <string>
17 
18 #include <boost/assert.hpp>
19 #include <boost/cstdint.hpp>
20 #include <boost/spirit/home/support/assert_msg.hpp>
21 
22 #include <boost/type_traits/make_unsigned.hpp>
23 
24 namespace boost { namespace spirit { namespace traits
25 {
26     template <std::size_t N>
27     struct wchar_t_size
28     {
29         BOOST_SPIRIT_ASSERT_MSG(N == 1 || N == 2 || N == 4,
30             not_supported_size_of_wchar_t, ());
31     };
32 
33     template <> struct wchar_t_size<1> { enum { mask = 0xff }; };
34     template <> struct wchar_t_size<2> { enum { mask = 0xffff }; };
35     template <> struct wchar_t_size<4> { enum { mask = 0xffffffff }; };
36 
37 }}}
38 
39 namespace boost { namespace spirit { namespace char_encoding
40 {
41     ///////////////////////////////////////////////////////////////////////////
42     //  Test characters for specified conditions (using std wchar_t functions)
43     ///////////////////////////////////////////////////////////////////////////
44 
45     struct standard_wide
46     {
47         typedef wchar_t char_type;
48         typedef wchar_t classify_type;
49 
50         template <typename Char>
51         static typename std::char_traits<Char>::int_type
to_int_typeboost::spirit::char_encoding::standard_wide52         to_int_type(Char ch)
53         {
54             return std::char_traits<Char>::to_int_type(ch);
55         }
56 
57         template <typename Char>
58         static Char
to_char_typeboost::spirit::char_encoding::standard_wide59         to_char_type(typename std::char_traits<Char>::int_type ch)
60         {
61             return std::char_traits<Char>::to_char_type(ch);
62         }
63 
64         static bool
ischarboost::spirit::char_encoding::standard_wide65         ischar(int ch)
66         {
67             // we have to watch out for sign extensions (casting is there to
68             // silence certain compilers complaining about signed/unsigned
69             // mismatch)
70             return (
71                 std::size_t(0) ==
72                     std::size_t(ch & ~traits::wchar_t_size<sizeof(wchar_t)>::mask) ||
73                 std::size_t(~0) ==
74                     std::size_t(ch | traits::wchar_t_size<sizeof(wchar_t)>::mask)
75             ) != 0;     // any wchar_t, but no other bits set
76         }
77 
78         static bool
isalnumboost::spirit::char_encoding::standard_wide79         isalnum(wchar_t ch)
80         {
81             using namespace std;
82             return iswalnum(to_int_type(ch)) != 0;
83         }
84 
85         static bool
isalphaboost::spirit::char_encoding::standard_wide86         isalpha(wchar_t ch)
87         {
88             using namespace std;
89             return iswalpha(to_int_type(ch)) != 0;
90         }
91 
92         static bool
iscntrlboost::spirit::char_encoding::standard_wide93         iscntrl(wchar_t ch)
94         {
95             using namespace std;
96             return iswcntrl(to_int_type(ch)) != 0;
97         }
98 
99         static bool
isdigitboost::spirit::char_encoding::standard_wide100         isdigit(wchar_t ch)
101         {
102             using namespace std;
103             return iswdigit(to_int_type(ch)) != 0;
104         }
105 
106         static bool
isgraphboost::spirit::char_encoding::standard_wide107         isgraph(wchar_t ch)
108         {
109             using namespace std;
110             return iswgraph(to_int_type(ch)) != 0;
111         }
112 
113         static bool
islowerboost::spirit::char_encoding::standard_wide114         islower(wchar_t ch)
115         {
116             using namespace std;
117             return iswlower(to_int_type(ch)) != 0;
118         }
119 
120         static bool
isprintboost::spirit::char_encoding::standard_wide121         isprint(wchar_t ch)
122         {
123             using namespace std;
124             return iswprint(to_int_type(ch)) != 0;
125         }
126 
127         static bool
ispunctboost::spirit::char_encoding::standard_wide128         ispunct(wchar_t ch)
129         {
130             using namespace std;
131             return iswpunct(to_int_type(ch)) != 0;
132         }
133 
134         static bool
isspaceboost::spirit::char_encoding::standard_wide135         isspace(wchar_t ch)
136         {
137             using namespace std;
138             return iswspace(to_int_type(ch)) != 0;
139         }
140 
141         static bool
isupperboost::spirit::char_encoding::standard_wide142         isupper(wchar_t ch)
143         {
144             using namespace std;
145             return iswupper(to_int_type(ch)) != 0;
146         }
147 
148         static bool
isxdigitboost::spirit::char_encoding::standard_wide149         isxdigit(wchar_t ch)
150         {
151             using namespace std;
152             return iswxdigit(to_int_type(ch)) != 0;
153         }
154 
155         static bool
BOOST_PREVENT_MACRO_SUBSTITUTIONboost::spirit::char_encoding::standard_wide156         isblank BOOST_PREVENT_MACRO_SUBSTITUTION (wchar_t ch)
157         {
158             return (ch == L' ' || ch == L'\t');
159         }
160 
161         ///////////////////////////////////////////////////////////////////////
162         //  Simple character conversions
163         ///////////////////////////////////////////////////////////////////////
164 
165         static wchar_t
tolowerboost::spirit::char_encoding::standard_wide166         tolower(wchar_t ch)
167         {
168             using namespace std;
169             return isupper(ch) ?
170                 to_char_type<wchar_t>(towlower(to_int_type(ch))) : ch;
171         }
172 
173         static wchar_t
toupperboost::spirit::char_encoding::standard_wide174         toupper(wchar_t ch)
175         {
176             using namespace std;
177             return islower(ch) ?
178                 to_char_type<wchar_t>(towupper(to_int_type(ch))) : ch;
179         }
180 
181         static ::boost::uint32_t
toucs4boost::spirit::char_encoding::standard_wide182         toucs4(wchar_t ch)
183         {
184             return static_cast<make_unsigned<wchar_t>::type>(ch);
185         }
186     };
187 }}}
188 
189 #endif
190