Skip to main content

detail.h File

C++ header file with declarations for the µTest++ internals. More...

Included Headers

#include "type-traits.h" #include "reflection.h" #include <cstdio> #include <string> #include "inlines/detail-inlines.h"

Namespaces Index

namespacemicro_os_plus

The primary namespace for the µOS++ framework. More...

namespacemicro_test_plus

Primary namespace for the µTest++ testing framework. More...

namespacedetail

Internal implementation details for the µTest++ framework. More...

Classes Index

structand_<Lhs_T, Rhs_T>

Logical AND comparator struct template. More...

structassertion<Expr_T>

Assertion struct template for parameter passing to the evaluator. More...

structbinary_op_<Lhs_T, Rhs_T>

Common base struct template for binary comparators. More...

structcallable_op_

Common base struct for callable-wrapping operators. More...

structeq_<Lhs_T, Rhs_T>

Equality comparator struct template. More...

structge_<Lhs_T, Rhs_T>

Greater than or equal comparator struct template. More...

structgt_<Lhs_T, Rhs_T>

Greater than comparator struct template. More...

structle_<Lhs_T, Rhs_T>

Less than or equal comparator struct template. More...

structlt_<Lhs_T, Rhs_T>

Less than comparator struct template. More...

structne_<Lhs_T, Rhs_T>

Non-equality comparator struct template. More...

structnot_<T>

Logical NOT comparator struct template. More...

structnothrow_<Callable_T>

Operator struct template to check if an expression does not throw any exception. More...

structor_<Lhs_T, Rhs_T>

Logical OR comparator struct template. More...

structthrows_<Callable_T, Exception_T>

Operator struct template to check if an expression throws a specific exception. More...

structthrows_<Callable_T, void>

Operator struct template to check if an expression throws any exception. More...

structunary_op_<T>

Common base struct template for unary comparators. More...

Functions Index

template <typename Lhs_T, typename Rhs_T>
and_ (const Lhs_T &, const Rhs_T &) -> and_< Lhs_T, Rhs_T >
template <class T>
voidappend_number_ (std::string &buffer, T v)

Appends the string representation of a numeric value to a buffer, using std::to_chars for allocation-free, locale-independent formatting. More...

template <typename Lhs_T, typename Rhs_T>
eq_ (const Lhs_T &, const Rhs_T &) -> eq_< Lhs_T, Rhs_T >
template <typename Lhs_T, typename Rhs_T>
ge_ (const Lhs_T &, const Rhs_T &) -> ge_< Lhs_T, Rhs_T >
template <class T>
constexpr autoget (const T &t)

Generic getter function template for value retrieval. More...

template <typename Lhs_T, typename Rhs_T>
gt_ (const Lhs_T &, const Rhs_T &) -> gt_< Lhs_T, Rhs_T >
template <typename Lhs_T, typename Rhs_T>
le_ (const Lhs_T &, const Rhs_T &) -> le_< Lhs_T, Rhs_T >
template <typename Lhs_T, typename Rhs_T>
lt_ (const Lhs_T &, const Rhs_T &) -> lt_< Lhs_T, Rhs_T >
template <typename Lhs_T, typename Rhs_T>
ne_ (const Lhs_T &, const Rhs_T &) -> ne_< Lhs_T, Rhs_T >
template <typename T>
not_ (const T &) -> not_< T >
template <typename Lhs_T, typename Rhs_T>
or_ (const Lhs_T &, const Rhs_T &) -> or_< Lhs_T, Rhs_T >

Description

C++ header file with declarations for the µTest++ internals.

This header provides the declarations for the internal components of the µTest++ framework, encapsulated within the micro_os_plus::micro_test_plus::detail namespace. It defines the core mechanisms, helper structures, and utility templates that underpin the framework's assertion handling, value retrieval, comparator logic, deferred reporting, and exception checking facilities.

All definitions reside within the micro_os_plus::micro_test_plus::detail namespace, ensuring clear separation from user code and minimising the risk of naming conflicts.

