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
24namespace 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
39namespace 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
52 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
59 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
65 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
79 isalnum(wchar_t ch)
80 {
81 using namespace std;
82 return iswalnum(wc: to_int_type(ch)) != 0;
83 }
84
85 static bool
86 isalpha(wchar_t ch)
87 {
88 using namespace std;
89 return iswalpha(wc: to_int_type(ch)) != 0;
90 }
91
92 static bool
93 iscntrl(wchar_t ch)
94 {
95 using namespace std;
96 return iswcntrl(wc: to_int_type(ch)) != 0;
97 }
98
99 static bool
100 isdigit(wchar_t ch)
101 {
102 using namespace std;
103 return iswdigit(wc: to_int_type(ch)) != 0;
104 }
105
106 static bool
107 isgraph(wchar_t ch)
108 {
109 using namespace std;
110 return iswgraph(wc: to_int_type(ch)) != 0;
111 }
112
113 static bool
114 islower(wchar_t ch)
115 {
116 using namespace std;
117 return iswlower(wc: to_int_type(ch)) != 0;
118 }
119
120 static bool
121 isprint(wchar_t ch)
122 {
123 using namespace std;
124 return iswprint(wc: to_int_type(ch)) != 0;
125 }
126
127 static bool
128 ispunct(wchar_t ch)
129 {
130 using namespace std;
131 return iswpunct(wc: to_int_type(ch)) != 0;
132 }
133
134 static bool
135 isspace(wchar_t ch)
136 {
137 using namespace std;
138 return iswspace(wc: to_int_type(ch)) != 0;
139 }
140
141 static bool
142 isupper(wchar_t ch)
143 {
144 using namespace std;
145 return iswupper(wc: to_int_type(ch)) != 0;
146 }
147
148 static bool
149 isxdigit(wchar_t ch)
150 {
151 using namespace std;
152 return iswxdigit(wc: to_int_type(ch)) != 0;
153 }
154
155 static bool
156 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
166 tolower(wchar_t ch)
167 {
168 using namespace std;
169 return isupper(ch) ?
170 to_char_type<wchar_t>(ch: towlower(wc: to_int_type(ch))) : ch;
171 }
172
173 static wchar_t
174 toupper(wchar_t ch)
175 {
176 using namespace std;
177 return islower(ch) ?
178 to_char_type<wchar_t>(ch: towupper(wc: to_int_type(ch))) : ch;
179 }
180
181 static ::boost::uint32_t
182 toucs4(wchar_t ch)
183 {
184 return static_cast<make_unsigned<wchar_t>::type>(ch);
185 }
186 };
187}}}
188
189#endif
190