micro-test-plus 3.3.1
µTest++ Testing Framework
Loading...
Searching...
No Matches
type-traits.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
47
48#ifndef MICRO_TEST_PLUS_TYPE_TRAITS_H_
49#define MICRO_TEST_PLUS_TYPE_TRAITS_H_
50
51// ----------------------------------------------------------------------------
52
53#ifdef __cplusplus
54
55// ----------------------------------------------------------------------------
56
57#include "math.h"
58
59// ----------------------------------------------------------------------------
60
61#if defined(__GNUC__)
62#pragma GCC diagnostic push
63#if defined(__clang__)
64#pragma clang diagnostic ignored "-Wc++98-compat"
65#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
66#endif
67#endif
68
70{
71 // --------------------------------------------------------------------------
72
97 namespace type_traits
98 {
117 template <class... Types>
118 struct list
119 {
120 };
121
140 template <class T, class... Extra>
141 struct identity
142 {
146 using type = T;
147 };
148
149#if defined(__DOXYGEN__)
150 // error: Detected potential recursive class relation between class
151 // micro_os_plus::micro_test_plus::type_traits::function_traits and base
152 // class micro_os_plus::micro_test_plus::type_traits::function_traits<
153 // decltype(&T::operator())>!
154 // https://github.com/doxygen/doxygen/issues/9915
155#else
176 template <class T>
177 struct function_traits : function_traits<decltype (&T::operator())>
178 {
179 };
180#endif
181
201 template <class R, class... Args_T>
202 struct function_traits<R (*) (Args_T...)>
203 {
207 using result_type = R;
208
212 using args = list<Args_T...>;
213 };
214
234 template <class R, class... Args_T>
235 struct function_traits<R (Args_T...)>
236 {
240 using result_type = R;
241
245 using args = list<Args_T...>;
246 };
247
268 template <class R, class T, class... Args_T>
269 struct function_traits<R (T::*) (Args_T...)>
270 {
274 using result_type = R;
275
279 using args = list<Args_T...>;
280 };
281
303 template <class R, class T, class... Args_T>
304 struct function_traits<R (T::*) (Args_T...) const>
305 {
309 using result_type = R;
310
314 using args = list<Args_T...>;
315 };
316
333 template <class T>
334 T&&
335 declval (void);
336 template <class... Ts, class Expr_T>
337 constexpr auto
338 is_valid (Expr_T expr) -> decltype (expr (declval<Ts...> ()), bool ())
339 {
340 return true;
341 }
342
356 template <class... Ts>
357 constexpr auto
358 is_valid (...) -> bool
359 {
360 return false;
361 }
362
379 template <class T>
380 static constexpr auto is_container_v = is_valid<T> (
381 [] (auto t) -> decltype (t.begin (), t.end (), void ()) {});
382
400 template <class T>
401 static constexpr auto has_npos_v
402 = is_valid<T> ([] (auto t) -> decltype (void (t.npos)) {});
403
420 template <class T>
421 static constexpr auto has_value_v
422 = is_valid<T> ([] (auto t) -> decltype (void (t.value)) {});
423
441 template <class T>
442 static constexpr auto has_epsilon_v
443 = is_valid<T> ([] (auto t) -> decltype (void (t.epsilon)) {});
444
464 template <class T>
465 inline constexpr auto is_floating_point_v = false;
466
480 template <>
481 inline constexpr auto is_floating_point_v<float> = true;
482
496 template <>
497 inline constexpr auto is_floating_point_v<double> = true;
498
512 template <>
513 inline constexpr auto is_floating_point_v<long double> = true;
514
515#if defined(__clang__) or defined(_MSC_VER)
536 template <class From, class To>
537 static constexpr auto is_convertible_v = __is_convertible_to (From, To);
538#else
559 template <class From, class To>
560 constexpr auto
561 is_convertible (int n) -> decltype (bool (To (declval<From> ())))
562 {
563 (void)n; // Prevent the unused parameter warning.
564 return true;
565 }
566
580 template <class...>
581 constexpr auto
583 {
584 return false;
585 }
586
604 template <class From, class To>
606#endif
607
624 template <bool Cond>
626 {
627 };
628
639 template <>
641 {
645 using type = int;
646 };
647
659 template <bool Cond>
661
678 struct op
679 {
680 };
681
700 template <auto N>
702 {
706 using value_type = decltype (N);
707
711 static constexpr auto value = N;
712
722 [[nodiscard]] constexpr auto
723 operator- () const
724 {
725 return integral_constant<-N>{};
726 }
727
738 [[nodiscard]] constexpr explicit
739 operator value_type (void) const
740 {
741 return N;
742 }
743
754 [[nodiscard]] constexpr auto
755 get (void) const
756 {
757 return N;
758 }
759 };
760
787 template <class T, auto N, auto D, auto Size, auto P = 1>
789 {
793 using value_type = T;
794
801 static constexpr auto epsilon = T (1) / math::pow (T (10), Size - 1);
802
809 static constexpr auto value
810 = T (P) * (T (N) + (T (D) / math::pow (T (10), Size)));
811
821 [[nodiscard]] constexpr auto
823 {
824 return floating_point_constant<T, N, D, Size, -1>{};
825 }
826
836 [[nodiscard]] constexpr explicit
837 operator value_type () const
838 {
839 return value;
840 }
841
850 [[nodiscard]] constexpr auto
851 get () const
852 {
853 return value;
854 }
855 };
856
876 template <class T>
878 {
882 using value_type = T;
883
889 constexpr genuine_integral_value (const T& _value) : value_{ _value }
890 {
891 }
892
901 [[nodiscard]] constexpr explicit
902 operator T () const
903 {
904 return value_;
905 }
906
915 [[nodiscard]] constexpr decltype (auto)
916 get () const
917 {
918 return value_;
919 }
920
925 };
926
943 template <class T>
944 inline constexpr auto is_op_v = __is_base_of (type_traits::op, T);
945
968 template <class T, class Opt = int>
970 {
974 using value_type = T;
975
981 constexpr value (const T& _value) : value_{ _value }
982 {
983 }
984
993 [[nodiscard]] constexpr explicit
994 operator T () const
995 {
996 return value_;
997 }
998
1009 [[nodiscard]] constexpr decltype (auto)
1010 get (void) const
1011 {
1012 return value_;
1013 }
1014
1019 };
1020
1046 template <class T>
1047 struct value<T,
1048 type_traits::requires_t<type_traits::is_floating_point_v<T>>>
1050 {
1054 using value_type = T;
1055
1064 static inline auto epsilon = T{}; // Why static?
1065
1072 constexpr value (const T& _value, const T precision) : value_{ _value }
1073 {
1074 epsilon = precision;
1075 }
1076
1086 constexpr /*explicit(false)*/ value (const T& val)
1087 : value{ val,
1088 T (1)
1089 / math::pow (T (10),
1090 math::den_size<unsigned long long> (val)) }
1091 {
1092 }
1093
1102 [[nodiscard]] constexpr explicit
1103 operator T () const
1104 {
1105 return value_;
1106 }
1107
1118 [[nodiscard]] constexpr decltype (auto)
1119 get (void) const
1120 {
1121 return value_;
1122 }
1123
1128 };
1129
1130 // ------------------------------------------------------------------------
1131 } // namespace type_traits
1132
1133 // --------------------------------------------------------------------------
1134} // namespace micro_os_plus::micro_test_plus
1135
1136#if defined(__GNUC__)
1137#pragma GCC diagnostic pop
1138#endif
1139
1140// ----------------------------------------------------------------------------
1141
1142#endif // __cplusplus
1143
1144// ----------------------------------------------------------------------------
1145
1146#endif // MICRO_TEST_PLUS_TYPE_TRAITS_H_
1147
1148// ----------------------------------------------------------------------------
C++ header file with declarations for the µTest++ mathematical utilities.
Mathematical utilities for the µTest++ testing framework.
constexpr auto pow(const T base, const Exp_T exp) -> T
Generic exponentiation function to compute the power of a base raised to an exponent.
Type trait utilities and metaprogramming support for the µTest++ testing framework.
static constexpr auto has_npos_v
Variable template to determine if a type provides a static npos member.
typename requires_< Cond >::type requires_t
Alias template for extracting the type member from requires_.
static constexpr auto has_epsilon_v
Variable template to determine if a type provides an epsilon member.
constexpr auto is_convertible_v
Variable template to determine if one type is convertible to another.
static constexpr auto has_value_v
Variable template to determine if a type provides a value member.
constexpr auto is_op_v
Variable template to determine if a type derives from op.
static constexpr auto is_container_v
Variable template to determine if a type models a container.
constexpr auto is_valid(Expr_T expr) -> decltype(expr(declval< Ts... >()), bool())
constexpr auto is_floating_point_v
Variable template to determine if a type is a floating point type.
T && declval(void)
Utility function template to simulate std::declval for type deduction.
constexpr auto is_convertible(int n) -> decltype(bool(To(declval< From >())))
Function template to determine if one type is convertible to another.
Primary namespace for the µTest++ testing framework.
Struct template representing a generic floating point constant with custom size and precision.
constexpr auto get() const
Getter for the constant value.
static constexpr auto epsilon
The epsilon value used for floating point comparisons.
constexpr auto operator-() const
Unary minus operator.
constexpr decltype(auto) get() const
Getter for the encapsulated value.
constexpr genuine_integral_value(const T &_value)
Constructs a genuine_integral_value with the specified value.
Struct template for compile-time type identity.
Struct template representing a generic integral constant.
decltype(N) value_type
The type of the constant value.
constexpr auto get(void) const
Getter for the constant value.
Struct template representing a compile-time type list.
Empty base struct for all operator types.
int type
Alias type provided when the requirement is satisfied.
Struct template for SFINAE requirements.
constexpr value(const T &_value, const T precision)
Constructs a floating point value with a specified precision.
constexpr value(const T &_value)
Constructs a value object with the specified value.