The header files are organised within the include/micro-os-plus/micro-test-plus folder to maintain a structured and modular codebase.

This file is intended solely for internal use within the framework and should not be included directly by user code.

Functions

and_()

template <typename Lhs_T, typename Rhs_T>
micro_os_plus::micro_test_plus::detail::and_ (const Lhs_T &, const Rhs_T &)

Definition at line 524 of file detail.h.

append_number_()

template <class T>
void micro_os_plus::micro_test_plus::detail::append_number_ (std::string & buffer, T v)

Appends the string representation of a numeric value to a buffer, using std::to_chars for allocation-free, locale-independent formatting.

Template Parameters
T

The numeric type to format.

Parameters
buffer

The string to append to.

v

The value to format.

Returns

Nothing.

For long double, a platform-specific path is chosen:

  • On Windows and on platforms where long double has the same storage width as double (e.g., ARM, RISC-V), the value is cast to double and formatted with std::to_chars.
  • On x86-64 Linux/macOS with 80-bit extended precision, snprintf with Lg is used as a portable fallback because std::to_chars for long double may be unavailable when linking with lld.

For all other numeric types, std::to_chars is called directly, providing locale-independent, allocation-free formatting.

Definition at line 674 of file detail-inlines.h.

674 append_number_ (std::string& buffer, const T v)
675 {
676 char buf[32];
677 if constexpr (std::is_same_v<T, long double>)
678 {
679#if defined(_WIN32) \
680 || (defined(__SIZEOF_LONG_DOUBLE__) \
681 && __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__)
682 // On Windows (all toolchains: MinGW, Clang, MSVC), the C runtime
683 // does not handle the %Lg printf specifier correctly for 80-bit
684 // long double, producing garbage output. On platforms where long
685 // double has the same width as double (ARM, RISC-V), the cast is
686 // lossless. In both cases, cast to double and use std::to_chars.
687 const auto [ptr, ec] = std::to_chars (buf, buf + sizeof (buf),
688 static_cast<double> (v));
689 if (ec == std::errc{})
690 buffer.append (buf, ptr);
691#else
692 // On x86-64 Linux/macOS with 80-bit extended-precision long double,
693 // std::to_chars for long double may be unavailable (e.g., with lld).
694 // Use snprintf as a portable fallback; %Lg is supported correctly
695 // by glibc and libc++ on these platforms.
696 snprintf (buf, sizeof (buf), "%Lg", v);
697 buffer.append (buf);
698#endif // defined(_WIN32) || (defined(__SIZEOF_LONG_DOUBLE__) && __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__)
699 }
700 else
701 {
702 const auto [ptr, ec] = std::to_chars (buf, buf + sizeof (buf), v);
703 if (ec == std::errc{})
704 buffer.append (buf, ptr);
705 }
706 }

Referenced by micro_os_plus::micro_test_plus::detail::expression_formatter::operator<<, micro_os_plus::micro_test_plus::detail::expression_formatter::operator<<, micro_os_plus::micro_test_plus::detail::expression_formatter::operator<<, micro_os_plus::micro_test_plus::detail::expression_formatter::operator<<, micro_os_plus::micro_test_plus::detail::expression_formatter::operator<<, micro_os_plus::micro_test_plus::detail::expression_formatter::operator<<, micro_os_plus::micro_test_plus::detail::expression_formatter::operator<<, micro_os_plus::micro_test_plus::detail::expression_formatter::operator<<, micro_os_plus::micro_test_plus::detail::expression_formatter::operator<<, micro_os_plus::micro_test_plus::detail::expression_formatter::operator<<, micro_os_plus::micro_test_plus::detail::expression_formatter::operator<<, micro_os_plus::micro_test_plus::detail::expression_formatter::operator<<, micro_os_plus::micro_test_plus::detail::expression_formatter::operator<<, micro_os_plus::micro_test_plus::detail::expression_formatter::operator<< and micro_os_plus::micro_test_plus::reporter::operator<<.

eq_()

