micro-test-plus 3.2.2
µ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 Liviu Ionescu. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software
6 * for any 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
9 * be 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...>
118 struct list
119 {
120 };
121
140 template <class T, class...>
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...>
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
626 template <bool>
628 {
629 };
630
641 template <>
643 {
647 using type = int;
648 };
649
661 template <bool Cond>
663
680 struct op
681 {
682 };
683
702 template <auto N>
704 {
708 using value_type = decltype (N);
709
713 static constexpr auto value = N;
714
724 [[nodiscard]] constexpr auto
725 operator- () const
726 {
727 return integral_constant<-N>{};
728 }
729
740 [[nodiscard]] constexpr explicit
741 operator value_type (void) const
742 {
743 return N;
744 }
745
756 [[nodiscard]] constexpr auto
757 get (void) const
758 {
759 return N;
760 }
761 };
762
789 template <class T, auto N, auto D, auto Size, auto P = 1>
791 {
795 using value_type = T;
796
803 static constexpr auto epsilon = T (1) / math::pow (T (10), Size - 1);
804
811 static constexpr auto value
812 = T (P) * (T (N) + (T (D) / math::pow (T (10), Size)));
813
823 [[nodiscard]] constexpr auto
825 {
826 return floating_point_constant<T, N, D, Size, -1>{};
827 }
828
838 [[nodiscard]] constexpr explicit
839 operator value_type () const
840 {
841 return value;
842 }
843
852 [[nodiscard]] constexpr auto
853 get () const
854 {
855 return value;
856 }
857 };
858
878 template <class T>
880 {
884 using value_type = T;
885
891 constexpr genuine_integral_value (const T& _value) : value_{ _value }
892 {
893 }
894
903 [[nodiscard]] constexpr explicit
904 operator T () const
905 {
906 return value_;
907 }
908
917 [[nodiscard]] constexpr decltype (auto)
918 get () const
919 {
920 return value_;
921 }
922
927 };
928
945 template <class T>
946 inline constexpr auto is_op_v = __is_base_of (type_traits::op, T);
947
970 template <class T, class = int>
972 {
976 using value_type = T;
977
983 constexpr value (const T& _value) : value_{ _value }
984 {
985 }
986
995 [[nodiscard]] constexpr explicit
996 operator T () const
997 {
998 return value_;
999 }
1000
1011 [[nodiscard]] constexpr decltype (auto)
1012 get (void) const
1013 {
1014 return value_;
1015 }
1016
1021 };
1022
1048 template <class T>
1049 struct value<T,
1050 type_traits::requires_t<type_traits::is_floating_point_v<T>>>
1052 {
1056 using value_type = T;
1057
1066 static inline auto epsilon = T{}; // Why static?
1067
1074 constexpr value (const T& _value, const T precision) : value_{ _value }
1075 {
1076 epsilon = precision;
1077 }
1078
1088 constexpr /*explicit(false)*/ value (const T& val)
1089 : value{ val,
1090 T (1)
1091 / math::pow (T (10),
1092 math::den_size<unsigned long long> (val)) }
1093 {
1094 }
1095
1104 [[nodiscard]] constexpr explicit
1105 operator T () const
1106 {
1107 return value_;
1108 }
1109
1120 [[nodiscard]] constexpr decltype (auto)
1121 get (void) const
1122 {
1123 return value_;
1124 }
1125
1130 };
1131
1132 // ------------------------------------------------------------------------
1133 } // namespace type_traits
1134
1135 // --------------------------------------------------------------------------
1136} // namespace micro_os_plus::micro_test_plus
1137
1138#if defined(__GNUC__)
1139#pragma GCC diagnostic pop
1140#endif
1141
1142// ----------------------------------------------------------------------------
1143
1144#endif // __cplusplus
1145
1146// ----------------------------------------------------------------------------
1147
1148#endif // MICRO_TEST_PLUS_TYPE_TRAITS_H_
1149
1150// ----------------------------------------------------------------------------
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.