Skip to main content

expression-formatter.h File

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

Included Headers​

#include "detail.h" #include "extension.h" #include <charconv> #include <chrono> #include <cstdio> #include <optional> #include <string> #include <tuple> #include <type_traits> #include <utility> #include <vector> #include <string_view> #include <version> #include "inlines/expression-formatter-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​

structcolour_code

An ANSI colour escape sequence, to be written as it is. More...

structcolours

Colours used to highlight pass and fail results in test reports. More...

classexpression_formatter

Formats values and expressions into an owned string buffer. More...

structplain_text

Writes values as text, as the messages of the checks are written. More...

Concepts Index​

conceptfree_printable

Concept satisfied by the types that have a free operator<< for the formatter. More...

conceptmember_printable

Concept satisfied by the types that the formatter writes with one of its own member functions operator<<. More...

Typedefs Index​

usingexpression_formatter = detail::expression_formatter

Public name of the formatter used to report operand values. More...

Functions Index​

voidappend_control_escape (std::string &text, char c)

Appends the escape sequence of a control character. More...

Variables Index​

constexpr colourscolours_none {}

Predefined colour set, without escape sequences. More...

constexpr colourscolours_red_green = ...

Predefined colour set, with green for pass and red for fail. More...

Description​

C++ header file with declarations for the µTest++ expression formatter.

This header provides the expression_formatter class, which encapsulates all value-formatting logic used by the µTest++ framework. The class owns a std::string buffer and exposes operator<< overloads for every standard arithmetic type, character type, string, pointer, container, scoped enumeration, pair, tuple, optional, and framework expression type (see extension::is_op).

By consolidating the formatting operators into a single class (using the shared detail::append_number() helper for numbers), the reporter is relieved of those responsibilities, and detail::check_result can pre-format expression text, when initialised, without requiring reporter or test_case to be complete at that point.

The formatter shares the colour configuration of the owning reporter: comparator expressions are wrapped in pass/fail colour codes, which are empty strings unless the reporter enables colours.

All definitions reside within the micro_os_plus::micro_test_plus namespace.

This file is included by micro-os-plus/micro-test-plus.h, which is the header that the applications include.

Functions​

append_control_escape()​

void micro_os_plus::micro_test_plus::detail::append_control_escape (std::string & text, char c)

Appends the escape sequence of a control character.

Writes the usual escape of the character (\\0, \\a, \\b, \\t, \\n, \\v, \\f, or \\r), or \\xHH for the other ones. Used for the characters of the messages and of the names that would otherwise reach the console and the output files unchanged. Defined in src/expression-formatter.cpp.

Parameters
text

The text to append to.

c

The control character.

The usual escapes for the characters that have one; the other ones, including DEL, as \\xHH.

Definition at line 401 of file expression-formatter.cpp.

401 append_control_escape (std::string& text, char c)
402 {
403 switch (c)
404 {
405 case '\0':
406 text.append ("\\0");
407 break;
408 case '\a':
409 text.append ("\\a");
410 break;
411 case '\b':
412 text.append ("\\b");
413 break;
414 case '\t':
415 text.append ("\\t");
416 break;
417 case '\n':
418 text.append ("\\n");
419 break;
420 case '\v':
421 text.append ("\\v");
422 break;
423 case '\f':
424 text.append ("\\f");
425 break;
426 case '\r':
427 text.append ("\\r");
428 break;
429 default:
430 append_hex (text, static_cast<unsigned char> (c), "\\x", 2);
431 break;
432 }
433 }

Reference micro_os_plus::micro_test_plus::detail::append_control_escape.

Referenced by micro_os_plus::micro_test_plus::detail::append_control_escape, micro_os_plus::micro_test_plus::detail::anonymous{expression-formatter.cpp}::append_plain, micro_os_plus::micro_test_plus::detail::escape_control_characters and micro_os_plus::micro_test_plus::detail::expression_formatter::operator<<.

Variables​

colours_none​

colours micro_os_plus::micro_test_plus::detail::colours_none {}
constexpr

Predefined colour set, without escape sequences.

Used by the formatters that write the messages of the checks, which are never coloured; all members are empty strings.

