Skip to main content

type-traits.h File

C++ header file with declarations for the µTest++ type trait utilities and metaprogramming support. More...

Included Headers

#include "math.h" #include <string_view> #include <type_traits> #include "inlines/type-traits-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...

namespacetype_traits

Type trait utilities and metaprogramming support for the µTest++ testing framework. More...

Classes Index

structfloating_point_constant<T, N, D, Size, P>

Struct template representing a generic floating point constant with custom size and precision. More...

structfunction_traits<R(*)(Args_T...)>

Struct template specialisation for extracting function traits from function pointer types. More...

structfunction_traits<R(Args_T...)>

Struct template specialisation for extracting function traits from plain function types. More...

structfunction_traits<R(T::*)(Args_T...) const>

Struct template specialisation for extracting function traits from const member function types. More...

structfunction_traits<R(T::*)(Args_T...)>

Struct template specialisation for extracting function traits from non-const member function types. More...

structgenuine_integral_value<T>

Struct template representing a genuine integral value. More...

structidentity<T, Extra>

Struct template for compile-time type identity. More...

structintegral_constant<N>

Struct template representing a generic integral constant. More...

structlist<Types>

Struct template representing a compile-time type list. More...

structop

Empty base struct for all operator types. More...

structvalue<T>

Struct template representing a generic value, accessible via a getter. More...

structvalue<T>

Struct template representing a floating point value with precision control. More...

structvalue_base_<T>

Base struct template providing common storage and accessors for runtime value-wrapper types. More...

Concepts Index

conceptany_op

C++20 concept satisfied when at least one of two types derives from op. More...

conceptcheckable

C++20 concept satisfied when a type can be used as a test expression in expect() or assume(). More...

conceptcontainer_like

C++20 concept satisfied when T provides both begin() and end() member functions. More...

concepthas_epsilon

C++20 concept satisfied when T provides an epsilon member. More...

concepthas_npos

C++20 concept satisfied when T provides a npos member. More...

concepthas_value

C++20 concept satisfied when T provides a value member. More...

conceptis_floating_point

C++20 concept satisfied when T is a standard floating point type. More...

conceptis_op

C++20 concept satisfied when a type derives from op. More...

conceptprintable

C++20 concept satisfied when a type can be appended to the deferred reporter's output via operator<<. More...

Description

C++ header file with declarations for the µTest++ type trait utilities and metaprogramming support.

This header provides the declarations for the type trait utilities and metaprogramming constructs used within the µTest++ framework. It defines templates and variable traits for function traits, type lists, identity, value wrappers, compile-time checks for container and floating-point types, and type convertibility.

These utilities underpin advanced template programming, type deduction, and compile-time introspection, supporting the flexible and type-safe design of the framework. The provided traits and wrappers enable expressive and generic handling of types, values, and callable objects, facilitating robust and maintainable test code.

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

