| 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 |
| 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 | |