@micro-os-plus/micro-test-plus 3.2.0 → 3.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/.cmake-format.yaml +11 -0
  2. package/CHANGELOG.md +502 -11
  3. package/CMakeLists.txt +33 -32
  4. package/LICENSE +1 -1
  5. package/README.md +15 -14
  6. package/config/xcdl-build.json +32 -0
  7. package/include/micro-os-plus/micro-test-plus/detail.h +1885 -0
  8. package/include/micro-os-plus/micro-test-plus/function-comparators.h +333 -0
  9. package/include/micro-os-plus/micro-test-plus/inlines/details-inlines.h +172 -0
  10. package/include/micro-os-plus/micro-test-plus/inlines/function-comparators-inlines.h +341 -0
  11. package/include/micro-os-plus/micro-test-plus/inlines/literals-inlines.h +604 -0
  12. package/include/micro-os-plus/micro-test-plus/inlines/math-inlines.h +315 -0
  13. package/include/micro-os-plus/micro-test-plus/inlines/micro-test-plus-inlines.h +313 -0
  14. package/include/micro-os-plus/micro-test-plus/inlines/reflection-inlines.h +170 -0
  15. package/include/micro-os-plus/micro-test-plus/inlines/test-reporter-inlines.h +471 -0
  16. package/include/micro-os-plus/micro-test-plus/inlines/test-suite-inlines.h +115 -0
  17. package/include/micro-os-plus/micro-test-plus/literals.h +912 -0
  18. package/include/micro-os-plus/micro-test-plus/math.h +217 -0
  19. package/include/micro-os-plus/micro-test-plus/operators.h +514 -0
  20. package/include/micro-os-plus/micro-test-plus/reflection.h +233 -0
  21. package/include/micro-os-plus/micro-test-plus/test-reporter.h +801 -0
  22. package/include/micro-os-plus/micro-test-plus/test-runner.h +241 -0
  23. package/include/micro-os-plus/micro-test-plus/test-suite.h +456 -0
  24. package/include/micro-os-plus/micro-test-plus/type-traits.h +1148 -0
  25. package/include/micro-os-plus/micro-test-plus.h +171 -554
  26. package/meson.build +6 -7
  27. package/package.json +40 -32
  28. package/src/micro-test-plus.cpp +143 -42
  29. package/src/test-reporter.cpp +350 -9
  30. package/src/test-runner.cpp +77 -14
  31. package/src/test-suite.cpp +132 -14
  32. package/LICENSE-Boost +0 -23
  33. package/include/micro-os-plus/detail.h +0 -766
  34. package/include/micro-os-plus/inlines.h +0 -204
  35. package/include/micro-os-plus/literals.h +0 -513
  36. package/include/micro-os-plus/math.h +0 -205
  37. package/include/micro-os-plus/reflection.h +0 -139
  38. package/include/micro-os-plus/test-reporter-inlines.h +0 -231
  39. package/include/micro-os-plus/test-reporter.h +0 -357
  40. package/include/micro-os-plus/test-runner.h +0 -133
  41. package/include/micro-os-plus/test-suite.h +0 -307
  42. package/include/micro-os-plus/type-traits.h +0 -390