Definition at line 184 of file expression-formatter.h.

184 inline constexpr colours colours_none{};

Referenced by micro_os_plus::micro_test_plus::detail::expression_formatter::expression_formatter and micro_os_plus::micro_test_plus::detail::expression_formatter::expression_formatter.

colours_red_green​

colours micro_os_plus::micro_test_plus::detail::colours_red_green
constexpr

Predefined colour set, with green for pass and red for fail.

Initialiser
                                           = {   "\033[0m",   "\033[32m",   "\033[31m" }

Assigned by reporters that output to a colour-capable terminal; the members are, in order, the reset, pass, and fail ANSI escape sequences.

Definition at line 171 of file expression-formatter.h.

171 inline constexpr colours colours_red_green = {
172 "\033[0m",
173 "\033[32m",
174 "\033[31m"
175 };

Referenced by micro_os_plus::micro_test_plus::detail::reporter_human::reporter_human.

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.0 Software License,
13 * which can be obtained from https://www.boost.org/LICENSE_1_0.txt.
14 */
15
16// ----------------------------------------------------------------------------
17
47
48#ifndef MICRO_OS_PLUS_MICRO_TEST_PLUS_EXPRESSION_FORMATTER_H_
49#define MICRO_OS_PLUS_MICRO_TEST_PLUS_EXPRESSION_FORMATTER_H_
50
51// ----------------------------------------------------------------------------
52
53#if defined(__cplusplus)
54
55// ----------------------------------------------------------------------------
56
57#if __has_include("micro-os-plus/project-config.h")
58#include "micro-os-plus/project-config.h"
59#endif // __has_include("micro-os-plus/project-config.h")
60
61#if __has_include("micro-os-plus/micro-test-plus-defines.h")
62#include "micro-os-plus/micro-test-plus-defines.h"
63#endif // __has_include("micro-os-plus/micro-test-plus-defines.h")
64
65#include "detail.h"
66#include "extension.h"
67
68#include <charconv>
69#include <chrono>
70#include <cstdio>
71#include <optional>
72#include <string>
73#include <tuple>
74#include <type_traits>
75#include <utility>
76#include <vector>
77#include <string_view>
78#include <version>
79
80// ----------------------------------------------------------------------------
81
82#if defined(__GNUC__)
83#pragma GCC diagnostic push
84
85#pragma GCC diagnostic ignored "-Wpadded"
86#pragma GCC diagnostic ignored "-Waggregate-return"
87#if defined(__clang__)
88#pragma clang diagnostic ignored "-Wc++98-compat"
89#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
90#endif // defined(__clang__)
91#endif // defined(__GNUC__)
92
93// ============================================================================
94
96{
97 // --------------------------------------------------------------------------
98
99 namespace detail
100 {
101 // Forward definitions.
102 class check_result;
103 struct plain_text;
104#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_DEPRECATED_ENABLED)
105 struct named_bool;
106#endif // defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_DEPRECATED_ENABLED)
107
108 // ------------------------------------------------------------------------
109
123 void
124 append_control_escape (std::string& text, char c);
125
126 // ------------------------------------------------------------------------
127
154 struct colours
155 {
156 const char* none = "";
157 const char* pass
158 = "";
159 const char* fail
160 = "";
161 };
162
171 inline constexpr colours colours_red_green = {
172 "\033[0m",
173 "\033[32m",
174 "\033[31m"
175 };
176
184 inline constexpr colours colours_none{};
185
186 // ========================================================================
187
230 {
239 friend class check_result;
240
251 friend struct plain_text;
252
253 public:
267 expression_formatter (void) noexcept;
268
275 expression_formatter (const colours& colours) noexcept;
276
284
292
301 = delete;
302
311 = delete;
312
320
321 // ----------------------------------------------------------------------
322 // Primitive operator<< overloads.
323
339 operator<<(std::string_view sv);
340
358 operator<<(std::wstring_view sv);
359
360#if defined(__cpp_lib_char8_t)
372 operator<<(std::u8string_view sv);
373#endif // defined(__cpp_lib_char8_t)
374
385 operator<<(std::u16string_view sv);
386
397 operator<<(std::u32string_view sv);
398
415 operator<<(char c);
416
417#if defined(__cpp_char8_t)
435 operator<<(char8_t c);
436#endif // defined(__cpp_char8_t)
437
456 operator<<(char16_t c);
457
477 operator<<(char32_t c);
478
496 operator<<(wchar_t c);
497
534 template <typename Pointer_T>
537 operator<<(Pointer_T s);
538
558 template <typename Char_T, std::size_t N>
559 requires (detail::character<Char_T> and not std::is_volatile_v<Char_T>)
561 operator<< (const Char_T (&s)[N]);
562
575 template <character Char_T>
578
579#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_DEPRECATED_ENABLED)
591 operator<<(const named_bool& b);
592#endif // defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_DEPRECATED_ENABLED)
593
601 operator<<(bool v);
602
608 expression_formatter& operator<<(std::nullptr_t);
609
619 expression_formatter& operator<<(std::nullopt_t);
620
628 operator<<(signed char c);
629
637 operator<<(unsigned char c);
638
646 operator<<(signed short v);
647
655 operator<<(unsigned short v);
656
664 operator<<(signed int v);
665
673 operator<<(unsigned int v);
674
682 operator<<(signed long v);
683
691 operator<<(unsigned long v);
692
700 operator<<(signed long long v);
701
709 operator<<(unsigned long long v);
710
722 operator<<(float v);
723
735 operator<<(double v);
736
748 operator<<(long double v);
749
750 // ----------------------------------------------------------------------
751 // Template operator<< overloads.
752
769 template <typename T>
772 operator<< (T* v);
773
774#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_DEPRECATED_ENABLED)
793 template <class T>
794 requires (extension::is_op<T> and requires (const T& v) { v.get (); })
796 operator<< (const T& t);
797#endif // defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_DEPRECATED_ENABLED)
798
817 template <class T>
820 operator<<(const T& t);
821
842 template <class T>
843 requires (std::is_enum_v<T>
844 and not std::is_convertible_v<T, std::underlying_type_t<T>>)
846 operator<< (T v);
847
863 template <class T1, class T2>
866 operator<< (const std::pair<T1, T2>& p);
867
880 template <class... Ts>
881 requires (extension::printable<Ts> and ...)
883 operator<<(const std::tuple<Ts...>& t);
884
899 template <class T>
902 operator<<(const std::optional<T>& o);
903
919 template <class Rep, class Period>
920 requires std::is_arithmetic_v<Rep>
922 operator<<(const std::chrono::duration<Rep, Period>& d);
923
924 // ----------------------------------------------------------------------
925 // Compound expression operator<< overloads (with pass/fail colours).
926
940 template <class Lhs_T, class Rhs_T, class Compare_T>
943
958 template <class Lhs_T, class Rhs_T, class Epsilon_T>
961
974 template <class Lhs_T, class Rhs_T>
977
990 template <class Lhs_T, class Rhs_T>
993
1006 template <class T>
1009
1022 template <class T, class Predicate_T>
1025
1026#if defined(__cpp_exceptions)
1027
1041 template <class Exception_T>
1044
1057
1058#endif // defined(__cpp_exceptions)
1059
1060 // ----------------------------------------------------------------------
1061
1075 [[nodiscard]] const std::string&
1076 str (void) const noexcept;
1077
1078#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_DEPRECATED_ENABLED)
1083
1097 [[deprecated ("use str().c_str() (since 6.0.0)"), nodiscard]] const char*
1098 c_str (void) const noexcept;
1099
1111 [[deprecated ("use str().empty() (since 6.0.0)"), nodiscard]] bool
1112 empty (void) const noexcept;
1113
1117#endif // defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_DEPRECATED_ENABLED)
1118
1119 private:
1129 {
1136 const char* sequence;
1137 };
1138
1146 static constexpr size_t max_range_elements_ = 16;
1147
1167 void
1168 append_c_string (const char* s, std::size_t capacity);
1169
1184 void
1185 append_c_string (const wchar_t* s, std::size_t capacity);
1186
1187#if defined(__cpp_lib_char8_t)
1202 void
1203 append_c_string (const char8_t* s, std::size_t capacity);
1204#endif // defined(__cpp_lib_char8_t)
1205
1220 void
1221 append_c_string (const char16_t* s, std::size_t capacity);
1222
1237 void
1238 append_c_string (const char32_t* s, std::size_t capacity);
1239
1253 explicit expression_formatter (std::string&& buffer) noexcept;
1254
1255 // ----------------------------------------------------------------------
1256 // Ownership by the checks.
1257
1272 void
1273 begin_check (const void* owner);
1274
1283 [[nodiscard]] const std::string&
1284 check_text (const void* owner) const noexcept;
1285
1294 void
1295 end_check (const void* owner) noexcept;
1296
1297 // ----------------------------------------------------------------------
1298
1305 [[nodiscard]] inline colour_code
1306 colour (const bool cond) const;
1307
1315 [[nodiscard]] inline colour_code
1316 colour_none (void) const;
1317
1330
1344 void
1345 append_decimal_point (std::size_t start);
1346
1358 void
1359 append_suffix (const char* suffix);
1360
1377 void
1378 prepend_cast (std::size_t start, const char* type);
1379
1404 void
1405 append_character (std::string_view prefix, char32_t code,
1406 std::size_t size);
1407
1423 template <class T>
1424 void
1425 append_value (const T& value);
1426
1447 template <class T>
1448 void
1449 append_operand (const T& value);
1450
1466 template <class Tuple_T, std::size_t... Is>
1467 void
1468 append_elements (const Tuple_T& t, std::index_sequence<Is...>);
1469
1490 template <class Lhs_T, class Rhs_T>
1491 void
1492 append_first_difference (const Lhs_T& lhs, const Rhs_T& rhs);
1493
1494#if defined(__cpp_exceptions)
1508 void
1510#endif // defined(__cpp_exceptions)
1511
1525 template <class T>
1526 void
1527 append_and_operand (const T& t);
1528
1538 template <class Lhs_T, class Rhs_T>
1539 void
1541
1553 template <class T>
1554 void
1555 append_or_operand (const T& t);
1556
1566 template <class Lhs_T, class Rhs_T>
1567 void
1569
1589 template <class T>
1590 void
1591 append_not_operand (const T& t, colour_code outer_colour);
1592
1607 template <class Lhs_T, class Rhs_T, class Compare_T>
1608 void
1611 colour_code outer_colour);
1612
1627 template <class Lhs_T, class Rhs_T, class Epsilon_T>
1628 void
1630 colour_code outer_colour);
1631
1640
1647 std::string buffer_{};
1648
1656 const void* owner_{ nullptr };
1657
1671 std::vector<std::pair<const void*, std::string>> pending_{};
1672
1682 const bool plain_{ false };
1683 };
1684
1685 // ------------------------------------------------------------------------
1686
1703 {
1720 template <class T>
1722 static void
1723 append (std::string& text, const T& value);
1724 };
1725
1726 // ------------------------------------------------------------------------
1727
1742 template <class T>
1744 = requires (expression_formatter& formatter, const T& value) {
1745 formatter.operator<< (value);
1746 };
1747
1766 template <class T>
1768 = requires (expression_formatter& formatter, const T& value) {
1769 operator<< (formatter, value);
1770 };
1771
1772 // ------------------------------------------------------------------------
1773 } // namespace detail
1774
1775 // --------------------------------------------------------------------------
1776
1825
1826 // --------------------------------------------------------------------------
1827} // namespace micro_os_plus::micro_test_plus
1828
1829#if defined(__GNUC__)
1830#pragma GCC diagnostic pop
1831#endif // defined(__GNUC__)
1832
1833// ----------------------------------------------------------------------------
1834
1835#endif // defined(__cplusplus)
1836
1837// ============================================================================
1838// Templates, inlines & constexpr implementations.
1839
1841
1842// ----------------------------------------------------------------------------
1843
1844#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_EXPRESSION_FORMATTER_H_
1845
1846// ----------------------------------------------------------------------------

Generated via doxygen2docusaurus 2.2.8 by Doxygen 1.18.0.