template <typename Lhs_T, typename Rhs_T>
micro_os_plus::micro_test_plus::detail::eq_ (const Lhs_T &, const Rhs_T &)

Definition at line 327 of file detail.h.

ge_()

template <typename Lhs_T, typename Rhs_T>
micro_os_plus::micro_test_plus::detail::ge_ (const Lhs_T &, const Rhs_T &)

Definition at line 425 of file detail.h.

get()

template <class T>
auto micro_os_plus::micro_test_plus::detail::get (const T & t)
nodiscard constexpr

Generic getter function template for value retrieval.

Template Parameters
T

The type from which the value is to be retrieved.

Parameters
t

The object or value to be accessed.

Returns

The value obtained via the relevant getter implementation.

If the type T provides a get() member function, it is invoked and its result returned. Otherwise the argument itself is returned unchanged. The selection is performed at compile time via if constexpr with an inline requires expression.

Definition at line 83 of file detail-inlines.h.

83 get (const T& t)
84 {
85 if constexpr (requires { t.get (); })
86 return t.get ();
87 else
88 return t;
89 }

Referenced by micro_os_plus::micro_test_plus::detail::eq_< Lhs_T, Rhs_T >::eq_, micro_os_plus::micro_test_plus::detail::ge_< Lhs_T, Rhs_T >::ge_, micro_os_plus::micro_test_plus::detail::gt_< Lhs_T, Rhs_T >::gt_, micro_os_plus::micro_test_plus::detail::le_< Lhs_T, Rhs_T >::le_, micro_os_plus::micro_test_plus::detail::lt_< Lhs_T, Rhs_T >::lt_, micro_os_plus::micro_test_plus::detail::ne_< Lhs_T, Rhs_T >::ne_, micro_os_plus::micro_test_plus::detail::binary_op_< Lhs_T, Rhs_T >::lhs, micro_os_plus::micro_test_plus::detail::unary_op_< T >::operand, micro_os_plus::micro_test_plus::detail::expression_formatter::operator<< and micro_os_plus::micro_test_plus::detail::binary_op_< Lhs_T, Rhs_T >::rhs.

gt_()

template <typename Lhs_T, typename Rhs_T>
micro_os_plus::micro_test_plus::detail::gt_ (const Lhs_T &, const Rhs_T &)

Definition at line 391 of file detail.h.

le_()

template <typename Lhs_T, typename Rhs_T>
micro_os_plus::micro_test_plus::detail::le_ (const Lhs_T &, const Rhs_T &)

Definition at line 491 of file detail.h.

lt_()

template <typename Lhs_T, typename Rhs_T>
micro_os_plus::micro_test_plus::detail::lt_ (const Lhs_T &, const Rhs_T &)

Definition at line 457 of file detail.h.

ne_()

template <typename Lhs_T, typename Rhs_T>
micro_os_plus::micro_test_plus::detail::ne_ (const Lhs_T &, const Rhs_T &)

Definition at line 359 of file detail.h.

not_()

template <typename T>
micro_os_plus::micro_test_plus::detail::not_ (const T &)

Definition at line 587 of file detail.h.

or_()

template <typename Lhs_T, typename Rhs_T>
micro_os_plus::micro_test_plus::detail::or_ (const Lhs_T &, const Rhs_T &)

Definition at line 557 of file detail.h.

File Listing