@@ -0,0 +1,1148 @@
1
+ /*
2
+ * This file is part of the µOS++ project (https://micro-os-plus.github.io/).
3
+ * Copyright (c) 2021-2026 Liviu Ionescu. All rights reserved.
4
+ *
5
+ * Permission to use, copy, modify, and/or distribute this software for any
6
+ * purpose is hereby granted, under the terms of the MIT license.
7
+ *
8
+ * If a copy of the license was not distributed with this file, it can be
9
+ * obtained from https://opensource.org/licenses/mit.
10
+ *
11
+ * Major parts of the code are inspired from v1.1.8 of the Boost UT project,
12
+ * released under the terms of the Boost Version 1.0 Software License,
13
+ * which can be obtained from https://www.boost.org/LICENSE_1_0.txt.
14
+ */
15
+
16
+ // ----------------------------------------------------------------------------
17
+
18
+ /**
19
+ * @file
20
+ * @brief C++ header file with declarations for the µTest++ type trait
21
+ * utilities and metaprogramming support.
22
+ *
23
+ * @details
24
+ * This header provides the declarations for the type trait utilities and
25
+ * metaprogramming constructs used within the µTest++ framework. It defines
26
+ * templates and variable traits for function traits, type lists, identity,
27
+ * value wrappers, compile-time checks for container and floating-point types,
28
+ * and type convertibility.
29
+ *
30
+ * These utilities underpin advanced template programming, type deduction, and
31
+ * compile-time introspection, supporting the flexible and type-safe design of
32
+ * the framework. The provided traits and wrappers enable expressive and
33
+ * generic handling of types, values, and callable objects, facilitating robust
34
+ * and maintainable test code.
35
+ *
36
+ * All definitions reside within the
37
+ * `micro_os_plus::micro_test_plus::type_traits` namespace, ensuring clear
38
+ * separation from user code and minimising the risk of naming conflicts.
39
+ *
40
+ * All header files are organised within the
41
+ * `include/micro-os-plus/micro-test-plus` folder to maintain a structured and
42
+ * modular codebase.
43
+ *
44
+ * This file is intended for internal use within the framework and should not
45
+ * be included directly by user code.
46
+ */
47
+
48
+ #ifndef MICRO_TEST_PLUS_TYPE_TRAITS_H_
49
+ #define MICRO_TEST_PLUS_TYPE_TRAITS_H_
50
+
51
+ // ----------------------------------------------------------------------------
52
+
53
+ #ifdef __cplusplus
54
+
55
+ // ----------------------------------------------------------------------------
56
+
57
+ #include "math.h"
58
+
59
+ // ----------------------------------------------------------------------------
60
+
61
+ #if defined(__GNUC__)
62
+ #pragma GCC diagnostic push
63
+ #if defined(__clang__)
64
+ #pragma clang diagnostic ignored "-Wc++98-compat"
65
+ #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
66
+ #endif
67
+ #endif
68
+
69
+ namespace micro_os_plus::micro_test_plus
70
+ {
71
+ // --------------------------------------------------------------------------
72
+
73
+ /**
74
+ * @namespace micro_os_plus::micro_test_plus::type_traits
75
+ * @brief Type trait utilities and metaprogramming support for the µTest++
76
+ * testing framework.
77
+ *
78
+ * @details
79
+ * The `type_traits` namespace offers a comprehensive suite of type trait
80
+ * templates and metaprogramming utilities employed throughout the µTest++
81
+ * framework.
82
+ *
83
+ * This includes templates for function traits, type lists, identity, value
84
+ * wrappers, and compile-time checks for container types, floating point
85
+ * types, and type convertibility. It also provides generic integral and
86
+ * floating point constant wrappers, as well as mechanisms for SFINAE and
87
+ * requirements checking.
88
+ *
89
+ * These utilities facilitate advanced template programming, type deduction,
90
+ * and compile-time introspection, supporting the flexible and type-safe
91
+ * design of the framework.
92
+ *
93
+ * All definitions within this namespace are implemented in the
94
+ * `include/micro-os-plus` folder to maintain a structured and modular
95
+ * codebase.
96
+ */
97
+ namespace type_traits
98
+ {
99
+ /**
100
+ * @brief Struct template representing a compile-time type list.
101
+ *
102
+ * @tparam Types The types to be included in the list.
103
+ *
104
+ * @details
105
+ * The `list` struct template provides a mechanism for grouping an
106
+ * arbitrary number of types into a single type list at compile time. This
107
+ * is a fundamental building block for template metaprogramming, enabling
108
+ * operations such as type iteration, transformation, and introspection
109
+ * within the µTest++ framework.
110
+ *
111
+ * The type list is commonly used in conjunction with function traits and
112
+ * other metaprogramming utilities to facilitate advanced type
113
+ * manipulations and compile-time computations.
114
+ *
115
+ * @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
116
+ */
117
+ template <class... Types>
118
+ struct list
119
+ {
120
+ };
121
+
122
+ /**
123
+ * @brief Struct template for compile-time type identity.
124
+ *
125
+ * @tparam T The type to be preserved.
126
+ * @tparam Extra Additional template parameters, ignored.
127
+ *
128
+ * @details
129
+ * The `identity` struct template provides a mechanism for preserving a
130
+ * type `T` during template metaprogramming. It is commonly used to delay
131
+ * type evaluation or to forward types in complex template constructs
132
+ * within the µTest++ framework.
133
+ *
134
+ * This utility is particularly useful in scenarios where type deduction or
135
+ * SFINAE is required, as it allows the type to be carried through template
136
+ * specialisations without modification.
137
+ *
138
+ * @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
139
+ */
140
+ template <class T, class... Extra>
141
+ struct identity
142
+ {
143
+ /**
144
+ * @brief Alias for the preserved type.
145
+ */
146
+ using type = T;
147
+ };
148
+
149
+ #if defined(__DOXYGEN__)
150
+ // error: Detected potential recursive class relation between class
151
+ // micro_os_plus::micro_test_plus::type_traits::function_traits and base
152
+ // class micro_os_plus::micro_test_plus::type_traits::function_traits<
153
+ // decltype(&T::operator())>!
154
+ // https://github.com/doxygen/doxygen/issues/9915
155
+ #else
156
+ /**
157
+ * @brief Struct template for extracting function traits from callable
158
+ * types.
159
+ *
160
+ * @tparam T The callable type for which traits are to be extracted.
161
+ *
162
+ * @details
163
+ * The `function_traits` struct template provides compile-time
164
+ * introspection of callable types, such as function pointers, member
165
+ * functions, and functors (including lambdas). For generic callable types,
166
+ * this primary template inherits from the specialisation for the type of
167
+ * the call operator, enabling seamless trait extraction for user-defined
168
+ * functors and lambdas.
169
+ *
170
+ * This mechanism allows the µTest++ framework to deduce argument types and
171
+ * return types of arbitrary callables, supporting advanced template
172
+ * metaprogramming and flexible test case registration.
173
+ *
174
+ * @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
175
+ */
176
+ template <class T>
177
+ struct function_traits : function_traits<decltype (&T::operator())>
178
+ {
179
+ };
180
+ #endif
181
+
182
+ /**
183
+ * @brief Struct template specialisation for extracting function traits
184
+ * from function pointer types.
185
+ *
186
+ * @tparam R The return type of the function.
187
+ * @tparam Args_T The argument types of the function.
188
+ *
189
+ * @details
190
+ * This specialisation of the `function_traits` struct template provides
191
+ * compile-time introspection for function pointer types. It exposes the
192
+ * return type and argument types of a function pointer, enabling advanced
193
+ * template metaprogramming and type deduction within the µTest++
194
+ * framework.
195
+ *
196
+ * The `result_type` member defines the return type of the function, while
197
+ * the `args` member is a type list containing all argument types.
198
+ *
199
+ * @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
200
+ */
201
+ template <class R, class... Args_T>
202
+ struct function_traits<R (*) (Args_T...)>
203
+ {
204
+ /**
205
+ * @brief The return type of the function.
206
+ */
207
+ using result_type = R;
208
+
209
+ /**
210
+ * @brief Type list of all argument types.
211
+ */
212
+ using args = list<Args_T...>;
213
+ };
214
+
215
+ /**
216
+ * @brief Struct template specialisation for extracting function traits
217
+ * from plain function types.
218
+ *
219
+ * @tparam R The return type of the function.
220
+ * @tparam Args_T The argument types of the function.
221
+ *
222
+ * @details
223
+ * This specialisation of the `function_traits` struct template provides
224
+ * compile-time introspection for plain function types (i.e., non-pointer,
225
+ * non-member functions). It exposes the return type and argument types of
226
+ * a function, enabling advanced template metaprogramming and type
227
+ * deduction within the µTest++ framework.
228
+ *
229
+ * The `result_type` member defines the return type of the function, while
230
+ * the `args` member is a type list containing all argument types.
231
+ *
232
+ * @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
233
+ */
234
+ template <class R, class... Args_T>
235
+ struct function_traits<R (Args_T...)>
236
+ {
237
+ /**
238
+ * @brief The return type of the function.
239
+ */
240
+ using result_type = R;
241
+
242
+ /**
243
+ * @brief Type list of all argument types.
244
+ */
245
+ using args = list<Args_T...>;
246
+ };
247
+
248
+ /**
249
+ * @brief Struct template specialisation for extracting function traits
250
+ * from non-const member function types.
251
+ *
252
+ * @tparam R The return type of the member function.
253
+ * @tparam T The class type to which the member function belongs.
254
+ * @tparam Args_T The argument types of the member function.
255
+ *
256
+ * @details
257
+ * This specialisation of the `function_traits` struct template provides
258
+ * compile-time introspection for non-const member function types. It
259
+ * exposes the return type and argument types of a member function,
260
+ * enabling advanced template metaprogramming and type deduction within the
261
+ * µTest++ framework.
262
+ *
263
+ * The `result_type` member defines the return type of the member function,
264
+ * while the `args` member is a type list containing all argument types.
265
+ *
266
+ * @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
267
+ */
268
+ template <class R, class T, class... Args_T>
269
+ struct function_traits<R (T::*) (Args_T...)>
270
+ {
271
+ /**
272
+ * @brief The return type of the member function.
273
+ */
274
+ using result_type = R;
275
+
276
+ /**
277
+ * @brief Type list of all argument types.
278
+ */
279
+ using args = list<Args_T...>;
280
+ };
281
+
282
+ /**
283
+ * @brief Struct template specialisation for extracting function traits
284
+ * from const member function types.
285
+ *
286
+ * @tparam R The return type of the const member function.
287
+ * @tparam T The class type to which the member function belongs.
288
+ * @tparam Args_T The argument types of the const member function.
289
+ *
290
+ * @details
291
+ * This specialisation of the `function_traits` struct template provides
292
+ * compile-time introspection for const member function types. It exposes
293
+ * the return type and argument types of a const member function, enabling
294
+ * advanced template metaprogramming and type deduction within the µTest++
295
+ * framework.
296
+ *
297
+ * The `result_type` member defines the return type of the const member
298
+ * function, while the `args` member is a type list containing all argument
299
+ * types.
300
+ *
301
+ * @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
302
+ */
303
+ template <class R, class T, class... Args_T>
304
+ struct function_traits<R (T::*) (Args_T...) const>
305
+ {
306
+ /**
307
+ * @brief The return type of the const member function.
308
+ */
309
+ using result_type = R;
310
+
311
+ /**
312
+ * @brief Type list of all argument types.
313
+ */
314
+ using args = list<Args_T...>;
315
+ };
316
+
317
+ /**
318
+ * @brief Utility function template to simulate std::declval for type
319
+ * deduction.
320
+ *
321
+ * @tparam T The type for which an rvalue reference is required.
322
+ *
323
+ * @par Parameters
324
+ * None.
325
+ * @return An rvalue reference to type `T`.
326
+ *
327
+ * @details
328
+ * The `declval` function template provides a mechanism for obtaining an
329
+ * rvalue reference to a type `T` without requiring an actual object. This
330
+ * is primarily used in unevaluated contexts, such as within `decltype`, to
331
+ * deduce types during template metaprogramming in the µTest++ framework.
332
+ */
333
+ template <class T>
334
+ T&&
335
+ declval (void);
336
+ template <class... Ts, class Expr_T>
337
+ constexpr auto
338
+ is_valid (Expr_T expr) -> decltype (expr (declval<Ts...> ()), bool ())
339
+ {
340
+ return true;
341
+ }
342
+
343
+ /**
344
+ * @brief Fallback function template for is_valid, returns false if the
345
+ * expression is not valid.
346
+ *
347
+ * @tparam Ts The argument types to be tested.
348
+ *
349
+ * @return `false` indicating the expression is not valid for the given
350
+ * argument types.
351
+ *
352
+ * @details
353
+ * This overload is selected when the primary `is_valid` template cannot be
354
+ * instantiated, providing a `false` result for invalid expressions.
355
+ */
356
+ template <class... Ts>
357
+ constexpr auto
358
+ is_valid (...) -> bool
359
+ {
360
+ return false;
361
+ }
362
+
363
+ /**
364
+ * @brief Variable template to determine if a type models a container.
365
+ *
366
+ * @tparam T The type to be checked for container-like behaviour.
367
+ *
368
+ * @retval true if `T` has both `begin()` and `end()` member functions.
369
+ * @retval false otherwise.
370
+ *
371
+ * @details
372
+ * The `is_container_v` variable template evaluates to `true` if the given
373
+ * type `T` provides both `begin()` and `end()` member functions,
374
+ * indicating that it models a standard container concept. This trait is
375
+ * determined at compile time using SFINAE and is_valid, and is used
376
+ * throughout the µTest++ framework to enable generic handling of container
377
+ * types in template metaprogramming.
378
+ */
379
+ template <class T>
380
+ static constexpr auto is_container_v = is_valid<T> (
381
+ [] (auto t) -> decltype (t.begin (), t.end (), void ()) {});
382
+
383
+ /**
384
+ * @brief Variable template to determine if a type provides a static `npos`
385
+ * member.
386
+ *
387
+ * @tparam T The type to be checked for the presence of a static `npos`
388
+ * member.
389
+ *
390
+ * @retval true if `T` has a static member named `npos`.
391
+ * @retval false otherwise.
392
+ *
393
+ * @details
394
+ * The `has_npos_v` variable template evaluates to `true` if the given type
395
+ * `T` defines a static member named `npos`. This trait is determined at
396
+ * compile time using SFINAE and the `is_valid` utility, and is used
397
+ * throughout the µTest++ framework to enable generic handling of types
398
+ * that follow the standard string or container conventions.
399
+ */
400
+ template <class T>
401
+ static constexpr auto has_npos_v
402
+ = is_valid<T> ([] (auto t) -> decltype (void (t.npos)) {});
403
+
404
+ /**
405
+ * @brief Variable template to determine if a type provides a `value`
406
+ * member.
407
+ *
408
+ * @tparam T The type to be checked for the presence of a `value` member.
409
+ *
410
+ * @retval true if `T` has a member named `value`.
411
+ * @retval false otherwise.
412
+ *
413
+ * @details
414
+ * The `has_value_v` variable template evaluates to `true` if the given
415
+ * type `T` defines a member named `value`. This trait is determined at
416
+ * compile time using SFINAE and the `is_valid` utility, and is used
417
+ * throughout the µTest++ framework to enable generic handling of types
418
+ * that encapsulate a value, such as wrappers or constant types.
419
+ */
420
+ template <class T>
421
+ static constexpr auto has_value_v
422
+ = is_valid<T> ([] (auto t) -> decltype (void (t.value)) {});
423
+
424
+ /**
425
+ * @brief Variable template to determine if a type provides an `epsilon`
426
+ * member.
427
+ *
428
+ * @tparam T The type to be checked for the presence of an `epsilon`
429
+ * member.
430
+ *
431
+ * @retval true if `T` has a member named `epsilon`.
432
+ * @retval false otherwise.
433
+ *
434
+ * @details
435
+ * The `has_epsilon_v` variable template evaluates to `true` if the given
436
+ * type `T` defines a member named `epsilon`. This trait is determined at
437
+ * compile time using SFINAE and the `is_valid` utility, and is used
438
+ * throughout the µTest++ framework to enable generic handling of types
439
+ * that represent floating-point values or require precision control.
440
+ */
441
+ template <class T>
442
+ static constexpr auto has_epsilon_v
443
+ = is_valid<T> ([] (auto t) -> decltype (void (t.epsilon)) {});
444
+
445
+ /**
446
+ * @brief Variable template to determine if a type is a floating point
447
+ * type.
448
+ *
449
+ * @tparam T The type to be checked for floating point classification.
450
+ *
451
+ * @retval true if `T` is a floating point type.
452
+ * @retval false otherwise.
453
+ *
454
+ * @details
455
+ * The `is_floating_point_v` variable template evaluates to `true` if the
456
+ * given type `T` is a floating point type (`float`, `double`, or `long
457
+ * double`). For all other types, it evaluates to `false`. This trait is
458
+ * used throughout the µTest++ framework to enable type-safe handling and
459
+ * specialisation for floating point types in template metaprogramming.
460
+ *
461
+ * Specialisations are provided for `float`, `double`, and `long double`,
462
+ * each evaluating to `true`.
463
+ */
464
+ template <class T>
465
+ inline constexpr auto is_floating_point_v = false;
466
+
467
+ /**
468
+ * @brief Variable template specialisation indicating that `float` is a
469
+ * floating point type.
470
+ *
471
+ * @details
472
+ * This specialisation of the `is_floating_point_v` variable template
473
+ * evaluates to `true` for the `float` type, confirming that it is
474
+ * recognised as a floating point type within the µTest++ framework. This
475
+ * enables type-safe handling and specialisation for floating point types
476
+ * in template metaprogramming.
477
+ *
478
+ * @see is_floating_point_v
479
+ */
480
+ template <>
481
+ inline constexpr auto is_floating_point_v<float> = true;
482
+
483
+ /**
484
+ * @brief Variable template specialisation indicating that `double` is a
485
+ * floating point type.
486
+ *
487
+ * @details
488
+ * This specialisation of the `is_floating_point_v` variable template
489
+ * evaluates to `true` for the `double` type, confirming that it is
490
+ * recognised as a floating point type within the µTest++ framework. This
491
+ * enables type-safe handling and specialisation for floating point types
492
+ * in template metaprogramming.
493
+ *
494
+ * @see is_floating_point_v
495
+ */
496
+ template <>
497
+ inline constexpr auto is_floating_point_v<double> = true;
498
+
499
+ /**
500
+ * @brief Variable template specialisation indicating that `long double` is
501
+ * a floating point type.
502
+ *
503
+ * @details
504
+ * This specialisation of the `is_floating_point_v` variable template
505
+ * evaluates to `true` for the `long double` type, confirming that it is
506
+ * recognised as a floating point type within the µTest++ framework. This
507
+ * enables type-safe handling and specialisation for floating point types
508
+ * in template metaprogramming.
509
+ *
510
+ * @see is_floating_point_v
511
+ */
512
+ template <>
513
+ inline constexpr auto is_floating_point_v<long double> = true;
514
+
515
+ #if defined(__clang__) or defined(_MSC_VER)
516
+ /**
517
+ * @brief Variable template to determine if one type is convertible to
518
+ * another.
519
+ *
520
+ * @tparam From The source type to be checked for convertibility.
521
+ * @tparam To The target type to which conversion is tested.
522
+ *
523
+ * @retval true if `From` is convertible to `To`.
524
+ * @retval false otherwise.
525
+ *
526
+ * @details
527
+ * The `is_convertible_v` variable template evaluates to `true` if the type
528
+ * `From` is implicitly convertible to the type `To`, and `false`
529
+ * otherwise. This trait is determined at compile time and is used
530
+ * throughout the µTest++ framework to enable type-safe conversions and
531
+ * requirements checking in template metaprogramming.
532
+ *
533
+ * On supported compilers, this trait leverages compiler intrinsics for
534
+ * optimal performance and accuracy.
535
+ */
536
+ template <class From, class To>
537
+ static constexpr auto is_convertible_v = __is_convertible_to (From, To);
538
+ #else
539
+ /**
540
+ * @brief Function template to determine if one type is convertible to
541
+ * another.
542
+ *
543
+ * @tparam From The source type to be checked for convertibility.
544
+ * @tparam To The target type to which conversion is tested.
545
+ *
546
+ * @param n Dummy parameter used for overload resolution.
547
+ * @retval true if `From` is convertible to `To`.
548
+ *
549
+ * @details
550
+ * The `is_convertible` function template checks, at compile time, whether
551
+ * a value of type `From` can be implicitly converted to type `To`. This is
552
+ * achieved using SFINAE and is primarily used as an implementation detail
553
+ * for the `is_convertible_v` variable template within the µTest++
554
+ * framework.
555
+ *
556
+ * If the conversion is valid, this overload is selected and returns
557
+ * `true`.
558
+ */
559
+ template <class From, class To>
560
+ constexpr auto
561
+ is_convertible (int n) -> decltype (bool (To (declval<From> ())))
562
+ {
563
+ (void)n; // Prevent the unused parameter warning.
564
+ return true;
565
+ }
566
+
567
+ /**
568
+ * @brief Fallback function template for is_convertible, returns false if
569
+ * the conversion is not valid.
570
+ *
571
+ * @tparam ...Unused Unused template parameters.
572
+ *
573
+ * @retval false indicating the conversion is not valid.
574
+ *
575
+ * @details
576
+ * This overload is selected when the primary `is_convertible` template
577
+ * cannot be instantiated, providing a `false` result for invalid
578
+ * conversions.
579
+ */
580
+ template <class...>
581
+ constexpr auto
582
+ is_convertible (...)
583
+ {
584
+ return false;
585
+ }
586
+
587
+ /**
588
+ * @brief Variable template to determine if one type is convertible to
589
+ * another.
590
+ *
591
+ * @tparam From The source type to be checked for convertibility.
592
+ * @tparam To The target type to which conversion is tested.
593
+ *
594
+ * @retval true if `From` is convertible to `To`.
595
+ * @retval false otherwise.
596
+ *
597
+ * @details
598
+ * The `is_convertible_v` variable template evaluates to `true` if the type
599
+ * `From` is implicitly convertible to the type `To`, and `false`
600
+ * otherwise. This trait is determined at compile time and is used
601
+ * throughout the µTest++ framework to enable type-safe conversions and
602
+ * requirements checking in template metaprogramming.
603
+ */
604
+ template <class From, class To>
605
+ constexpr auto is_convertible_v = is_convertible<From, To> (0);
606
+ #endif
607
+
608
+ /**
609
+ * @brief Struct template for SFINAE requirements.
610
+ *
611
+ * @details
612
+ * The `requires_` struct template is a utility for SFINAE (Substitution
613
+ * Failure Is Not An Error) in template metaprogramming. It is typically
614
+ * used to enable or disable template specialisations and function
615
+ * templates based on compile-time boolean conditions.
616
+ *
617
+ * When the boolean template parameter is `true`, the specialisation
618
+ * provides a nested `type` alias, which can be used in conjunction with
619
+ * `typename` and `requires_t` to enforce requirements in template
620
+ * declarations.
621
+ *
622
+ * @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
623
+ */
624
+ template <bool Cond>
625
+ struct requires_
626
+ {
627
+ };
628
+
629
+ /**
630
+ * @brief Specialisation of the requirements struct template for `true`.
631
+ *
632
+ * @details
633
+ * When the condition is `true`, this specialisation provides a nested
634
+ * `type` alias, typically used for SFINAE and requirements checking in
635
+ * template metaprogramming.
636
+ *
637
+ * @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
638
+ */
639
+ template <>
640
+ struct requires_<true>
641
+ {
642
+ /**
643
+ * @brief Alias type provided when the requirement is satisfied.
644
+ */
645
+ using type = int;
646
+ };
647
+
648
+ /**
649
+ * @brief Alias template for extracting the `type` member from `requires_`.
650
+ *
651
+ * @tparam Cond The boolean condition to be checked at compile time.
652
+ *
653
+ * @details
654
+ * The `requires_t` alias template simplifies the use of the `requires_`
655
+ * struct template by directly exposing the nested `type` member. It is
656
+ * commonly used to enforce compile-time requirements in template
657
+ * declarations.
658
+ */
659
+ template <bool Cond>
660
+ using requires_t = typename requires_<Cond>::type;
661
+
662
+ /**
663
+ * @brief Empty base struct for all operator types.
664
+ *
665
+ * @details
666
+ * The `op` struct serves as a common base for all operator and value
667
+ * wrapper types used in the µTest++ framework's type traits and
668
+ * metaprogramming utilities. It provides a unified type hierarchy,
669
+ * enabling compile-time detection and generic handling of operator-like
670
+ * types within the framework.
671
+ *
672
+ * This struct is intended for internal use as a base for integral
673
+ * constants, floating point constants, and other value wrappers,
674
+ * supporting advanced template metaprogramming and type introspection.
675
+ *
676
+ * @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
677
+ */
678
+ struct op
679
+ {
680
+ };
681
+
682
+ /**
683
+ * @brief Struct template representing a generic integral constant.
684
+ *
685
+ * @tparam N The compile-time constant value.
686
+ *
687
+ * @details
688
+ * The `integral_constant` struct template provides a compile-time constant
689
+ * value of an integral type, with additional utility features. It inherits
690
+ * from `op` to enable unified handling within the µTest++ framework's type
691
+ * traits and metaprogramming utilities.
692
+ *
693
+ * This struct template exposes the constant value via a static member, a
694
+ * getter method, and explicit conversion operators. It also provides a
695
+ * unary minus operator to obtain the negative value as a new
696
+ * `integral_constant` instance.
697
+ *
698
+ * @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
699
+ */
700
+ template <auto N>
701
+ struct integral_constant : op
702
+ {
703
+ /**
704
+ * @brief The type of the constant value.
705
+ */
706
+ using value_type = decltype (N);
707
+
708
+ /**
709
+ * @brief The constant value.
710
+ */
711
+ static constexpr auto value = N;
712
+
713
+ /**
714
+ * @brief Unary minus operator.
715
+ *
716
+ * @return An `integral_constant` with value `-N`.
717
+ *
718
+ * @details
719
+ * Returns a new `integral_constant` instance representing the negative
720
+ * of the current value.
721
+ */
722
+ [[nodiscard]] constexpr auto
723
+ operator- () const
724
+ {
725
+ return integral_constant<-N>{};
726
+ }
727
+
728
+ /**
729
+ * @brief Explicit conversion operator to value_type.
730
+ *
731
+ * @par Parameters
732
+ * None.
733
+ * @return The constant value as type `value_type`.
734
+ *
735
+ * @details
736
+ * Allows explicit conversion to the underlying value type.
737
+ */
738
+ [[nodiscard]] constexpr explicit
739
+ operator value_type (void) const
740
+ {
741
+ return N;
742
+ }
743
+
744
+ /**
745
+ * @brief Getter for the constant value.
746
+ *
747
+ * @par Parameters
748
+ * None.
749
+ * @return The constant value.
750
+ *
751
+ * @details
752
+ * Returns the compile-time constant value.
753
+ */
754
+ [[nodiscard]] constexpr auto
755
+ get (void) const
756
+ {
757
+ return N;
758
+ }
759
+ };
760
+
761
+ /**
762
+ * @brief Struct template representing a generic floating point constant
763
+ * with custom size and precision.
764
+ *
765
+ * @tparam T The floating point type (e.g., float, double).
766
+ * @tparam N The integral part of the constant value.
767
+ * @tparam D The fractional part of the constant value.
768
+ * @tparam Size The number of decimal digits for the fractional part.
769
+ * @tparam P The sign of the value (1 for positive, -1 for negative).
770
+ * Defaults to 1.
771
+ *
772
+ * @details
773
+ * The `floating_point_constant` struct template provides a compile-time
774
+ * constant value of a floating point type, supporting custom size and
775
+ * precision. It inherits from `op` to enable unified handling within the
776
+ * µTest++ framework's type traits and metaprogramming utilities.
777
+ *
778
+ * This struct template exposes the constant value via a static member, a
779
+ * getter method, and explicit conversion operators. It also provides a
780
+ * unary minus operator to obtain the negative value as a new
781
+ * `floating_point_constant` instance. The `epsilon` member defines the
782
+ * precision used for floating point comparisons, calculated based on the
783
+ * specified size.
784
+ *
785
+ * @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
786
+ */
787
+ template <class T, auto N, auto D, auto Size, auto P = 1>
788
+ struct floating_point_constant : op
789
+ {
790
+ /**
791
+ * @brief The type of the constant value.
792
+ */
793
+ using value_type = T;
794
+
795
+ /**
796
+ * @brief The epsilon value used for floating point comparisons.
797
+ *
798
+ * @details
799
+ * Calculated as 1 divided by 10 raised to the power of (Size - 1).
800
+ */
801
+ static constexpr auto epsilon = T (1) / math::pow (T (10), Size - 1);
802
+
803
+ /**
804
+ * @brief The constant value.
805
+ *
806
+ * @details
807
+ * Computed as `P * (N + D / 10^Size)`.
808
+ */
809
+ static constexpr auto value
810
+ = T (P) * (T (N) + (T (D) / math::pow (T (10), Size)));
811
+
812
+ /**
813
+ * @brief Unary minus operator.
814
+ *
815
+ * @return A `floating_point_constant` with value `-value`.
816
+ *
817
+ * @details
818
+ * Returns a new `floating_point_constant` instance representing the
819
+ * negative of the current value.
820
+ */
821
+ [[nodiscard]] constexpr auto
822
+ operator- () const
823
+ {
824
+ return floating_point_constant<T, N, D, Size, -1>{};
825
+ }
826
+
827
+ /**
828
+ * @brief Explicit conversion operator to value_type.
829
+ *
830
+ * @return The constant value as type `value_type`.
831
+ *
832
+ * @details
833
+ * Allows explicit conversion to the underlying floating point value
834
+ * type.
835
+ */
836
+ [[nodiscard]] constexpr explicit
837
+ operator value_type () const
838
+ {
839
+ return value;
840
+ }
841
+
842
+ /**
843
+ * @brief Getter for the constant value.
844
+ *
845
+ * @return The constant value.
846
+ *
847
+ * @details
848
+ * Returns the compile-time floating point constant value.
849
+ */
850
+ [[nodiscard]] constexpr auto
851
+ get () const
852
+ {
853
+ return value;
854
+ }
855
+ };
856
+
857
+ /**
858
+ * @brief Struct template representing a genuine integral value.
859
+ *
860
+ * @tparam T The type of the integral value.
861
+ *
862
+ * @details
863
+ * The `genuine_integral_value` struct template encapsulates a runtime
864
+ * integral value, providing a consistent interface for value access and
865
+ * conversion. It inherits from `op` to enable unified handling within the
866
+ * µTest++ framework's type traits and metaprogramming utilities.
867
+ *
868
+ * This struct template exposes the value via a member variable, a getter
869
+ * method, and an explicit conversion operator. It is intended for use
870
+ * cases where a value must be wrapped and treated generically within the
871
+ * framework, supporting advanced template metaprogramming and type
872
+ * introspection.
873
+ *
874
+ * @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
875
+ */
876
+ template <class T>
877
+ struct genuine_integral_value : op
878
+ {
879
+ /**
880
+ * @brief The type of the encapsulated value.
881
+ */
882
+ using value_type = T;
883
+
884
+ /**
885
+ * @brief Constructs a genuine_integral_value with the specified value.
886
+ *
887
+ * @param _value The integral value to be stored.
888
+ */
889
+ constexpr genuine_integral_value (const T& _value) : value_{ _value }
890
+ {
891
+ }
892
+
893
+ /**
894
+ * @brief Explicit conversion operator to the underlying value type.
895
+ *
896
+ * @return The stored value as type `T`.
897
+ *
898
+ * @details
899
+ * Allows explicit conversion to the encapsulated value.
900
+ */
901
+ [[nodiscard]] constexpr explicit
902
+ operator T () const
903
+ {
904
+ return value_;
905
+ }
906
+
907
+ /**
908
+ * @brief Getter for the encapsulated value.
909
+ *
910
+ * @return The value of type `T`.
911
+ *
912
+ * @details
913
+ * Returns the stored integral value.
914
+ */
915
+ [[nodiscard]] constexpr decltype (auto)
916
+ get () const
917
+ {
918
+ return value_;
919
+ }
920
+
921
+ /**
922
+ * @brief The encapsulated integral value.
923
+ */
924
+ T value_{};
925
+ };
926
+
927
+ /**
928
+ * @brief Variable template to determine if a type derives from `op`.
929
+ *
930
+ * @tparam T The type to be checked for derivation from `op`.
931
+ *
932
+ * @retval true if `T` is derived from `type_traits::op`.
933
+ * @retval false otherwise.
934
+ *
935
+ * @details
936
+ * The `is_op_v` variable template evaluates to `true` if the given type
937
+ * `T` is derived from the `type_traits::op` base struct, and `false`
938
+ * otherwise. This trait is determined at compile time using compiler
939
+ * intrinsics and is used throughout the µTest++ framework to enable
940
+ * generic handling and detection of operator-like or value wrapper types
941
+ * in template metaprogramming.
942
+ */
943
+ template <class T>
944
+ inline constexpr auto is_op_v = __is_base_of (type_traits::op, T);
945
+
946
+ /**
947
+ * @brief Struct template representing a generic value, accessible via a
948
+ * getter.
949
+ *
950
+ * @tparam T The type of the value to be encapsulated.
951
+ * @tparam Opt An optional parameter for SFINAE or specialisation,
952
+ * defaults to `int`.
953
+ *
954
+ * @details
955
+ * The `value` struct template encapsulates a value of type `T`, providing
956
+ * a consistent interface for value access and conversion. It inherits from
957
+ * `type_traits::op` to enable unified handling within the µTest++
958
+ * framework's type traits and metaprogramming utilities.
959
+ *
960
+ * This struct template exposes the value via a member variable, a getter
961
+ * method, and an explicit conversion operator. It is intended for use
962
+ * cases where a value must be wrapped and treated generically within the
963
+ * framework, supporting advanced template metaprogramming and type
964
+ * introspection.
965
+ *
966
+ * @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
967
+ */
968
+ template <class T, class Opt = int>
969
+ struct value : type_traits::op
970
+ {
971
+ /**
972
+ * @brief The type of the encapsulated value.
973
+ */
974
+ using value_type = T;
975
+
976
+ /**
977
+ * @brief Constructs a value object with the specified value.
978
+ *
979
+ * @param _value The value to be stored.
980
+ */
981
+ constexpr value (const T& _value) : value_{ _value }
982
+ {
983
+ }
984
+
985
+ /**
986
+ * @brief Explicit conversion operator to the underlying value type.
987
+ *
988
+ * @return The stored value as type `T`.
989
+ *
990
+ * @details
991
+ * Allows explicit conversion to the encapsulated value.
992
+ */
993
+ [[nodiscard]] constexpr explicit
994
+ operator T () const
995
+ {
996
+ return value_;
997
+ }
998
+
999
+ /**
1000
+ * @brief Getter for the encapsulated value.
1001
+ *
1002
+ * @par Parameters
1003
+ * None.
1004
+ * @return The value of type `T`.
1005
+ *
1006
+ * @details
1007
+ * Returns the stored value.
1008
+ */
1009
+ [[nodiscard]] constexpr decltype (auto)
1010
+ get (void) const
1011
+ {
1012
+ return value_;
1013
+ }
1014
+
1015
+ /**
1016
+ * @brief The encapsulated value.
1017
+ */
1018
+ T value_{};
1019
+ };
1020
+
1021
+ /**
1022
+ * @brief Struct template representing a floating point value with
1023
+ * precision control.
1024
+ *
1025
+ * @tparam T The floating point type to be encapsulated.
1026
+ *
1027
+ * @details
1028
+ * The `value` struct template specialisation for floating point types
1029
+ * encapsulates a value of type `T` and provides an associated `epsilon`
1030
+ * for precision control during comparisons. It inherits from
1031
+ * `type_traits::op` to enable unified handling within the µTest++
1032
+ * framework's type traits and metaprogramming utilities.
1033
+ *
1034
+ * This struct template exposes the value via a member variable, a getter
1035
+ * method, and an explicit conversion operator. The `epsilon` member
1036
+ * defines the precision used for floating point comparisons and can be set
1037
+ * explicitly or computed as a default based on the number of decimal
1038
+ * digits in the value.
1039
+ *
1040
+ * This specialisation is intended for use cases where floating point
1041
+ * values require controlled precision, supporting advanced template
1042
+ * metaprogramming and type-safe comparisons within the framework.
1043
+ *
1044
+ * @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
1045
+ */
1046
+ template <class T>
1047
+ struct value<T,
1048
+ type_traits::requires_t<type_traits::is_floating_point_v<T>>>
1049
+ : type_traits::op
1050
+ {
1051
+ /**
1052
+ * @brief The type of the encapsulated value.
1053
+ */
1054
+ using value_type = T;
1055
+
1056
+ /**
1057
+ * @brief The epsilon value used for floating point comparisons.
1058
+ *
1059
+ * @details
1060
+ * This static inline member defines the precision for comparisons. It
1061
+ * can be set explicitly via the constructor or computed as a default
1062
+ * based on the number of decimal digits in the value.
1063
+ */
1064
+ static inline auto epsilon = T{}; // Why static?
1065
+
1066
+ /**
1067
+ * @brief Constructs a floating point value with a specified precision.
1068
+ *
1069
+ * @param _value The floating point value to be stored.
1070
+ * @param precision The epsilon value to be used for comparisons.
1071
+ */
1072
+ constexpr value (const T& _value, const T precision) : value_{ _value }
1073
+ {
1074
+ epsilon = precision;
1075
+ }
1076
+
1077
+ /**
1078
+ * @brief Constructs a floating point value with default precision.
1079
+ *
1080
+ * @param val The floating point value to be stored.
1081
+ *
1082
+ * @details
1083
+ * The epsilon is computed as 1 divided by 10 raised to the number of
1084
+ * decimal digits in the value.
1085
+ */
1086
+ constexpr /*explicit(false)*/ value (const T& val)
1087
+ : value{ val,
1088
+ T (1)
1089
+ / math::pow (T (10),
1090
+ math::den_size<unsigned long long> (val)) }
1091
+ {
1092
+ }
1093
+
1094
+ /**
1095
+ * @brief Explicit conversion operator to the underlying value type.
1096
+ *
1097
+ * @return The stored value as type `T`.
1098
+ *
1099
+ * @details
1100
+ * Allows explicit conversion to the encapsulated floating point value.
1101
+ */
1102
+ [[nodiscard]] constexpr explicit
1103
+ operator T () const
1104
+ {
1105
+ return value_;
1106
+ }
1107
+
1108
+ /**
1109
+ * @brief Getter for the encapsulated value.
1110
+ *
1111
+ * @par Parameters
1112
+ * None.
1113
+ * @return The value of type `T`.
1114
+ *
1115
+ * @details
1116
+ * Returns the stored floating point value.
1117
+ */
1118
+ [[nodiscard]] constexpr decltype (auto)
1119
+ get (void) const
1120
+ {
1121
+ return value_;
1122
+ }
1123
+
1124
+ /**
1125
+ * @brief The encapsulated floating point value.
1126
+ */
1127
+ T value_{};
1128
+ };
1129
+
1130
+ // ------------------------------------------------------------------------
1131
+ } // namespace type_traits
1132
+
1133
+ // --------------------------------------------------------------------------
1134
+ } // namespace micro_os_plus::micro_test_plus
1135
+
1136
+ #if defined(__GNUC__)
1137
+ #pragma GCC diagnostic pop
1138
+ #endif
1139
+
1140
+ // ----------------------------------------------------------------------------
1141
+
1142
+ #endif // __cplusplus
1143
+
1144
+ // ----------------------------------------------------------------------------
1145
+
1146
+ #endif // MICRO_TEST_PLUS_TYPE_TRAITS_H_
1147
+
1148
+ // ----------------------------------------------------------------------------