@@ -42,6 +42,26 @@ struct StringValue
42
42
void (*m_format)(const void *value, std::size_t size, FormatContext &context);
43
43
};
44
44
45
+ /* *
46
+ * Structure to store a type-erased standard value.
47
+ */
48
+ template <typename FormatContext>
49
+ struct StandardValue
50
+ {
51
+ union
52
+ {
53
+ const void *m_pointer;
54
+ std::int64_t m_signed_int;
55
+ std::uint64_t m_unsigned_int;
56
+ float m_float;
57
+ double m_double;
58
+ long double m_long_double;
59
+ bool m_bool;
60
+ };
61
+
62
+ void (*m_format)(StandardValue value, FormatContext &context);
63
+ };
64
+
45
65
/* *
46
66
* Re-form a type-erased user-defined value and format that value.
47
67
*
@@ -67,6 +87,18 @@ void format_user_defined_value(const void *value, FormatContext &context);
67
87
template <typename FormatContext, typename T>
68
88
void format_string_value (const void *value, std::size_t size, FormatContext &context);
69
89
90
+ /* *
91
+ * Re-form a type-erased standard value and format that value.
92
+ *
93
+ * @tparam FormatContext The formatting context type.
94
+ * @tparam T The standrd type.
95
+ *
96
+ * @param value The container holding the type-erased value.
97
+ * @param context The context holding the formatting state.
98
+ */
99
+ template <typename FormatContext, typename T>
100
+ void format_standard_value (StandardValue<FormatContext> value, FormatContext &context);
101
+
70
102
/* *
71
103
* A container to hold a single type-erased format parameter.
72
104
*
@@ -139,6 +171,13 @@ class BasicFormatParameter
139
171
template <typename T, fly::enable_if<BasicFormatTraits::is_default_formatted_enum<T>> = 0 >
140
172
explicit constexpr BasicFormatParameter (T value) noexcept ;
141
173
174
+ /* *
175
+ * Apply the type-erased formatting function to the stored format parameter.
176
+ *
177
+ * @param context The context holding the formatting state.
178
+ */
179
+ constexpr void format (FormatContext &context) const ;
180
+
142
181
/* *
143
182
* Apply the provided visitor to the stored format parameter.
144
183
*
@@ -174,13 +213,7 @@ class BasicFormatParameter
174
213
MonoState m_monostate;
175
214
UserDefinedValue<FormatContext> m_generic;
176
215
StringValue<FormatContext> m_string;
177
- const void *m_pointer;
178
- std::int64_t m_signed_int;
179
- std::uint64_t m_unsigned_int;
180
- float m_float;
181
- double m_double;
182
- long double m_long_double;
183
- bool m_bool;
216
+ StandardValue<FormatContext> m_standard;
184
217
};
185
218
186
219
Type m_type;
@@ -246,6 +279,53 @@ inline void format_string_value(const void *value, std::size_t size, FormatConte
246
279
Formatter<decltype (view), typename FormatContext::char_type>().format (view, context);
247
280
}
248
281
282
+ // ==================================================================================================
283
+ template <typename FormatContext, typename T>
284
+ inline void format_standard_value (StandardValue<FormatContext> value, FormatContext &context)
285
+ {
286
+ Formatter<T, typename FormatContext::char_type> formatter {};
287
+
288
+ if constexpr (BasicFormatTraits::is_pointer_v<T>)
289
+ {
290
+ if constexpr (std::is_null_pointer_v<T>)
291
+ {
292
+ formatter.format (nullptr , context);
293
+ }
294
+ else if constexpr (std::is_const_v<T>)
295
+ {
296
+ formatter.format (static_cast <T>(value.m_pointer ), context);
297
+ }
298
+ else
299
+ {
300
+ formatter.format (static_cast <T>(const_cast <void *>(value.m_pointer )), context);
301
+ }
302
+ }
303
+ else if constexpr (std::is_same_v<T, float >)
304
+ {
305
+ formatter.format (value.m_float , context);
306
+ }
307
+ else if constexpr (std::is_same_v<T, double >)
308
+ {
309
+ formatter.format (value.m_double , context);
310
+ }
311
+ else if constexpr (std::is_same_v<T, long double >)
312
+ {
313
+ formatter.format (value.m_long_double , context);
314
+ }
315
+ else if constexpr (std::is_same_v<T, bool >)
316
+ {
317
+ formatter.format (value.m_bool , context);
318
+ }
319
+ else if constexpr (std::is_signed_v<T>)
320
+ {
321
+ formatter.format (static_cast <T>(value.m_signed_int ), context);
322
+ }
323
+ else
324
+ {
325
+ formatter.format (static_cast <T>(value.m_unsigned_int ), context);
326
+ }
327
+ }
328
+
249
329
// ==================================================================================================
250
330
template <typename FormatContext>
251
331
constexpr inline BasicFormatParameter<FormatContext>::BasicFormatParameter() noexcept :
@@ -305,7 +385,7 @@ template <typename FormatContext>
305
385
template <typename T, fly::enable_if<BasicFormatTraits::is_pointer<T>>>
306
386
constexpr inline BasicFormatParameter<FormatContext>::BasicFormatParameter(T value) noexcept :
307
387
m_type (Type::Pointer),
308
- m_value {.m_pointer {value}}
388
+ m_value {.m_standard {. m_pointer {value}, . m_format {format_standard_value<FormatContext, T>} }}
309
389
{
310
390
}
311
391
@@ -314,38 +394,37 @@ template <typename FormatContext>
314
394
template <typename T, fly::enable_if<std::is_arithmetic<T>>>
315
395
constexpr inline BasicFormatParameter<FormatContext>::BasicFormatParameter(T value) noexcept
316
396
{
317
- if constexpr (std::is_floating_point_v<T>)
397
+ m_value.m_standard .m_format = format_standard_value<FormatContext, T>;
398
+
399
+ if constexpr (std::is_same_v<T, float >)
318
400
{
319
- if constexpr (std::is_same_v<T, float >)
320
- {
321
- m_type = Type::Float;
322
- m_value.m_float = value;
323
- }
324
- else if constexpr (std::is_same_v<T, double >)
325
- {
326
- m_type = Type::Double;
327
- m_value.m_double = value;
328
- }
329
- else if constexpr (std::is_same_v<T, long double >)
330
- {
331
- m_type = Type::LongDouble;
332
- m_value.m_long_double = value;
333
- }
401
+ m_type = Type::Float;
402
+ m_value.m_standard .m_float = value;
403
+ }
404
+ else if constexpr (std::is_same_v<T, double >)
405
+ {
406
+ m_type = Type::Double;
407
+ m_value.m_standard .m_double = value;
408
+ }
409
+ else if constexpr (std::is_same_v<T, long double >)
410
+ {
411
+ m_type = Type::LongDouble;
412
+ m_value.m_standard .m_long_double = value;
334
413
}
335
414
else if constexpr (std::is_same_v<T, bool >)
336
415
{
337
416
m_type = Type::Bool;
338
- m_value.m_bool = value;
417
+ m_value.m_standard . m_bool = value;
339
418
}
340
419
else if constexpr (std::is_signed_v<T>)
341
420
{
342
421
m_type = Type::SignedInt;
343
- m_value.m_signed_int = value;
422
+ m_value.m_standard . m_signed_int = value;
344
423
}
345
424
else
346
425
{
347
426
m_type = Type::UnsignedInt;
348
- m_value.m_unsigned_int = value;
427
+ m_value.m_standard . m_unsigned_int = value;
349
428
}
350
429
}
351
430
@@ -357,6 +436,32 @@ constexpr inline BasicFormatParameter<FormatContext>::BasicFormatParameter(T val
357
436
{
358
437
}
359
438
439
+ // ==================================================================================================
440
+ template <typename FormatContext>
441
+ constexpr inline void BasicFormatParameter<FormatContext>::format(FormatContext &context) const
442
+ {
443
+ switch (m_type)
444
+ {
445
+ case Type::Generic:
446
+ m_value.m_generic .m_format (m_value.m_generic .m_value , context);
447
+ break ;
448
+ case Type::String:
449
+ m_value.m_string .m_format (m_value.m_string .m_value , m_value.m_string .m_size , context);
450
+ break ;
451
+ case Type::Pointer:
452
+ case Type::SignedInt:
453
+ case Type::UnsignedInt:
454
+ case Type::Float:
455
+ case Type::Double:
456
+ case Type::LongDouble:
457
+ case Type::Bool:
458
+ m_value.m_standard .m_format (m_value.m_standard , context);
459
+ break ;
460
+ default :
461
+ break ;
462
+ }
463
+ }
464
+
360
465
// ==================================================================================================
361
466
template <typename FormatContext>
362
467
template <typename Visitor>
@@ -369,19 +474,19 @@ constexpr inline auto BasicFormatParameter<FormatContext>::visit(Visitor &&visit
369
474
case Type::String:
370
475
return visitor (m_value.m_string );
371
476
case Type::Pointer:
372
- return visitor (m_value.m_pointer );
477
+ return visitor (m_value.m_standard . m_pointer );
373
478
case Type::SignedInt:
374
- return visitor (m_value.m_signed_int );
479
+ return visitor (m_value.m_standard . m_signed_int );
375
480
case Type::UnsignedInt:
376
- return visitor (m_value.m_unsigned_int );
481
+ return visitor (m_value.m_standard . m_unsigned_int );
377
482
case Type::Float:
378
- return visitor (m_value.m_float );
483
+ return visitor (m_value.m_standard . m_float );
379
484
case Type::Double:
380
- return visitor (m_value.m_double );
485
+ return visitor (m_value.m_standard . m_double );
381
486
case Type::LongDouble:
382
- return visitor (m_value.m_long_double );
487
+ return visitor (m_value.m_standard . m_long_double );
383
488
case Type::Bool:
384
- return visitor (m_value.m_bool );
489
+ return visitor (m_value.m_standard . m_bool );
385
490
default :
386
491
return visitor (m_value.m_monostate );
387
492
}
0 commit comments