All 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 for internal use within the framework and should not be included directly by user code.

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
47
48#ifndef MICRO_OS_PLUS_MICRO_TEST_PLUS_TYPE_TRAITS_H_
49#define MICRO_OS_PLUS_MICRO_TEST_PLUS_TYPE_TRAITS_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 "math.h"
66
67#include <string_view>
68#include <type_traits>
69
70// ----------------------------------------------------------------------------
71
72#if defined(__GNUC__)
73#pragma GCC diagnostic push
74
75#if defined(__clang__)
76#pragma clang diagnostic ignored "-Wc++98-compat"
77#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
78#endif // defined(__clang__)
79#endif // defined(__GNUC__)
80
81// ============================================================================
82
84{
85 // --------------------------------------------------------------------------
86
111 namespace type_traits
112 {
131 template <class... Types>
132 struct list
133 {
134 };
135
157 template <class T, class... Extra>
158 struct identity
159 {
163 using type = T;
164 };
165
166#if defined(__DOXYGEN__)
167 // error: Detected potential recursive class relation between class
168 // micro_os_plus::micro_test_plus::type_traits::function_traits and base
169 // class micro_os_plus::micro_test_plus::type_traits::function_traits<
170 // decltype(&T::operator())>!
171 // https://github.com/doxygen/doxygen/issues/9915
172#else
193 template <class T>
194 struct function_traits : function_traits<decltype (&T::operator())>
195 {
196 };
197#endif // defined(__DOXYGEN__)
198
218 template <class R, class... Args_T>
219 struct function_traits<R (*) (Args_T...)>
220 {
224 using result_type = R;
225
229 using args = list<Args_T...>;
230 };
231
251 template <class R, class... Args_T>
252 struct function_traits<R (Args_T...)>
253 {
257 using result_type = R;
258
262 using args = list<Args_T...>;
263 };
264
285 template <class R, class T, class... Args_T>
286 struct function_traits<R (T::*) (Args_T...)>
287 {
291 using result_type = R;
292
296 using args = list<Args_T...>;
297 };
298
320 template <class R, class T, class... Args_T>
321 struct function_traits<R (T::*) (Args_T...) const>
322 {
326 using result_type = R;
327
331 using args = list<Args_T...>;
332 };
333
334 // ------------------------------------------------------------------------
335
352 struct op
353 {
354 };
355
356 // ------------------------------------------------------------------------
357 // Concepts.
358
371 template <class T>
372 concept container_like = requires (const T& t) {
373 t.begin ();
374 t.end ();
375 };
376
388 template <class T>
389 concept has_npos = requires { T::npos; };
390
402 template <class T>
403 concept has_value = requires (const T& t) { t.value; };
404
416 template <class T>
417 concept has_epsilon = requires (const T& t) { t.epsilon; };
418
431 template <class T>
432 concept is_floating_point = std::is_floating_point_v<T>;
433
445 template <class T>
446 concept is_op = std::is_base_of_v<type_traits::op, T>;
447
462 template <class Lhs_T, class Rhs_T>
464
478 template <class T>
479 concept checkable = is_op<T> or std::convertible_to<T, bool>;
480
494 template <class T>
495 concept printable = std::is_arithmetic_v<T>
496 or std::is_convertible_v<T, std::string_view>;
497
498 // ------------------------------------------------------------------------
499
517 template <class T>
518 struct value_base_ : op
519 {
523 using value_type = T;
524
530 constexpr explicit value_base_ (const T& v) noexcept;
531
537 [[nodiscard]] constexpr explicit
538 operator T () const noexcept;
539
547 [[nodiscard]] constexpr T
548 get (void) const noexcept;
549
553 T value_{};
554 };
555
574 template <auto N>
575 struct integral_constant : value_base_<decltype (N)>
576 {
580 static constexpr auto value = N;
581
585 constexpr integral_constant () noexcept;
586
592 [[nodiscard]] constexpr auto
593 operator- () const noexcept;
594 };
595
624 template <class T, auto N, auto D, auto Size, auto P = 1>
626 {
627 static_assert (P == 1 || P == -1,
628 "floating_point_constant: P must be 1 or -1");
629
633 using value_type = T;
634
641 static constexpr auto epsilon = T (1) / math::pow (T (10), Size - 1);
642
649 static constexpr auto value
650 = T (P) * (T (N) + (T (D) / math::pow (T (10), Size)));
651
657 [[nodiscard]] constexpr explicit
658 operator T () const noexcept;
659
667 [[nodiscard]] constexpr T
668 get (void) const noexcept;
669
675 [[nodiscard]] constexpr auto
676 operator- () const noexcept;
677 };
678
691 template <class T>
693 {
699 constexpr genuine_integral_value (const T& _value) noexcept;
700 };
701
715 template <class T>
716 struct value : value_base_<T>
717 {
726 constexpr value (const T& _value) noexcept;
727 };
728
751 template <class T>
753 struct value<T> : value_base_<T>
754 {
765 T epsilon = T{};
766
767 // Note: These constructor bodies are defined inline rather than
768 // out-of-line in type-traits-inlines.h. Clang 16 has a deficiency
769 // where it fails to match out-of-line constructor definitions to a
770 // `requires`-constrained partial specialisation: it either rejects
771 // the `requires` clause on the definition as differing from the
772 // declaration, or — when the clause is omitted — incorrectly matches
773 // the definition against the primary template instead of this
774 // specialisation. Keeping the bodies here avoids both failure modes.
775
786 constexpr value (const T& _value, const T precision) noexcept
787 : value_base_<T>{ _value }, epsilon{ precision }
788 {
789 }
790
800 constexpr value (const T& val)
801 : value{ val,
802 T (1)
803 / math::pow (T (10),
804 math::den_size<unsigned long long> (val)) }
805 {
806 }
807 };
808
809 // ------------------------------------------------------------------------
810 } // namespace type_traits
811
812 // --------------------------------------------------------------------------
813} // namespace micro_os_plus::micro_test_plus
814
815#if defined(__GNUC__)
816#pragma GCC diagnostic pop
817#endif // defined(__GNUC__)
818
819// ----------------------------------------------------------------------------
820
821#endif // defined(__cplusplus)
822
823// ============================================================================
824// Templates, inlines & constexpr implementations.
825
827
828// ----------------------------------------------------------------------------
829
830#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TYPE_TRAITS_H_
831
832// ----------------------------------------------------------------------------

Generated via doxygen2docusaurus 2.2.2 by Doxygen 1.17.0.