micro-test-plus 6.0.0
µTest++ Testing Framework
Loading...
Searching...
No Matches
check-result-inlines.h
Go to the documentation of this file.
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
12// ----------------------------------------------------------------------------
13
33
34#ifndef MICRO_OS_PLUS_MICRO_TEST_PLUS_INLINES_CHECK_RESULT_INLINES_H_
35#define MICRO_OS_PLUS_MICRO_TEST_PLUS_INLINES_CHECK_RESULT_INLINES_H_
36
37// ----------------------------------------------------------------------------
38
39#if defined(__cplusplus)
40
41// ----------------------------------------------------------------------------
42
43#if __has_include("micro-os-plus/diag/trace.h")
44#include "micro-os-plus/diag/trace.h"
45#endif // __has_include("micro-os-plus/diag/trace.h")
46
47#include <concepts>
48#include <cstdio>
49#include <functional>
50#include <utility>
51
52// ----------------------------------------------------------------------------
53
54#if defined(__GNUC__)
55#pragma GCC diagnostic push
56
57#pragma GCC diagnostic ignored "-Waggregate-return"
58#if defined(__clang__)
59#pragma clang diagnostic ignored "-Wc++98-compat"
60#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
61#endif // defined(__clang__)
62#endif // defined(__GNUC__)
63
64// ============================================================================
65
67{
68 // --------------------------------------------------------------------------
69
70 namespace detail
71 {
72 // ========================================================================
73
100 template <class Expr_T>
101 void
102 check_result::init (const Expr_T& expr, check_kind kind,
103 const reflection::source_location& location,
105 bool writes_passed)
106 {
107 start (static_cast<bool> (expr), kind, extension::is_op<Expr_T>,
108 location, test_case, writes_passed);
109
110#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
111 trace::printf ("%s\n", __PRETTY_FUNCTION__);
112#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
113
114 // The same address is used by the destructor, to retrieve the text,
115 // even if other checks used the formatter in the meantime.
116 expression.begin_check (this);
117
118 if (is_written_)
119 {
120 if constexpr (extension::is_op<Expr_T>
121 or std::convertible_to<Expr_T, bool>)
122 {
123 expression << expr;
124 }
125 else
126 {
127 expression << static_cast<bool> (expr);
128 }
129 }
130 }
131
132 // ------------------------------------------------------------------------
133
138 inline bool
139 check_result::value (void) const&& noexcept
140 {
141 return value_;
142 }
143
144 // ------------------------------------------------------------------------
145
175 template <class T>
178 check_result::operator<< (const T& msg) &&
179 {
180 if constexpr (detail::lazy_message<T>)
181 {
182 if (value_)
183 {
184 return std::move (*this);
185 }
186 }
187 else
188 {
189 if (!is_written_)
190 {
191 return std::move (*this);
192 }
193 }
194
195 expression_formatter formatter{ std::move (info_.message) };
196 if constexpr (detail::lazy_message<T>)
197 {
198 formatter << std::invoke (msg);
199 }
200 else
201 {
202 formatter << msg;
203 }
204 info_.message = std::move (formatter.buffer_);
205 return std::move (*this);
206 }
207
208#if !defined(__DOXYGEN__)
214 template <class T>
215 requires (not detail::message_argument<T>)
217 check_result::operator<< ([[maybe_unused]] const T& msg) &&
218 {
219 if constexpr (std::is_class_v<T> and std::invocable<const T&>)
220 {
221 static_assert (
222 not std::is_same_v<T, T>,
223 "a message that is a callable object must be callable "
224 "without arguments and return a value that can be "
225 "written, not void");
226 }
227 else
228 {
229 static_assert (not std::is_same_v<T, T>,
230 "a message argument must be a value that can be "
231 "written: define an operator<< (mt::"
232 "expression_formatter&, const T&) in the namespace "
233 "of the type, or pass a callable object that returns "
234 "such a value");
235 }
236 return std::move (*this);
237 }
238#endif // !defined(__DOXYGEN__)
239
240 // ------------------------------------------------------------------------
241 } // namespace detail
242
243 // --------------------------------------------------------------------------
244} // namespace micro_os_plus::micro_test_plus
245
246#if defined(__GNUC__)
247#pragma GCC diagnostic pop
248#endif // defined(__GNUC__)
249
250// ----------------------------------------------------------------------------
251
252#endif // defined(__cplusplus)
253
254// ----------------------------------------------------------------------------
255
256#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_INLINES_CHECK_RESULT_INLINES_H_
257
258// ----------------------------------------------------------------------------
The result of one check, reported when destroyed.
bool value(void) const &&noexcept
Retrieves the result value.
void start(bool value, check_kind kind, bool has_expression, const reflection::source_location &location, test_case &test_case, bool writes_passed)
Starts the result of a check from its parts.
check_result(void)
Constructs a result in the initial state.
bool is_written_
Whether the outcome of the check is written.
check_result && operator<<(const T &msg) &&
Appends a message to the check.
void init(const Expr_T &expr, check_kind kind, const reflection::source_location &location, test_case &test_case, expression_formatter &expression, bool writes_passed)
Initialises the result with the check of an expression.
bool value_
Stores the result value of the check.
failure_info info_
The details displayed when the check fails.
Formats values and expressions into an owned string buffer.
void begin_check(const void *owner)
Prepares the buffer for the expression of a new check.
Local implementation of source location information for diagnostics.
Definition reflection.h:143
A named, runnable test case that lives inside a suite.
Definition test.h:1362
Concept satisfied when T is a callable object that returns a printable message.
Definition extension.h:694
Concept satisfied when T can be appended to the message of a check.
Definition extension.h:715
Concept satisfied when a type is a framework expression type.
Definition extension.h:320
Internal implementation details for the µTest++ framework.
check_kind
The kind of a check, which determines what happens when it fails.
Primary namespace for the µTest++ testing framework.