The file content with the documentation metadata removed is:

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 Software License,
13 * which can be obtained from https://www.boost.org/LICENSE_1_0.txt.
14 */
15
16// ----------------------------------------------------------------------------
17
41
42#ifndef MICRO_OS_PLUS_MICRO_TEST_PLUS_DETAIL_H_
43#define MICRO_OS_PLUS_MICRO_TEST_PLUS_DETAIL_H_
44
45// ----------------------------------------------------------------------------
46
47#if defined(__cplusplus)
48
49// ----------------------------------------------------------------------------
50
51#if __has_include("micro-os-plus/project-config.h")
52#include "micro-os-plus/project-config.h"
53#endif // __has_include("micro-os-plus/project-config.h")
54
55#if __has_include("micro-os-plus/micro-test-plus-defines.h")
56#include "micro-os-plus/micro-test-plus-defines.h"
57#endif // __has_include("micro-os-plus/micro-test-plus-defines.h")
58
59#include "type-traits.h"
60#include "reflection.h"
61
62#include <cstdio>
63#include <string>
64
65// ----------------------------------------------------------------------------
66
67#if defined(__GNUC__)
68#pragma GCC diagnostic push
69
70#pragma GCC diagnostic ignored "-Wpadded"
71#pragma GCC diagnostic ignored "-Waggregate-return"
72#if defined(__clang__)
73#pragma clang diagnostic ignored "-Wc++98-compat"
74#endif // defined(__clang__)
75#endif // defined(__GNUC__)
76
77// ============================================================================
78
80{
81 class test_node;
82
83 // --------------------------------------------------------------------------
84
108 namespace detail
109 {
110 // ========================================================================
111
125 template <class Expr_T>
126 struct assertion
127 {
131 Expr_T expr{};
132
137 };
138
139 // ========================================================================
140
149 template <class T>
150 [[nodiscard]] constexpr auto
151 get (const T& t);
152
153 // ========================================================================
154
169 template <class T>
171 {
179 constexpr unary_op_ (const T& t, bool value);
180
188 [[nodiscard]] constexpr
189 operator bool () const;
190
198 [[nodiscard]] constexpr auto
199 operand () const;
200
201 private:
205 const T t_{};
206
210 const bool value_{};
211 };
212
213 // ========================================================================
214
231 template <class Lhs_T, class Rhs_T>
233 {
242 constexpr binary_op_ (const Lhs_T& lhs, const Rhs_T& rhs, bool value);
243
251 [[nodiscard]] constexpr
252 operator bool () const;
253
261 [[nodiscard]] constexpr auto
262 lhs (void) const;
263
271 [[nodiscard]] constexpr auto
272 rhs (void) const;
273
274 private:
281 const Lhs_T lhs_{};
282
289 const Rhs_T rhs_{};
290
294 const bool value_{};
295 };
296
297 // ========================================================================
298
313 template <class Lhs_T, class Rhs_T>
314 struct eq_ : binary_op_<Lhs_T, Rhs_T>
315 {
322 constexpr eq_ (const Lhs_T& lhs = {}, const Rhs_T& rhs = {});
323 };
324
325 // Deduction guide.
326 template <typename Lhs_T, typename Rhs_T>
327 eq_ (const Lhs_T&, const Rhs_T&) -> eq_<Lhs_T, Rhs_T>;
328
329 // ========================================================================
330
345 template <class Lhs_T, class Rhs_T>
346 struct ne_ : binary_op_<Lhs_T, Rhs_T>
347 {
354 constexpr ne_ (const Lhs_T& lhs = {}, const Rhs_T& rhs = {});
355 };
356
357 // Deduction guide.
358 template <typename Lhs_T, typename Rhs_T>
359 ne_ (const Lhs_T&, const Rhs_T&) -> ne_<Lhs_T, Rhs_T>;
360
361 // ========================================================================
362
377 template <class Lhs_T, class Rhs_T>
378 struct gt_ : binary_op_<Lhs_T, Rhs_T>
379 {
386 constexpr gt_ (const Lhs_T& lhs = {}, const Rhs_T& rhs = {});
387 };
388
389 // Deduction guide.
390 template <typename Lhs_T, typename Rhs_T>
391 gt_ (const Lhs_T&, const Rhs_T&) -> gt_<Lhs_T, Rhs_T>;
392
393 // ========================================================================
394
410 template <class Lhs_T, class Rhs_T>
411 struct ge_ : binary_op_<Lhs_T, Rhs_T>
412 {
420 constexpr ge_ (const Lhs_T& lhs = {}, const Rhs_T& rhs = {});
421 };
422
423 // Deduction guide.
424 template <typename Lhs_T, typename Rhs_T>
425 ge_ (const Lhs_T&, const Rhs_T&) -> ge_<Lhs_T, Rhs_T>;
426
427 // ========================================================================
428
443 template <class Lhs_T, class Rhs_T>
444 struct lt_ : binary_op_<Lhs_T, Rhs_T>
445 {
452 constexpr lt_ (const Lhs_T& lhs = {}, const Rhs_T& rhs = {});
453 };
454
455 // Deduction guide.
456 template <typename Lhs_T, typename Rhs_T>
457 lt_ (const Lhs_T&, const Rhs_T&) -> lt_<Lhs_T, Rhs_T>;
458
459 // ========================================================================
460
476 template <class Lhs_T, class Rhs_T>
477 struct le_ : binary_op_<Lhs_T, Rhs_T>
478 {
486 constexpr le_ (const Lhs_T& lhs = {}, const Rhs_T& rhs = {});
487 };
488
489 // Deduction guide.
490 template <typename Lhs_T, typename Rhs_T>
491 le_ (const Lhs_T&, const Rhs_T&) -> le_<Lhs_T, Rhs_T>;
492
493 // ========================================================================
494
510 template <class Lhs_T, class Rhs_T>
511 struct and_ : binary_op_<Lhs_T, Rhs_T>
512 {
519 constexpr and_ (const Lhs_T& lhs = {}, const Rhs_T& rhs = {});
520 };
521
522 // Deduction guide.
523 template <typename Lhs_T, typename Rhs_T>
524 and_ (const Lhs_T&, const Rhs_T&) -> and_<Lhs_T, Rhs_T>;
525
526 // ========================================================================
527
543 template <class Lhs_T, class Rhs_T>
544 struct or_ : binary_op_<Lhs_T, Rhs_T>
545 {
552 constexpr or_ (const Lhs_T& lhs = {}, const Rhs_T& rhs = {});
553 };
554
555 // Deduction guide.
556 template <typename Lhs_T, typename Rhs_T>
557 or_ (const Lhs_T&, const Rhs_T&) -> or_<Lhs_T, Rhs_T>;
558
559 // ========================================================================
560
574 template <class T>
575 struct not_ : unary_op_<T>
576 {
582 explicit constexpr not_ (const T& t = {});
583 };
584
585 // Deduction guide.
586 template <typename T>
587 not_ (const T&) -> not_<T>;
588
589 // ========================================================================
590
591#if defined(__cpp_exceptions)
592
607 {
614 constexpr explicit callable_op_ (bool value);
615
623 [[nodiscard]] constexpr
624 operator bool () const;
625
626 private:
630 const bool value_{};
631 };
632
633 // ========================================================================
634
652 template <class Callable_T, class Exception_T = void>
654 {
661 constexpr explicit throws_ (const Callable_T& func);
662 };
663
664 // ========================================================================
665
681 template <class Callable_T>
682 struct throws_<Callable_T, void> : callable_op_
683 {
690 constexpr explicit throws_ (const Callable_T& func);
691 };
692
693 // ========================================================================
694
709 template <class Callable_T>
711 {
718 constexpr explicit nothrow_ (const Callable_T& func);
719 };
720
721#endif // defined(__cpp_exceptions)
722
723 // ========================================================================
724
736 template <class T>
737 requires std::is_arithmetic_v<T>
738 void
739 append_number_ (std::string& buffer, T v);
740
741 // ------------------------------------------------------------------------
742 } // namespace detail
743
744 // --------------------------------------------------------------------------
745} // namespace micro_os_plus::micro_test_plus
746
747#if defined(__GNUC__)
748#pragma GCC diagnostic pop
749#endif // defined(__GNUC__)
750
751// ----------------------------------------------------------------------------
752
753#endif // defined(__cplusplus)
754
755// ============================================================================
756// Templates, inlines & constexpr implementations.
757
759
760// ----------------------------------------------------------------------------
761
762#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_DETAIL_H_
763
764// ----------------------------------------------------------------------------

Generated via doxygen2docusaurus 2.2.2 by Doxygen 1.17.0.