@micro-os-plus/micro-test-plus 3.3.0 → 4.0.0

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 (53) hide show
  1. package/CHANGELOG.md +339 -2
  2. package/CMakeLists.txt +79 -23
  3. package/README.md +1 -1
  4. package/config/xcdl-build.json +11 -4
  5. package/include/micro-os-plus/micro-test-plus/deferred-reporter.h +292 -0
  6. package/include/micro-os-plus/micro-test-plus/detail.h +462 -1076
  7. package/include/micro-os-plus/micro-test-plus/exceptions.h +126 -0
  8. package/include/micro-os-plus/micro-test-plus/function-comparators.h +10 -7
  9. package/include/micro-os-plus/micro-test-plus/inlines/{details-inlines.h → deferred-reporter-inlines.h} +49 -22
  10. package/include/micro-os-plus/micro-test-plus/inlines/function-comparators-inlines.h +67 -4
  11. package/include/micro-os-plus/micro-test-plus/inlines/literals-inlines.h +3 -6
  12. package/include/micro-os-plus/micro-test-plus/inlines/math-inlines.h +21 -15
  13. package/include/micro-os-plus/micro-test-plus/inlines/reflection-inlines.h +35 -17
  14. package/include/micro-os-plus/micro-test-plus/inlines/{test-reporter-inlines.h → reporter-inlines.h} +176 -106
  15. package/include/micro-os-plus/micro-test-plus/inlines/{test-suite-inlines.h → runner-inlines.h} +41 -43
  16. package/include/micro-os-plus/micro-test-plus/inlines/test-inlines.h +369 -0
  17. package/include/micro-os-plus/micro-test-plus/inlines/utility-inlines.h +126 -0
  18. package/include/micro-os-plus/micro-test-plus/literals.h +4 -3
  19. package/include/micro-os-plus/micro-test-plus/math.h +9 -6
  20. package/include/micro-os-plus/micro-test-plus/operators.h +38 -44
  21. package/include/micro-os-plus/micro-test-plus/reflection.h +15 -4
  22. package/include/micro-os-plus/micro-test-plus/{test-reporter-basic.h → reporter-human.h} +72 -72
  23. package/include/micro-os-plus/micro-test-plus/{test-reporter-tap.h → reporter-tap.h} +69 -69
  24. package/include/micro-os-plus/micro-test-plus/{test-reporter.h → reporter.h} +296 -200
  25. package/include/micro-os-plus/micro-test-plus/runner-totals.h +264 -0
  26. package/include/micro-os-plus/micro-test-plus/runner.h +453 -0
  27. package/include/micro-os-plus/micro-test-plus/test.h +1069 -0
  28. package/include/micro-os-plus/micro-test-plus/timings.h +366 -0
  29. package/include/micro-os-plus/micro-test-plus/type-traits.h +239 -545
  30. package/include/micro-os-plus/micro-test-plus/utility.h +135 -0
  31. package/include/micro-os-plus/micro-test-plus.h +25 -228
  32. package/meson.build +10 -6
  33. package/package.json +1 -1
  34. package/src/deferred-reporter.cpp +118 -0
  35. package/src/reflection.cpp +95 -0
  36. package/src/reporter-human.cpp +822 -0
  37. package/src/reporter-tap.cpp +782 -0
  38. package/src/reporter.cpp +676 -0
  39. package/src/runner-totals.cpp +95 -0
  40. package/src/runner.cpp +563 -0
  41. package/src/test.cpp +496 -0
  42. package/src/timings.cpp +209 -0
  43. package/src/utility.cpp +163 -0
  44. package/.cmake-format.yaml +0 -11
  45. package/include/micro-os-plus/micro-test-plus/inlines/micro-test-plus-inlines.h +0 -313
  46. package/include/micro-os-plus/micro-test-plus/test-runner.h +0 -281
  47. package/include/micro-os-plus/micro-test-plus/test-suite.h +0 -492
  48. package/src/micro-test-plus.cpp +0 -316
  49. package/src/test-reporter-basic.cpp +0 -466
  50. package/src/test-reporter-tap.cpp +0 -530
  51. package/src/test-reporter.cpp +0 -399
  52. package/src/test-runner.cpp +0 -311
  53. package/src/test-suite.cpp +0 -304
