@@ -208,11 +208,185 @@ struct TypeInfoCommonBase : TypeInfo
208
208
}
209
209
};
210
210
211
+ /* * Categorically describes a fundamental type.
212
+
213
+ @see https://en.cppreference.com/w/cpp/language/types
214
+ */
215
+ enum class FundamentalTypeKind
216
+ {
217
+ // void
218
+ Void,
219
+ // std::nullptr_t
220
+ Nullptr,
221
+ // bool
222
+ Bool,
223
+ // char
224
+ Char,
225
+ // signed char
226
+ SignedChar,
227
+ // unsigned char
228
+ UnsignedChar,
229
+ // char8_t
230
+ Char8,
231
+ // char16_t
232
+ Char16,
233
+ // char32_t
234
+ Char32,
235
+ // wchar_t
236
+ WChar,
237
+ // short / short int / signed short / signed short int
238
+ Short,
239
+ // unsigned short / unsigned short int
240
+ UnsignedShort,
241
+ // int / signed / signed int
242
+ Int,
243
+ // unsigned / unsigned int
244
+ UnsignedInt,
245
+ // long / long int / signed long / signed long int
246
+ Long,
247
+ // unsigned long / unsigned long int
248
+ UnsignedLong,
249
+ // long long / long long int / signed long long / signed long long int
250
+ LongLong,
251
+ // unsigned long long / unsigned long long int
252
+ UnsignedLongLong,
253
+ // float
254
+ Float,
255
+ // double
256
+ Double,
257
+ // long double
258
+ LongDouble
259
+ };
260
+
261
+ /* * Convert a FundamentalTypeKind to a string.
262
+
263
+ This function converts a FundamentalTypeKind to
264
+ the shortest canonical string representing the type.
265
+
266
+ @return The string representation of the kind
267
+ */
268
+ MRDOCS_DECL
269
+ std::string_view
270
+ toString (FundamentalTypeKind kind) noexcept ;
271
+
272
+ /* * Convert a string to a FundamentalTypeKind.
273
+
274
+ This function converts a string to a FundamentalTypeKind.
275
+
276
+ All variations of the type specifiers are supported.
277
+
278
+ However, the "long long" specifier cannot be split
279
+ into two separate specifiers.
280
+
281
+ @return true if the string was successfully converted
282
+ */
283
+ MRDOCS_DECL
284
+ bool
285
+ fromString (std::string_view str, FundamentalTypeKind& kind) noexcept ;
286
+
287
+ /* * Apply the "long" specifier to the type
288
+
289
+ If applying "long" the specifier is a valid operation
290
+ the function changes the type and returns true.
291
+
292
+ For instance, applying "long" to
293
+ `FundamentalTypeKind::Int` ("int") results in
294
+ `FundamentalTypeKind::Long` ("long int").
295
+
296
+ @param[in/out] kind The type to modify
297
+ @return Whether the operation was successful
298
+ */
299
+ MRDOCS_DECL
300
+ bool
301
+ makeLong (FundamentalTypeKind& kind) noexcept ;
302
+
303
+ /* * Apply the "short" specifier to the type
304
+
305
+ If applying "short" the specifier is a valid operation
306
+ the function changes the type and returns true.
307
+
308
+ For instance, applying "short" to
309
+ `FundamentalTypeKind::Int` ("int") results in
310
+ `FundamentalTypeKind::Short` ("short int").
311
+
312
+ @param[in/out] kind The type to modify
313
+ @return Whether the operation was successful
314
+ */
315
+ MRDOCS_DECL
316
+ bool
317
+ makeShort (FundamentalTypeKind& kind) noexcept ;
318
+
319
+ /* * Apply the "signed" specifier to the type
320
+
321
+ If applying the "signed" specifier is a valid operation
322
+ the function changes the type and returns true.
323
+
324
+ For instance, applying "signed" to
325
+ `FundamentalTypeKind::Char` ("char") results in
326
+ `FundamentalTypeKind::SignedChar` ("signed char").
327
+
328
+ It also returns true if applying the "signed" specifier
329
+ is a valid operation but doesn't affect the
330
+ type.
331
+
332
+ For instance, applying "signed" to
333
+ `FundamentalTypeKind::Int` ("int") doesn't change the type
334
+ but returns `true`, even though `FundamentalTypeKind::Int`
335
+ could be declared as "int" or "signed" and multiple
336
+ "signed" specifiers are not allowed.
337
+
338
+ @param[in/out] kind The type to modify
339
+ @return Whether the operation was successful
340
+ */
341
+ MRDOCS_DECL
342
+ bool
343
+ makeSigned (FundamentalTypeKind& kind) noexcept ;
344
+
345
+ /* * Apply the "unsigned" specifier to the type
346
+
347
+ If applying the "unsigned" specifier is a valid operation
348
+ the function changes the type and returns true.
349
+
350
+ For instance, applying "unsigned" to
351
+ `FundamentalTypeKind::Char` ("char") results in
352
+ `FundamentalTypeKind::UnsignedChar` ("unsigned char")
353
+ and applying "unsigned" to
354
+ `FundamentalTypeKind::Int` ("int") results in
355
+ `FundamentalTypeKind::UnsignedInt` ("unsigned int").
356
+
357
+ @param[in/out] kind The type to modify
358
+ @return Whether the operation was successful
359
+ */
360
+ MRDOCS_DECL
361
+ bool
362
+ makeUnsigned (FundamentalTypeKind& kind) noexcept ;
363
+
364
+ /* * Apply the "char" specifier to the type
365
+
366
+ If applying the "char" specifier to a type
367
+ that might have been declared only with "signed/unsigned"
368
+ or "short/long" specifiers, the function changes the type
369
+ and returns true.
370
+
371
+ For instance, applying "char" to
372
+ `FundamentalTypeKind::Int` ("int", which could be declared
373
+ as "signed") results in
374
+ `FundamentalTypeKind::SignedChar` ("signed char").
375
+
376
+ @param[in/out] kind The type to modify
377
+ @return Whether the operation was successful
378
+ */
379
+ MRDOCS_DECL
380
+ bool
381
+ makeChar (FundamentalTypeKind& kind) noexcept ;
382
+
211
383
struct NamedTypeInfo final
212
384
: TypeInfoCommonBase<TypeKind::Named>
213
385
{
214
386
Polymorphic<NameInfo> Name;
215
387
388
+ std::optional<FundamentalTypeKind> FundamentalType;
389
+
216
390
std::strong_ordering
217
391
operator <=>(NamedTypeInfo const & other) const ;
218
392
};
0 commit comments