micro-test-plus 6.0.0
µTest++ Testing Framework
Loading...
Searching...
No Matches
extension.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 * 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
50
51#ifndef MICRO_OS_PLUS_MICRO_TEST_PLUS_EXTENSION_H_
52#define MICRO_OS_PLUS_MICRO_TEST_PLUS_EXTENSION_H_
53
54// ----------------------------------------------------------------------------
55
56#if defined(__cplusplus)
57
58// ----------------------------------------------------------------------------
59
60#if __has_include("micro-os-plus/project-config.h")
61#include "micro-os-plus/project-config.h"
62#endif // __has_include("micro-os-plus/project-config.h")
63
64#if __has_include("micro-os-plus/micro-test-plus-defines.h")
65#include "micro-os-plus/micro-test-plus-defines.h"
66#endif // __has_include("micro-os-plus/micro-test-plus-defines.h")
67
68#include <concepts>
69#include <iterator>
70#include <memory>
71#include <optional>
72#include <string_view>
73#include <type_traits>
74#include <utility>
75
76// ----------------------------------------------------------------------------
77
78#if defined(__GNUC__)
79#pragma GCC diagnostic push
80
81#if defined(__clang__)
82#pragma clang diagnostic ignored "-Wc++98-compat"
83#pragma clang diagnostic ignored "-Wdocumentation"
84#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
85#endif // defined(__clang__)
86#endif // defined(__GNUC__)
87
88// ============================================================================
89
91{
92 // --------------------------------------------------------------------------
93
94 namespace detail
95 {
96 // Forward definitions.
98
99 // ========================================================================
100
119 struct op
120 {
128 using op_type = op;
129 };
130
131 // ------------------------------------------------------------------------
132
144 template <class T>
145 struct is_bool_wrapper : std::false_type
146 {
147 };
148
158 template <class T>
159 requires std::is_same_v<std::remove_cv_t<T>, bool>
160 struct is_bool_wrapper<std::optional<T>> : std::true_type
161 {
162 };
163
174 template <class T, class Deleter_T>
175 requires std::is_same_v<std::remove_cv_t<T>, bool>
176 struct is_bool_wrapper<std::unique_ptr<T, Deleter_T>> : std::true_type
177 {
178 };
179
189 template <class T>
190 requires std::is_same_v<std::remove_cv_t<T>, bool>
191 struct is_bool_wrapper<std::shared_ptr<T>> : std::true_type
192 {
193 };
194
215 template <class T>
217
218 // ------------------------------------------------------------------------
219
237 template <class T>
239 = std::is_array_v<T> or std::is_function_v<T>
240 or std::is_member_pointer_v<T>
241 or (std::is_pointer_v<T>
242 and (std::is_function_v<std::remove_pointer_t<T>>
243 or std::is_same_v<
244 std::remove_cv_t<std::remove_pointer_t<T>>, char>
245 or std::is_same_v<
246 std::remove_cv_t<std::remove_pointer_t<T>>, wchar_t>
247 or std::is_same_v<
248 std::remove_cv_t<std::remove_pointer_t<T>>, char8_t>
249 or std::is_same_v<
250 std::remove_cv_t<std::remove_pointer_t<T>>, char16_t>
251 or std::is_same_v<
252 std::remove_cv_t<std::remove_pointer_t<T>>, char32_t>));
253
254 // ------------------------------------------------------------------------
255 } // namespace detail
256
257 // --------------------------------------------------------------------------
258
291 namespace extension
292 {
293 // ------------------------------------------------------------------------
294 // Concepts.
295
318 template <class T>
319 concept is_op
320 = requires { requires std::same_as<typename T::op_type, detail::op>; };
321
322#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_DEPRECATED_ENABLED)
348 template <class T>
349 concept has_epsilon = is_op<T> and requires (const T& t) { t.epsilon; };
350#endif // defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_DEPRECATED_ENABLED)
351
368 template <class Lhs_T, class Rhs_T>
370
402 template <class T>
406 and requires (const T& t) { t ? true : false; });
407
432 template <class T>
433 concept printable = requires (detail::expression_formatter& formatter,
434 const T& value) { formatter << value; };
435
455 template <class Tag_T, class Lhs_T, class Rhs_T>
456 concept compare_tag = requires (const Lhs_T& lhs, const Rhs_T& rhs) {
457 requires printable<std::remove_cvref_t<decltype (Tag_T::symbol)>>;
458 { Tag_T::apply (lhs, rhs) } -> std::convertible_to<bool>;
459 };
460
476 template <class Tag_T, class T>
477 concept predicate_tag = requires (const T& operand) {
478 requires printable<std::remove_cvref_t<decltype (Tag_T::symbol)>>;
479 { Tag_T::apply (operand) } -> std::convertible_to<bool>;
480 };
481
482 // ------------------------------------------------------------------------
483 } // namespace extension
484
485 // --------------------------------------------------------------------------
486
487 namespace detail
488 {
489
490#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_DEPRECATED_ENABLED)
504 template <class T>
507 and requires (const T& t) { t ? true : false; };
508#endif // defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_DEPRECATED_ENABLED)
509
510 // ------------------------------------------------------------------------
511 // Concepts used only by the implementation.
512
531 template <class T>
532 concept container_like = requires (const T& t) {
533 requires std::input_or_output_iterator<decltype (t.begin ())>;
534 requires std::sentinel_for<decltype (t.end ()), decltype (t.begin ())>;
535 };
536
552 template <class T>
554 = std::convertible_to<const T&, std::basic_string_view<char>>
555 or std::convertible_to<const T&, std::basic_string_view<wchar_t>>
556 or std::convertible_to<const T&, std::basic_string_view<char8_t>>
557 or std::convertible_to<const T&, std::basic_string_view<char16_t>>
558 or std::convertible_to<const T&, std::basic_string_view<char32_t>>;
559
573 template <class T>
574 concept free_range = (not container_like<T>) and requires (const T& t) {
575 requires std::input_or_output_iterator<decltype (begin (t))>;
576 requires std::sentinel_for<decltype (end (t)), decltype (begin (t))>;
577 };
578
591 template <class T>
593
600 template <class T>
601 requires container_like<T>
603 {
611 using type = std::remove_cvref_t<
612 decltype (*std::declval<const T&> ().begin ())>;
613 };
614
621 template <class T>
622 requires free_range<T>
623 struct range_element<T>
624 {
633 using type
634 = std::remove_cvref_t<decltype (*begin (std::declval<const T&> ()))>;
635 };
636
664 template <class T>
666 = (container_like<T> or free_range<T>) and (not std::is_array_v<T>)
667 and (not string_like<T>)
668 and (not std::is_same_v<typename range_element<T>::type, T>)
669 and extension::printable<typename range_element<T>::type>;
670
692 template <class T>
694 = std::is_class_v<T> and std::invocable<const T&>
695 and (not std::is_void_v<std::invoke_result_t<const T&>>)
696 and extension::printable<std::invoke_result_t<const T&>>;
697
713 template <class T>
715 = lazy_message<T>
716 or (extension::printable<T>
717 and not(std::is_class_v<T> and std::invocable<const T&>));
718
719#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_DEPRECATED_ENABLED)
737 template <class T>
738 concept has_value = extension::is_op<T> and requires { T::value; };
739#endif // defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_DEPRECATED_ENABLED)
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
757#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_EXTENSION_H_
758
759// ----------------------------------------------------------------------------
Formats values and expressions into an owned string buffer.
Concept satisfied by the wrappers of a bool, whose condition is ambiguous.
Definition extension.h:216
Concept satisfied when T provides both begin() and end() member functions returning an iterator and i...
Definition extension.h:532
Concept satisfied when T is a range that the formatter writes element by element.
Definition extension.h:666
Concept satisfied when T provides begin() and end() only as functions found by argument-dependent loo...
Definition extension.h:574
Concept satisfied when T is a framework compile-time constant.
Definition extension.h:738
Concept satisfied when T is a callable object that returns a printable message.
Definition extension.h:694
Concept satisfied when a type was accepted by expect() and require() before the exclusion of the susp...
Definition extension.h:506
Concept satisfied when T can be appended to the message of a check.
Definition extension.h:715
Concept satisfied when T is a string, convertible to a std::basic_string_view of a character type.
Definition extension.h:554
Concept satisfied when a type is contextually convertible to bool, but is most likely not a condition...
Definition extension.h:239
Concept satisfied when at least one of two types is a framework expression type.
Definition extension.h:369
Concept satisfied when a type can be used as a test expression in expect() or require().
Definition extension.h:403
Concept satisfied by a tag that defines a custom comparator.
Definition extension.h:456
Deprecated concept satisfied when T is a framework floating-point wrapper with a tolerance.
Definition extension.h:349
Concept satisfied when a type is a framework expression type.
Definition extension.h:320
Concept satisfied by a tag that defines a custom predicate.
Definition extension.h:477
Concept satisfied when a type can be appended to the message of a check result via operator<<.
Definition extension.h:433
Internal implementation details for the µTest++ framework.
The templates and the concepts for extending the µTest++ testing framework.
Definition detail.h:1935
Primary namespace for the µTest++ testing framework.
Trait marking the wrappers of a bool, whose condition is ambiguous.
Definition extension.h:146
Empty base struct for the framework expression types.
Definition extension.h:120
op op_type
Marker identifying the framework expression types.
Definition extension.h:128
std::remove_cvref_t< decltype(*std::declval< const T & >().begin())> type
The element type, without references and qualifiers.
Definition extension.h:611
The type of the elements of a range, as iterated by a range-based for statement.
Definition extension.h:592
Struct template representing a generic value, accessible via a getter.
Definition deprecated.h:629