9
9
10
10
namespace fly {
11
11
12
+ template <typename CharType>
13
+ class BasicLexer ;
14
+
15
+ using Lexer = BasicLexer<char >;
16
+ using WLexer = BasicLexer<wchar_t >;
17
+ using Lexer8 = BasicLexer<char8_t >;
18
+ using Lexer16 = BasicLexer<char16_t >;
19
+ using Lexer32 = BasicLexer<char32_t >;
20
+
12
21
/* *
13
22
* Helper class to perform lexical analysis of a C-string literal. All methods are constant
14
23
* expressions, allowing for string analysis at compile time.
15
24
*
16
25
* @author Timothy Flynn ([email protected] )
17
26
* @version January 3, 2021
18
27
*/
19
- template <typename StringType >
20
- class BasicStringLexer
28
+ template <typename CharType >
29
+ class BasicLexer
21
30
{
22
- using traits = detail::BasicStringTraits<StringType>;
23
- using classifier = detail::BasicStringClassifier<StringType>;
24
- using char_type = typename traits::char_type;
31
+ using string_type = std::basic_string<CharType>;
32
+
33
+ using traits = detail::BasicStringTraits<string_type>;
34
+ using classifier = detail::BasicStringClassifier<string_type>;
25
35
using view_type = typename traits::view_type;
26
36
27
37
public:
@@ -33,14 +43,14 @@ class BasicStringLexer
33
43
* @param literals Reference to a C-string literal of size N.
34
44
*/
35
45
template <std::size_t N>
36
- constexpr explicit BasicStringLexer (const char_type (&literals)[N]) noexcept ;
46
+ constexpr explicit BasicLexer (const CharType (&literals)[N]) noexcept ;
37
47
38
48
/* *
39
49
* Constructor. Stores an existing view into a string.
40
50
*
41
51
* @param view The existing view into the string.
42
52
*/
43
- constexpr explicit BasicStringLexer (view_type view) noexcept ;
53
+ constexpr explicit BasicLexer (view_type view) noexcept ;
44
54
45
55
/* *
46
56
* @return A string view into the C-string literal.
@@ -61,15 +71,15 @@ class BasicStringLexer
61
71
* @return If available, the character at the provided offset. Otherwise, an uninitialized
62
72
* value.
63
73
*/
64
- constexpr std::optional<char_type > peek (std::size_t offset = 0 );
74
+ constexpr std::optional<CharType > peek (std::size_t offset = 0 );
65
75
66
76
/* *
67
77
* If a character is available at the current position in the C-string literal, return that
68
78
* character and advance the current position to the next character.
69
79
*
70
80
* @return If available, the current character. Otherwise, an uninitialized value.
71
81
*/
72
- constexpr std::optional<char_type > consume ();
82
+ constexpr std::optional<CharType > consume ();
73
83
74
84
/* *
75
85
* If a character is available at the current position in the C-string literal, and if that
@@ -80,7 +90,7 @@ class BasicStringLexer
80
90
*
81
91
* @return Whether the current character was available and matched the provided character.
82
92
*/
83
- constexpr bool consume_if (char_type ch);
93
+ constexpr bool consume_if (CharType ch);
84
94
85
95
/* *
86
96
* Beginning with the current position, retrieve characters from the C-string literal and
@@ -113,13 +123,13 @@ class BasicStringLexer
113
123
* @return Whether the current character was available and satisfied the provided condition.
114
124
*/
115
125
template <typename Condition>
116
- constexpr std::optional<char_type > consume_if (Condition condition);
126
+ constexpr std::optional<CharType > consume_if (Condition condition);
117
127
118
- static constexpr const auto s_zero = FLY_CHR(char_type , ' 0' );
119
- static constexpr const auto s_upper_a = FLY_CHR(char_type , ' A' );
120
- static constexpr const auto s_upper_f = FLY_CHR(char_type , ' F' );
121
- static constexpr const auto s_lower_a = FLY_CHR(char_type , ' a' );
122
- static constexpr const auto s_lower_f = FLY_CHR(char_type , ' f' );
128
+ static constexpr const auto s_zero = FLY_CHR(CharType , ' 0' );
129
+ static constexpr const auto s_upper_a = FLY_CHR(CharType , ' A' );
130
+ static constexpr const auto s_upper_f = FLY_CHR(CharType , ' F' );
131
+ static constexpr const auto s_lower_a = FLY_CHR(CharType , ' a' );
132
+ static constexpr const auto s_lower_f = FLY_CHR(CharType , ' f' );
123
133
124
134
const std::size_t m_size;
125
135
const view_type m_view;
@@ -128,39 +138,39 @@ class BasicStringLexer
128
138
};
129
139
130
140
// ==================================================================================================
131
- template <typename StringType >
141
+ template <typename CharType >
132
142
template <std::size_t N>
133
- constexpr BasicStringLexer<StringType >::BasicStringLexer (const char_type (&literals)[N]) noexcept :
143
+ constexpr BasicLexer<CharType >::BasicLexer (const CharType (&literals)[N]) noexcept :
134
144
m_size(classifier::size(literals)),
135
145
m_view(literals, m_size)
136
146
{
137
147
}
138
148
139
149
// ==================================================================================================
140
- template <typename StringType >
141
- constexpr BasicStringLexer<StringType >::BasicStringLexer (view_type view) noexcept :
150
+ template <typename CharType >
151
+ constexpr BasicLexer<CharType >::BasicLexer (view_type view) noexcept :
142
152
m_size (view.size()),
143
153
m_view(std::move(view))
144
154
{
145
155
}
146
156
147
157
// ==================================================================================================
148
- template <typename StringType >
149
- constexpr auto BasicStringLexer<StringType >::view() const -> view_type
158
+ template <typename CharType >
159
+ constexpr auto BasicLexer<CharType >::view() const -> view_type
150
160
{
151
161
return m_view;
152
162
}
153
163
154
164
// ==================================================================================================
155
- template <typename StringType >
156
- constexpr std::size_t BasicStringLexer<StringType >::position() const
165
+ template <typename CharType >
166
+ constexpr std::size_t BasicLexer<CharType >::position() const
157
167
{
158
168
return m_index;
159
169
}
160
170
161
171
// ==================================================================================================
162
- template <typename StringType >
163
- constexpr auto BasicStringLexer<StringType >::peek(std::size_t offset) -> std::optional<char_type>
172
+ template <typename CharType >
173
+ constexpr std::optional<CharType> BasicLexer<CharType >::peek(std::size_t offset)
164
174
{
165
175
if ((m_index + offset) >= m_size)
166
176
{
@@ -171,8 +181,8 @@ constexpr auto BasicStringLexer<StringType>::peek(std::size_t offset) -> std::op
171
181
}
172
182
173
183
// ==================================================================================================
174
- template <typename StringType >
175
- constexpr auto BasicStringLexer<StringType >::consume() -> std::optional<char_type>
184
+ template <typename CharType >
185
+ constexpr std::optional<CharType> BasicLexer<CharType >::consume()
176
186
{
177
187
if (m_index >= m_size)
178
188
{
@@ -183,8 +193,8 @@ constexpr auto BasicStringLexer<StringType>::consume() -> std::optional<char_typ
183
193
}
184
194
185
195
// ==================================================================================================
186
- template <typename StringType >
187
- constexpr bool BasicStringLexer<StringType >::consume_if(char_type ch)
196
+ template <typename CharType >
197
+ constexpr bool BasicLexer<CharType >::consume_if(CharType ch)
188
198
{
189
199
if (auto next = peek (); next && (next.value () == ch))
190
200
{
@@ -196,8 +206,8 @@ constexpr bool BasicStringLexer<StringType>::consume_if(char_type ch)
196
206
}
197
207
198
208
// ==================================================================================================
199
- template <typename StringType >
200
- constexpr std::optional<std::uintmax_t > BasicStringLexer<StringType >::consume_number()
209
+ template <typename CharType >
210
+ constexpr std::optional<std::uintmax_t > BasicLexer<CharType >::consume_number()
201
211
{
202
212
bool parsed_number = false ;
203
213
std::uintmax_t number = 0 ;
@@ -214,8 +224,8 @@ constexpr std::optional<std::uintmax_t> BasicStringLexer<StringType>::consume_nu
214
224
}
215
225
216
226
// ==================================================================================================
217
- template <typename StringType >
218
- constexpr std::optional<std::uintmax_t > BasicStringLexer<StringType >::consume_hex_number()
227
+ template <typename CharType >
228
+ constexpr std::optional<std::uintmax_t > BasicLexer<CharType >::consume_hex_number()
219
229
{
220
230
bool parsed_number = false ;
221
231
std::uintmax_t number = 0 ;
@@ -243,10 +253,9 @@ constexpr std::optional<std::uintmax_t> BasicStringLexer<StringType>::consume_he
243
253
}
244
254
245
255
// ==================================================================================================
246
- template <typename StringType >
256
+ template <typename CharType >
247
257
template <typename Condition>
248
- constexpr auto BasicStringLexer<StringType>::consume_if(Condition condition)
249
- -> std::optional<char_type>
258
+ constexpr std::optional<CharType> BasicLexer<CharType>::consume_if(Condition condition)
250
259
{
251
260
if (auto next = peek (); next && condition (next.value ()))
252
261
{
0 commit comments