@@ -61,6 +61,34 @@ class BasicStringClassifier
61
61
*/
62
62
static constexpr bool is_lower(char_type ch);
63
63
64
+ /**
65
+ * Converts the given character to an upper-case alphabetic character as classified by the
66
+ * default C locale.
67
+ *
68
+ * The STL's std:tosupper and std::towupper require that the provided character fits into an
69
+ * unsigned char and unsigned wchar_t, respectively. Other values result in undefined behavior.
70
+ * This method has no such restriction.
71
+ *
72
+ * @param ch The character to convert.
73
+ *
74
+ * @return The converted character.
75
+ */
76
+ static constexpr char_type to_upper(char_type ch);
77
+
78
+ /**
79
+ * Converts the given character to a lower-case alphabetic character as classified by the
80
+ * default C locale.
81
+ *
82
+ * The STL's std:toslower and std::towlower require that the provided character fits into an
83
+ * unsigned char and unsigned wchar_t, respectively. Other values result in undefined behavior.
84
+ * This method has no such restriction.
85
+ *
86
+ * @param ch The character to convert.
87
+ *
88
+ * @return The converted character.
89
+ */
90
+ static constexpr char_type to_lower(char_type ch);
91
+
64
92
/**
65
93
* Checks if the given character is a decimal digit character.
66
94
*
@@ -105,7 +133,8 @@ class BasicStringClassifier
105
133
static constexpr const char_type s_lower_a = FLY_CHR(char_type, 'a');
106
134
static constexpr const char_type s_lower_z = FLY_CHR(char_type, 'z');
107
135
108
- static constexpr const int_type s_case_mask = static_cast<int_type>(~0x20);
136
+ static constexpr const int_type s_case_bit = static_cast<int_type>(0x20);
137
+ static constexpr const int_type s_case_mask = static_cast<int_type>(~s_case_bit);
109
138
};
110
139
111
140
//==================================================================================================
@@ -129,6 +158,30 @@ constexpr inline bool BasicStringClassifier<StringType>::is_lower(char_type ch)
129
158
return (ch >= s_lower_a) && (ch <= s_lower_z);
130
159
}
131
160
161
+ //==================================================================================================
162
+ template <typename StringType>
163
+ constexpr inline auto BasicStringClassifier<StringType>::to_upper(char_type ch) -> char_type
164
+ {
165
+ if (is_lower(ch))
166
+ {
167
+ ch = static_cast<char_type>(static_cast<int_type>(ch) & s_case_mask);
168
+ }
169
+
170
+ return ch;
171
+ }
172
+
173
+ //==================================================================================================
174
+ template <typename StringType>
175
+ constexpr inline auto BasicStringClassifier<StringType>::to_lower(char_type ch) -> char_type
176
+ {
177
+ if (is_upper(ch))
178
+ {
179
+ ch = static_cast<char_type>(static_cast<int_type>(ch) | s_case_bit);
180
+ }
181
+
182
+ return ch;
183
+ }
184
+
132
185
//==================================================================================================
133
186
template <typename StringType>
134
187
constexpr inline bool BasicStringClassifier<StringType>::is_digit(char_type ch)
0 commit comments