@@ -0,0 +1,126 @@
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 with declarations for the µTest++ exception-checking
21
+ * functions.
22
+ *
23
+ * @details
24
+ * This header provides the declarations for the exception-checking facilities
25
+ * of the µTest++ framework. It exposes three function templates —
26
+ * `throws<Exception_T>()`, `throws()`, and `nothrow()` — which allow test
27
+ * cases to verify that a callable throws a specific exception, throws any
28
+ * exception, or throws no exception, respectively.
29
+ *
30
+ * All declarations are conditionally compiled under `__cpp_exceptions` and
31
+ * reside within the `micro_os_plus::micro_test_plus` namespace, ensuring
32
+ * clear separation from user code and minimising the risk of naming conflicts.
33
+ *
34
+ * This header is located in the top-level `include/micro-os-plus` folder.
35
+ * Users should include `<micro-os-plus/micro-test-plus.h>` rather than this
36
+ * header directly.
37
+ */
38
+
39
+ #ifndef MICRO_TEST_PLUS_EXCEPTIONS_H_
40
+ #define MICRO_TEST_PLUS_EXCEPTIONS_H_
41
+
42
+ // ----------------------------------------------------------------------------
43
+
44
+ #ifdef __cplusplus
45
+
46
+ // ----------------------------------------------------------------------------
47
+
48
+ #if defined(MICRO_OS_PLUS_INCLUDE_CONFIG_H)
49
+ #include <micro-os-plus/config.h>
50
+ #endif // MICRO_OS_PLUS_INCLUDE_CONFIG_H
51
+
52
+ // ----------------------------------------------------------------------------
53
+
54
+ #if defined(__GNUC__)
55
+ #pragma GCC diagnostic push
56
+ #pragma GCC diagnostic ignored "-Waggregate-return"
57
+ #if defined(__clang__)
58
+ #pragma clang diagnostic ignored "-Wc++98-compat"
59
+ #endif
60
+ #endif
61
+
62
+ // ============================================================================
63
+
64
+ namespace micro_os_plus::micro_test_plus
65
+ {
66
+ // --------------------------------------------------------------------------
67
+
68
+ #if defined(__cpp_exceptions)
69
+
70
+ /**
71
+ * @ingroup micro-test-plus-exceptions
72
+ * @brief Check if a callable throws a specific exception.
73
+ *
74
+ * @tparam Exception_T The type of the exception expected to be thrown.
75
+ * @tparam Callable_T The type of the callable object to be invoked.
76
+ * @param [in] func The callable object to check for exception throwing
77
+ * behaviour.
78
+ * @return An output stream to write optional messages.
79
+ */
80
+ template <class Exception_T, class Callable_T>
81
+ [[nodiscard]] constexpr auto
82
+ throws (const Callable_T& func);
83
+
84
+ /**
85
+ * @ingroup micro-test-plus-exceptions
86
+ * @brief Check if a callable throws an exception (any exception).
87
+ *
88
+ * @tparam Callable_T The type of the callable object to be invoked.
89
+ * @param [in] func The callable object to check for exception throwing
90
+ * behaviour.
91
+ * @return An output stream to write optional messages.
92
+ */
93
+ template <class Callable_T>
94
+ [[nodiscard]] constexpr auto
95
+ throws (const Callable_T& func);
96
+
97
+ /**
98
+ * @ingroup micro-test-plus-exceptions
99
+ * @brief Check if a callable does not throw an exception.
100
+ *
101
+ * @tparam Callable_T The type of the callable object to be invoked.
102
+ * @param [in] func The callable object to check for exception safety.
103
+ * @return An output stream to write optional messages.
104
+ */
105
+ template <class Callable_T>
106
+ [[nodiscard]] constexpr auto
107
+ nothrow (const Callable_T& func);
108
+
109
+ #endif
110
+
111
+ // --------------------------------------------------------------------------
112
+ } // namespace micro_os_plus::micro_test_plus
113
+
114
+ #if defined(__GNUC__)
115
+ #pragma GCC diagnostic pop
116
+ #endif
117
+
118
+ // ----------------------------------------------------------------------------
119
+
120
+ #endif // __cplusplus
121
+
122
+ // ----------------------------------------------------------------------------
123
+
124
+ #endif // MICRO_TEST_PLUS_EXCEPTIONS_H_
125
+
126
+ // ----------------------------------------------------------------------------
@@ -24,10 +24,10 @@
24
24
  * This header provides the declarations for the function comparator templates
25
25
  * and logical operators used within the µTest++ framework. It defines the
26
26
  * interfaces for generic and pointer-based comparison functions, including
27
- * equality, non-equality, greater than, less than, and their respective
28
- * logical variants. Additionally, it declares logical combinators such as
29
- * conjunction (`_and`), disjunction (`_or`), and negation (`_not`), as well as
30
- * a utility for safely removing constness from objects.
27
+ * equality, non-equality, greater than, less than, greater than or equal,
28
+ * and less than or equal. Additionally, it declares logical combinators such
29
+ * as conjunction (`_and`), disjunction (`_or`), and negation (`_not`), as
30
+ * well as a utility for safely removing constness from objects.
31
31
  *
32
32
  * These comparators and logical operators enable expressive and type-safe test
33
33
  * expectations and assertions, supporting both value and pointer semantics.
@@ -62,10 +62,13 @@
62
62
  #pragma GCC diagnostic ignored "-Waggregate-return"
63
63
  #if defined(__clang__)
64
64
  #pragma clang diagnostic ignored "-Wc++98-compat"
65
+ #pragma clang diagnostic ignored "-Wpre-c++17-compat"
65
66
  #pragma clang diagnostic ignored "-Wunknown-warning-option"
66
67
  #endif
67
68
  #endif
68
69
 
70
+ // ===========================================================================
71
+
69
72
  namespace micro_os_plus::micro_test_plus
70
73
  {
71
74
  // --------------------------------------------------------------------------
@@ -315,13 +318,13 @@ namespace micro_os_plus::micro_test_plus
315
318
  [[nodiscard]] constexpr auto
316
319
  mut (const T& t) noexcept -> T&;
317
320
 
321
+ // --------------------------------------------------------------------------
322
+ } // namespace micro_os_plus::micro_test_plus
323
+
318
324
  #if defined(__GNUC__)
319
325
  #pragma GCC diagnostic pop
320
326
  #endif
321
327
 
322
- // --------------------------------------------------------------------------
323
- } // namespace micro_os_plus::micro_test_plus
324
-
325
328
  // ----------------------------------------------------------------------------
326
329
 
327
330
  #endif // __cplusplus
@@ -42,8 +42,8 @@
42
42
  * should not be included directly by user code.
43
43
  */
44
44
 
45
- #ifndef MICRO_TEST_PLUS_DETAILS_INLINES_H_
46
- #define MICRO_TEST_PLUS_DETAILS_INLINES_H_
45
+ #ifndef MICRO_TEST_PLUS_DEFERRED_REPORTER_INLINES_H_
46
+ #define MICRO_TEST_PLUS_DEFERRED_REPORTER_INLINES_H_
47
47
 
48
48
  // ----------------------------------------------------------------------------
49
49
 
@@ -51,9 +51,8 @@
51
51
 
52
52
  // ----------------------------------------------------------------------------
53
53
 
54
- #include <stdio.h>
55
- #include <cstring>
56
- // #include "test-reporter.h"
54
+ #include <charconv>
55
+ #include <cstdio>
57
56
 
58
57
  // ----------------------------------------------------------------------------
59
58
 
@@ -66,6 +65,8 @@
66
65
  #endif
67
66
  #endif
68
67
 
68
+ // ============================================================================
69
+
69
70
  namespace micro_os_plus::micro_test_plus
70
71
  {
71
72
  // --------------------------------------------------------------------------
@@ -80,22 +81,45 @@ namespace micro_os_plus::micro_test_plus
80
81
  * expectation messages by appending the provided value to the internal
81
82
  * message string.
82
83
  *
83
- * If the argument is of an arithmetic type, it is first converted to a
84
- * string using `std::to_string` before being appended. For all other
85
- * types, the value is appended directly. This ensures that both numeric
86
- * and string-like messages are handled appropriately and consistently.
84
+ * If the argument is a `char`, it is appended directly as a character.
85
+ * If the argument is of another arithmetic type, it is converted to a
86
+ * string using a fixed-size buffer and `std::to_chars` to avoid dynamic
87
+ * memory allocation. For all other types, the value is appended directly.
87
88
  */
88
89
  template <class T>
90
+ requires type_traits::printable<T>
89
91
  auto&
90
92
  deferred_reporter_base::operator<< (const T& msg)
91
93
  {
92
- if constexpr (std::is_arithmetic_v<T>)
94
+ if constexpr (std::is_same_v<T, char>)
95
+ {
96
+ deferred_output_.push_back (msg);
97
+ }
98
+ else if constexpr (std::is_arithmetic_v<T>)
93
99
  {
94
- message_.append (std::to_string (msg));
100
+ // Optimise to avoid dynamic memory allocation in std::to_string by
101
+ // using a fixed-size buffer and std::to_chars.
102
+ #if defined(__GNUC__)
103
+ #pragma GCC diagnostic push
104
+ #if defined(__clang__)
105
+ #pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
106
+ #endif
107
+ #endif
108
+ char buf[64];
109
+ // 64 bytes is sufficient for the longest decimal representation
110
+ // of any standard arithmetic type (long double ~45 chars).
111
+ static_assert (sizeof (buf) >= 50,
112
+ "buf must be large enough for any arithmetic type");
113
+ auto [ptr, ec] = std::to_chars (buf, buf + sizeof (buf), msg);
114
+ if (ec == std::errc{})
115
+ deferred_output_.append (buf, ptr);
116
+ #if defined(__GNUC__)
117
+ #pragma GCC diagnostic pop
118
+ #endif
95
119
  }
96
120
  else
97
121
  {
98
- message_.append (msg);
122
+ deferred_output_.append (msg);
99
123
  }
100
124
  return *this;
101
125
  }
@@ -114,15 +138,17 @@ namespace micro_os_plus::micro_test_plus
114
138
  * contextual information for reporting purposes.
115
139
  */
116
140
  template <class Expr_T>
117
- constexpr deferred_reporter<Expr_T>::deferred_reporter (
141
+ deferred_reporter<Expr_T>::deferred_reporter (
118
142
  const Expr_T& expr, bool abort,
119
- const reflection::source_location& location)
120
- : deferred_reporter_base{ static_cast<bool> (expr), location },
143
+ const reflection::source_location& location, subtest& subtest)
144
+ : deferred_reporter_base{ static_cast<bool> (expr), location,
145
+ subtest },
121
146
  expr_{ expr }
122
147
  {
123
- #if 0 // defined(MICRO_OS_PLUS_TRACE_MICRO_TEST_PLUS)
124
- printf ("%s\n", __PRETTY_FUNCTION__);
125
- #endif // MICRO_OS_PLUS_TRACE_MICRO_TEST_PLUS
148
+ #if defined(MICRO_OS_PLUS_TRACE) \
149
+ && defined(MICRO_OS_PLUS_TRACE_MICRO_TEST_PLUS_CONSTRUCTORS)
150
+ trace::printf ("%s\n", __PRETTY_FUNCTION__);
151
+ #endif // MICRO_OS_PLUS_TRACE_MICRO_TEST_PLUS_CONSTRUCTORS
126
152
  abort_ = abort;
127
153
  }
128
154
 
@@ -141,13 +167,14 @@ namespace micro_os_plus::micro_test_plus
141
167
  template <class Expr_T>
142
168
  deferred_reporter<Expr_T>::~deferred_reporter ()
143
169
  {
144
- if (value_)
170
+ if (value_) [[likely]]
145
171
  {
146
- reporter->pass (expr_, message_);
172
+ subtest_.reporter ().pass (expr_, deferred_output_, subtest_);
147
173
  }
148
174
  else
149
175
  {
150
- reporter->fail (expr_, abort_, message_, location_);
176
+ subtest_.reporter ().fail (expr_, abort_, deferred_output_,
177
+ location_, subtest_);
151
178
  }
152
179
  }
153
180
 
@@ -167,6 +194,6 @@ namespace micro_os_plus::micro_test_plus
167
194
 
168
195
  // ----------------------------------------------------------------------------
169
196
 
170
- #endif // MICRO_TEST_PLUS_DETAILS_INLINES_H_
197
+ #endif // MICRO_TEST_PLUS_DEFERRED_REPORTER_INLINES_H_
171
198
 
172
199
  // ----------------------------------------------------------------------------
@@ -55,10 +55,6 @@
55
55
 
56
56
  // ----------------------------------------------------------------------------
57
57
 
58
- // #include "detail.h"
59
-
60
- // ----------------------------------------------------------------------------
61
-
62
58
  #if defined(__GNUC__)
63
59
  #pragma GCC diagnostic push
64
60
  #pragma GCC diagnostic ignored "-Waggregate-return"
@@ -68,6 +64,8 @@
68
64
  #endif
69
65
  #endif
70
66
 
67
+ // ===========================================================================
68
+
71
69
  namespace micro_os_plus::micro_test_plus
72
70
  {
73
71
  // --------------------------------------------------------------------------
@@ -254,6 +252,9 @@ namespace micro_os_plus::micro_test_plus
254
252
  return detail::le_<Lhs_T*, Rhs_T*>{ lhs, rhs };
255
253
  }
256
254
 
255
+ // --------------------------------------------------------------------------
256
+ // Logical operators.
257
+
257
258
  /**
258
259
  * @details
259
260
  * The `_not` function template provides a generic logical negation for any
@@ -308,6 +309,68 @@ namespace micro_os_plus::micro_test_plus
308
309
  return detail::or_<Lhs_T, Rhs_T>{ lhs, rhs };
309
310
  }
310
311
 
312
+ // --------------------------------------------------------------------------
313
+ // Exceptions related comparators.
314
+
315
+ #if defined(__cpp_exceptions)
316
+
317
+ /**
318
+ * @details
319
+ * The `throws` function template verifies whether invoking the provided
320
+ * callable object results in the throwing of a specific exception type
321
+ * within the µTest++ framework. This is useful for testing error handling
322
+ * and exception safety in code under test.
323
+ *
324
+ * The function returns an output stream, allowing optional messages to be
325
+ * appended to the test report for diagnostic purposes.
326
+ */
327
+ template <class Exception_T, class Callable_T>
328
+ [[nodiscard]] constexpr auto
329
+ throws (const Callable_T& func)
330
+ {
331
+ return detail::throws_<Callable_T, Exception_T>{ func };
332
+ }
333
+
334
+ /**
335
+ * @details
336
+ * The `throws` function template verifies whether invoking the provided
337
+ * callable object results in the throwing of any exception within the
338
+ * µTest++ framework. This is useful for testing general exception safety and
339
+ * ensuring that code under test properly signals error conditions.
340
+ *
341
+ * The function returns an output stream, allowing optional messages to be
342
+ * appended to the test report for diagnostic purposes.
343
+ */
344
+ template <class Callable_T>
345
+ [[nodiscard]] constexpr auto
346
+ throws (const Callable_T& func)
347
+ {
348
+ return detail::throws_<Callable_T>{ func };
349
+ }
350
+
351
+ /**
352
+ * @details
353
+ * The `nothrow` function template verifies whether invoking the provided
354
+ * callable object does not result in the throwing of any exception within
355
+ * the µTest++ framework. This is useful for testing exception safety and
356
+ * ensuring that code under test does not unexpectedly signal error
357
+ * conditions.
358
+ *
359
+ * The function returns an output stream, allowing optional messages to be
360
+ * appended to the test report for diagnostic purposes.
361
+ */
362
+ template <class Callable_T>
363
+ [[nodiscard]] constexpr auto
364
+ nothrow (const Callable_T& func)
365
+ {
366
+ return detail::nothrow_<Callable_T>{ func };
367
+ }
368
+
369
+ #endif // defined(__cpp_exceptions)
370
+
371
+ // --------------------------------------------------------------------------
372
+ // Utility functions.
373
+
311
374
  /**
312
375
  * @details
313
376
  * The `mut` function template provides a safe and generic mechanism to
@@ -58,8 +58,6 @@
58
58
 
59
59
  #include <cstdint>
60
60
 
61
- // #include "type-traits.h"
62
-
63
61
  // ----------------------------------------------------------------------------
64
62
 
65
63
  #if defined(__GNUC__)
@@ -71,6 +69,8 @@
71
69
  #endif
72
70
  #endif
73
71
 
72
+ // ===========================================================================
73
+
74
74
  namespace micro_os_plus::micro_test_plus
75
75
  {
76
76
  // --------------------------------------------------------------------------
@@ -509,9 +509,7 @@ namespace micro_os_plus::micro_test_plus
509
509
  *
510
510
  * The returned type is a lightweight wrapper that behaves as a `bool` and
511
511
  * supports equality comparison with both other named instances and boolean
512
- * values.
513
- *
514
- * @note This operator is intended to facilitate expressive and type-safe
512
+ * values. This operator is intended to facilitate expressive and type-safe
515
513
  * test conditions.
516
514
  */
517
515
  constexpr auto
@@ -523,7 +521,6 @@ namespace micro_os_plus::micro_test_plus
523
521
  * @details
524
522
  * This structure inherits from `std::string_view` and a type trait base,
525
523
  * providing a strongly-typed boolean value for use in test expressions.
526
- *
527
524
  * It defines conversion to `bool` and equality operators for comparison
528
525
  * with other named instances and boolean values.
529
526
  */
@@ -56,8 +56,6 @@
56
56
 
57
57
  #include <cstdint>
58
58
 
59
- // #include "type-traits.h"
60
-
61
59
  // ----------------------------------------------------------------------------
62
60
 
63
61
  #if defined(__GNUC__)
@@ -66,9 +64,12 @@
66
64
  #if defined(__clang__)
67
65
  #pragma clang diagnostic ignored "-Wc++98-compat"
68
66
  #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
67
+ #pragma clang diagnostic ignored "-Wc++20-compat"
69
68
  #endif
70
69
  #endif
71
70
 
71
+ // ============================================================================
72
+
72
73
  namespace micro_os_plus::micro_test_plus
73
74
  {
74
75
  // --------------------------------------------------------------------------
@@ -93,7 +94,7 @@ namespace micro_os_plus::micro_test_plus
93
94
  */
94
95
  template <class T>
95
96
  [[nodiscard]] constexpr auto
96
- abs (const T t) -> T
97
+ abs (const T t) noexcept -> T
97
98
  {
98
99
  return t < T{} ? -t : t;
99
100
  }
@@ -114,7 +115,7 @@ namespace micro_os_plus::micro_test_plus
114
115
  */
115
116
  template <class T>
116
117
  [[nodiscard]] constexpr auto
117
- min_value (const T& lhs, const T& rhs) -> const T&
118
+ min_value (const T& lhs, const T& rhs) noexcept -> const T&
118
119
  {
119
120
  return (rhs < lhs) ? rhs : lhs;
120
121
  }
@@ -123,9 +124,9 @@ namespace micro_os_plus::micro_test_plus
123
124
  * @details
124
125
  * This function template provides a constexpr implementation for raising a
125
126
  * base value to a given exponent, supporting any types that allow
126
- * multiplication and subtraction.
127
+ * multiplication.
127
128
  *
128
- * The function recursively multiplies the base by itself exponent times.
129
+ * The function iteratively multiplies the base by itself exponent times.
129
130
  * If the exponent is zero, the function returns one (the multiplicative
130
131
  * identity for the type).
131
132
  *
@@ -135,10 +136,12 @@ namespace micro_os_plus::micro_test_plus
135
136
  */
136
137
  template <class T, class Exp_T>
137
138
  [[nodiscard]] constexpr auto
138
- pow (const T base, const Exp_T exp) -> T
139
+ pow (const T base, const Exp_T exp) noexcept -> T
139
140
  {
140
- // If the exponent is 0, return 1, otherwise recurse.
141
- return exp ? T (base * pow (base, exp - Exp_T (1))) : T (1);
141
+ T result{ 1 };
142
+ for (Exp_T i{}; i < exp; ++i)
143
+ result *= base;
144
+ return result;
142
145
  }
143
146
 
144
147
  /**
@@ -156,7 +159,7 @@ namespace micro_os_plus::micro_test_plus
156
159
  * conversion from character sequences to integral values.
157
160
  */
158
161
  template <class T, char... Cs>
159
- [[nodiscard]] constexpr auto
162
+ [[nodiscard]] consteval auto
160
163
  num (void) -> T
161
164
  {
162
165
  // Assume all are digits or dot or apostrophe.
@@ -196,9 +199,11 @@ namespace micro_os_plus::micro_test_plus
196
199
  * values.
197
200
  */
198
201
  template <class T, char... Cs>
199
- [[nodiscard]] constexpr auto
202
+ [[nodiscard]] consteval auto
200
203
  den (void) -> T
201
204
  {
205
+ static_assert ((... || (Cs == '.')),
206
+ "den(): no decimal point in literal");
202
207
  constexpr const std::array cs{ Cs... };
203
208
  T result{};
204
209
  auto i = 0u;
@@ -229,9 +234,11 @@ namespace micro_os_plus::micro_test_plus
229
234
  * determination of decimal precision from character sequences.
230
235
  */
231
236
  template <class T, char... Cs>
232
- [[nodiscard]] constexpr auto
237
+ [[nodiscard]] consteval auto
233
238
  den_size (void) -> T
234
239
  {
240
+ static_assert ((... || (Cs == '.')),
241
+ "den_size(): no decimal point in literal");
235
242
  constexpr const std::array cs{ Cs... };
236
243
  T i{};
237
244
  #if defined(__GNUC__)
@@ -276,11 +283,10 @@ namespace micro_os_plus::micro_test_plus
276
283
  value *= 10;
277
284
  #if defined(__GNUC__)
278
285
  #pragma GCC diagnostic push
279
- #if !defined(__clang__) // GCC only
280
- #pragma GCC diagnostic ignored "-Warith-conversion"
281
- #endif
282
286
  #if defined(__clang__)
283
287
  #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion"
288
+ #else // GCC only
289
+ #pragma GCC diagnostic ignored "-Warith-conversion"
284
290
  #endif
285
291
  #endif
286
292
  tmp = value - T (value);
@@ -56,8 +56,6 @@
56
56
 
57
57
  #include <cstdint>
58
58
 
59
- // #include "type-traits.h"
60
-
61
59
  // ----------------------------------------------------------------------------
62
60
 
63
61
  #if defined(__GNUC__)
@@ -69,6 +67,8 @@
69
67
  #endif
70
68
  #endif
71
69
 
70
+ // ============================================================================
71
+
72
72
  namespace micro_os_plus::micro_test_plus
73
73
  {
74
74
  // --------------------------------------------------------------------------
@@ -98,7 +98,8 @@ namespace micro_os_plus::micro_test_plus
98
98
 
99
99
  /**
100
100
  * @details
101
- * ... TBD
101
+ * Returns the file name captured at the time this `source_location`
102
+ * instance was created.
102
103
  */
103
104
  [[nodiscard]] constexpr auto
104
105
  source_location::file_name (void) const noexcept
@@ -108,7 +109,8 @@ namespace micro_os_plus::micro_test_plus
108
109
 
109
110
  /**
110
111
  * @details
111
- * ... TBD
112
+ * Returns the line number captured at the time this `source_location`
113
+ * instance was created.
112
114
  */
113
115
  [[nodiscard]] constexpr auto
114
116
  source_location::line (void) const noexcept
@@ -124,29 +126,45 @@ namespace micro_os_plus::micro_test_plus
124
126
  * `__PRETTY_FUNCTION__` macro to extract a concise type name for the
125
127
  * template parameter \c T.
126
128
  *
127
- * The implementation is compiler-dependent and may require adjustment for
128
- * different toolchains. It is primarily intended for internal use within
129
- * the µTest++ framework to support improved diagnostics and reporting.
129
+ * Rather than relying on fixed character offsets (which are fragile across
130
+ * compiler versions and namespace changes), the implementation searches
131
+ * for well-known marker characters in the function signature string:
132
+ *
133
+ * - Clang formats the signature as `"... [T = <typename>]"`, so the type
134
+ * name lies between the last `'['` (skipping `"[T = "`) and the last
135
+ * `']'`.
136
+ * - GCC formats the signature as `"... [with T = <typename>]"`, so the
137
+ * type name lies between the last `'='` (skipping the trailing space)
138
+ * and the last `']'`.
139
+ *
140
+ * This approach is resilient to namespace renaming, namespace nesting
141
+ * changes, and compiler format updates.
130
142
  */
131
143
  template <class T>
132
144
  [[nodiscard]] constexpr auto
133
145
  type_name (void) -> std::string_view
134
146
  {
147
+ const std::string_view sv = __PRETTY_FUNCTION__;
135
148
  #if defined(__clang__)
136
- #pragma GCC diagnostic push
137
- #pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
138
- // printf("|%s|%zu|\n", __PRETTY_FUNCTION__, sizeof
139
- // (__PRETTY_FUNCTION__)); printf("|%s|\n", &__PRETTY_FUNCTION__[78]);
140
- return { &__PRETTY_FUNCTION__[78], sizeof (__PRETTY_FUNCTION__) - 80 };
141
- #pragma GCC diagnostic pop
149
+ // Clang: "... [T = <typename>]"
150
+ // rfind('[') locates the opening bracket of "[T = ...]".
151
+ const auto start = sv.rfind ('[') + 5; // skip "[T = "
152
+ const auto end = sv.rfind (']');
142
153
  #elif defined(__GNUC__)
143
- // printf("|%s|%zu|\n", __PRETTY_FUNCTION__, sizeof
144
- // (__PRETTY_FUNCTION__)); printf("|%s|\n", &__PRETTY_FUNCTION__[93]);
145
- return { &__PRETTY_FUNCTION__[93], sizeof (__PRETTY_FUNCTION__) - 144 };
154
+ // GCC: "... [with T = <typename>]" or, on some versions,
155
+ // "... [with T = <typename>; std::string_view = ...]"
156
+ // Search for "T = " explicitly to avoid landing on a later '='.
157
+ const auto t_eq = sv.find ("T = ");
158
+ const auto start = t_eq + 4; // skip "T = "
159
+ const auto semi = sv.find (';', start);
160
+ const auto end
161
+ = (semi != std::string_view::npos) ? semi : sv.rfind (']');
146
162
  #else
163
+ // Note: MSVC uses __FUNCSIG__ instead of __PRETTY_FUNCTION__.
164
+ // MSVC is not a supported target for this framework.
147
165
  #error "Unsupported compiler"
148
- return "Unsupported compiler";
149
166
  #endif
167
+ return sv.substr (start, end - start);
150
168
  }
151
169
 
152
170
  // ------------------------------------------------------------------------