@micro-os-plus/micro-test-plus 2.1.1 → 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +349 -72
- package/CMakeLists.txt +15 -26
- package/LICENSE-Boost +23 -0
- package/README.md +1036 -256
- package/include/micro-os-plus/detail.h +733 -0
- package/include/micro-os-plus/inlines.h +161 -0
- package/include/micro-os-plus/literals.h +285 -0
- package/include/micro-os-plus/math.h +205 -0
- package/include/micro-os-plus/micro-test-plus.h +490 -103
- package/include/micro-os-plus/reflection.h +134 -0
- package/include/micro-os-plus/test-reporter-inlines.h +231 -0
- package/include/micro-os-plus/test-reporter.h +347 -0
- package/include/micro-os-plus/test-runner.h +132 -0
- package/include/micro-os-plus/test-suite.h +241 -0
- package/include/micro-os-plus/type-traits.h +346 -0
- package/meson.build +35 -11
- package/package.json +243 -147
- package/src/micro-test-plus.cpp +105 -188
- package/src/test-reporter.cpp +423 -0
- package/src/test-runner.cpp +186 -0
- package/src/test-suite.cpp +133 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of the µOS++ distribution.
|
|
3
|
+
* (https://github.com/micro-os-plus/)
|
|
4
|
+
* Copyright (c) 2021 Liviu Ionescu.
|
|
5
|
+
*
|
|
6
|
+
* Permission to use, copy, modify, and/or distribute this software
|
|
7
|
+
* for any purpose is hereby granted, under the terms of the MIT license.
|
|
8
|
+
*
|
|
9
|
+
* If a copy of the license was not distributed with this file, it can
|
|
10
|
+
* be obtained from <https://opensource.org/licenses/MIT/>.
|
|
11
|
+
*
|
|
12
|
+
* Major parts of the code are inspired from v1.1.8 of the Boost UT project,
|
|
13
|
+
* released under the terms of the Boost Version 1.0 Software License,
|
|
14
|
+
* which can be obtained from <https://www.boost.org/LICENSE_1_0.txt>.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
#ifndef MICRO_TEST_PLUS_TEST_RUNNER_H_
|
|
18
|
+
#define MICRO_TEST_PLUS_TEST_RUNNER_H_
|
|
19
|
+
|
|
20
|
+
// ----------------------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
#ifdef __cplusplus
|
|
23
|
+
|
|
24
|
+
// ----------------------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
#include <functional>
|
|
27
|
+
|
|
28
|
+
// ----------------------------------------------------------------------------
|
|
29
|
+
|
|
30
|
+
#if defined(__GNUC__)
|
|
31
|
+
#pragma GCC diagnostic push
|
|
32
|
+
#pragma GCC diagnostic ignored "-Wpadded"
|
|
33
|
+
#if defined(__clang__)
|
|
34
|
+
#pragma clang diagnostic ignored "-Wc++98-compat"
|
|
35
|
+
#endif
|
|
36
|
+
#endif
|
|
37
|
+
|
|
38
|
+
namespace micro_os_plus::micro_test_plus
|
|
39
|
+
{
|
|
40
|
+
// --------------------------------------------------------------------------
|
|
41
|
+
|
|
42
|
+
class test_suite_base;
|
|
43
|
+
|
|
44
|
+
// --------------------------------------------------------------------------
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @brief The test runner. It maintaines a list of test suites which
|
|
48
|
+
* automatically register themselves in their constructors.
|
|
49
|
+
*/
|
|
50
|
+
class test_runner
|
|
51
|
+
{
|
|
52
|
+
public:
|
|
53
|
+
test_runner ();
|
|
54
|
+
|
|
55
|
+
// The rule of five.
|
|
56
|
+
test_runner (const test_runner&) = delete;
|
|
57
|
+
test_runner (test_runner&&) = delete;
|
|
58
|
+
test_runner&
|
|
59
|
+
operator= (const test_runner&)
|
|
60
|
+
= delete;
|
|
61
|
+
test_runner&
|
|
62
|
+
operator= (test_runner&&)
|
|
63
|
+
= delete;
|
|
64
|
+
|
|
65
|
+
~test_runner () = default;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @brief Pass the main arguments explicitly, if the default
|
|
69
|
+
* contructor was used.
|
|
70
|
+
*/
|
|
71
|
+
void
|
|
72
|
+
initialize (int argc, char* argv[], const char* name);
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @brief Return 0 if the all tests were successful, 1 otherwise.
|
|
76
|
+
*/
|
|
77
|
+
int
|
|
78
|
+
exit_code (void);
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* @brief Called by test suite constructors to register them
|
|
82
|
+
* to the runner.
|
|
83
|
+
*/
|
|
84
|
+
void
|
|
85
|
+
register_test_suite (test_suite_base* suite);
|
|
86
|
+
|
|
87
|
+
constexpr const char*
|
|
88
|
+
name (void)
|
|
89
|
+
{
|
|
90
|
+
return default_suite_name_;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
[[noreturn]] void
|
|
94
|
+
abort (void);
|
|
95
|
+
|
|
96
|
+
protected:
|
|
97
|
+
int argc_ = 0;
|
|
98
|
+
char** argv_ = nullptr;
|
|
99
|
+
|
|
100
|
+
const char* default_suite_name_ = "Test";
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @brief Pointer to the default test suite which groups
|
|
104
|
+
* the main tests.
|
|
105
|
+
*/
|
|
106
|
+
test_suite_base* default_test_suite_;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* @brief Pointer to array of registered test suites.
|
|
110
|
+
* Statically initialised to zero as BSS, such that
|
|
111
|
+
* test suites defined as static objects in different
|
|
112
|
+
* compilation units can be automatically executed.
|
|
113
|
+
*/
|
|
114
|
+
std::vector<test_suite_base*>* suites_;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
// --------------------------------------------------------------------------
|
|
118
|
+
} // namespace micro_os_plus::micro_test_plus
|
|
119
|
+
|
|
120
|
+
#if defined(__GNUC__)
|
|
121
|
+
#pragma GCC diagnostic pop
|
|
122
|
+
#endif
|
|
123
|
+
|
|
124
|
+
// ----------------------------------------------------------------------------
|
|
125
|
+
|
|
126
|
+
#endif // __cplusplus
|
|
127
|
+
|
|
128
|
+
// ----------------------------------------------------------------------------
|
|
129
|
+
|
|
130
|
+
#endif // MICRO_TEST_PLUS_TEST_RUNNER_H_
|
|
131
|
+
|
|
132
|
+
// ----------------------------------------------------------------------------
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of the µOS++ distribution.
|
|
3
|
+
* (https://github.com/micro-os-plus/)
|
|
4
|
+
* Copyright (c) 2021 Liviu Ionescu.
|
|
5
|
+
*
|
|
6
|
+
* Permission to use, copy, modify, and/or distribute this software
|
|
7
|
+
* for any purpose is hereby granted, under the terms of the MIT license.
|
|
8
|
+
*
|
|
9
|
+
* If a copy of the license was not distributed with this file, it can
|
|
10
|
+
* be obtained from <https://opensource.org/licenses/MIT/>.
|
|
11
|
+
*
|
|
12
|
+
* Major parts of the code are inspired from v1.1.8 of the Boost UT project,
|
|
13
|
+
* released under the terms of the Boost Version 1.0 Software License,
|
|
14
|
+
* which can be obtained from <https://www.boost.org/LICENSE_1_0.txt>.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
#ifndef MICRO_TEST_PLUS_TEST_SUITE_H_
|
|
18
|
+
#define MICRO_TEST_PLUS_TEST_SUITE_H_
|
|
19
|
+
|
|
20
|
+
// ----------------------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
#ifdef __cplusplus
|
|
23
|
+
|
|
24
|
+
// ----------------------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
#include <functional>
|
|
27
|
+
|
|
28
|
+
// ----------------------------------------------------------------------------
|
|
29
|
+
|
|
30
|
+
#if defined(__GNUC__)
|
|
31
|
+
#pragma GCC diagnostic push
|
|
32
|
+
#pragma GCC diagnostic ignored "-Wpadded"
|
|
33
|
+
#if !defined(__clang__) // GCC only
|
|
34
|
+
#pragma GCC diagnostic ignored "-Wsuggest-final-types"
|
|
35
|
+
#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
|
|
36
|
+
#endif
|
|
37
|
+
#if defined(__clang__)
|
|
38
|
+
#pragma clang diagnostic ignored "-Wc++98-compat"
|
|
39
|
+
#endif
|
|
40
|
+
#endif
|
|
41
|
+
|
|
42
|
+
namespace micro_os_plus::micro_test_plus
|
|
43
|
+
{
|
|
44
|
+
// --------------------------------------------------------------------------
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @brief Test suites are classes that represent a named group of
|
|
48
|
+
* test cases which self registers to the runner.
|
|
49
|
+
*/
|
|
50
|
+
class test_suite_base
|
|
51
|
+
{
|
|
52
|
+
public:
|
|
53
|
+
/**
|
|
54
|
+
* @brief Construct the default suite used in main().
|
|
55
|
+
*/
|
|
56
|
+
test_suite_base (const char* name);
|
|
57
|
+
|
|
58
|
+
// The rule of five.
|
|
59
|
+
test_suite_base (const test_suite_base&) = delete;
|
|
60
|
+
test_suite_base (test_suite_base&&) = delete;
|
|
61
|
+
test_suite_base&
|
|
62
|
+
operator= (const test_suite_base&)
|
|
63
|
+
= delete;
|
|
64
|
+
test_suite_base&
|
|
65
|
+
operator= (test_suite_base&&)
|
|
66
|
+
= delete;
|
|
67
|
+
|
|
68
|
+
virtual ~test_suite_base ();
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @brief Run the sequence of test cases in the suite.
|
|
72
|
+
*/
|
|
73
|
+
virtual void
|
|
74
|
+
run (void);
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @brief Mark the begining of a named test case.
|
|
78
|
+
*/
|
|
79
|
+
void
|
|
80
|
+
begin_test_case (const char* name);
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @brief Mark the end of a test case.
|
|
84
|
+
*/
|
|
85
|
+
void
|
|
86
|
+
end_test_case (void);
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @brief Get the suite name.
|
|
90
|
+
*/
|
|
91
|
+
[[nodiscard]] constexpr const char*
|
|
92
|
+
name ()
|
|
93
|
+
{
|
|
94
|
+
return name_;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* @brief Count one more passed test condition.
|
|
99
|
+
*/
|
|
100
|
+
void
|
|
101
|
+
increment_successful (void);
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @brief Count one more failed test condition.
|
|
105
|
+
*/
|
|
106
|
+
void
|
|
107
|
+
increment_failed (void);
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @brief Get the number of conditions that passed.
|
|
111
|
+
*/
|
|
112
|
+
[[nodiscard]] constexpr int
|
|
113
|
+
successful_checks (void)
|
|
114
|
+
{
|
|
115
|
+
return successful_checks_;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @brief Get the number of conditions that failed.
|
|
120
|
+
*/
|
|
121
|
+
[[nodiscard]] constexpr int
|
|
122
|
+
failed_checks (void)
|
|
123
|
+
{
|
|
124
|
+
return failed_checks_;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* @brief Get the number of test cases.
|
|
129
|
+
*/
|
|
130
|
+
[[nodiscard]] constexpr int
|
|
131
|
+
test_cases (void)
|
|
132
|
+
{
|
|
133
|
+
return test_cases_;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* @brief Begin the execution of the test suite.
|
|
138
|
+
*/
|
|
139
|
+
void
|
|
140
|
+
begin_test_suite (void);
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* @brief Mark the end of the test suite.
|
|
144
|
+
*/
|
|
145
|
+
void
|
|
146
|
+
end_test_suite (void);
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* @brief Get the test suite result.
|
|
150
|
+
*/
|
|
151
|
+
[[nodiscard]] constexpr bool
|
|
152
|
+
was_successful (void)
|
|
153
|
+
{
|
|
154
|
+
// Also fail if none passed.
|
|
155
|
+
return (failed_checks_ == 0 && successful_checks_ != 0);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
[[nodiscard]] constexpr bool
|
|
159
|
+
unused (void)
|
|
160
|
+
{
|
|
161
|
+
return (failed_checks_ == 0 && successful_checks_ == 0
|
|
162
|
+
&& test_cases_ == 0);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
protected:
|
|
166
|
+
/**
|
|
167
|
+
* @brief The test suite name.
|
|
168
|
+
*/
|
|
169
|
+
const char* name_;
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* @brief The current test case name.
|
|
173
|
+
*/
|
|
174
|
+
const char* test_case_name_;
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* @brief Count of test conditions that passed.
|
|
178
|
+
*/
|
|
179
|
+
int successful_checks_ = 0;
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* @brief Count of test conditions that failed.
|
|
183
|
+
*/
|
|
184
|
+
int failed_checks_ = 0;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* @brief Count of test cases in the test suite.
|
|
188
|
+
*/
|
|
189
|
+
int test_cases_ = 0;
|
|
190
|
+
|
|
191
|
+
public:
|
|
192
|
+
bool process_deferred_begin = true;
|
|
193
|
+
struct
|
|
194
|
+
{
|
|
195
|
+
int successful_checks;
|
|
196
|
+
int failed_checks;
|
|
197
|
+
} current_test_case{};
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
class test_suite : public test_suite_base
|
|
201
|
+
{
|
|
202
|
+
public:
|
|
203
|
+
template <typename Callable_T, typename... Args_T>
|
|
204
|
+
test_suite (const char* name, Callable_T&& callable,
|
|
205
|
+
Args_T&&... arguments);
|
|
206
|
+
|
|
207
|
+
// The rule of five.
|
|
208
|
+
test_suite (const test_suite&) = delete;
|
|
209
|
+
test_suite (test_suite&&) = delete;
|
|
210
|
+
test_suite&
|
|
211
|
+
operator= (const test_suite&)
|
|
212
|
+
= delete;
|
|
213
|
+
test_suite&
|
|
214
|
+
operator= (test_suite&&)
|
|
215
|
+
= delete;
|
|
216
|
+
|
|
217
|
+
virtual ~test_suite () override;
|
|
218
|
+
|
|
219
|
+
virtual void
|
|
220
|
+
run (void) override;
|
|
221
|
+
|
|
222
|
+
protected:
|
|
223
|
+
std::function<void (void)> callable_;
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
// --------------------------------------------------------------------------
|
|
227
|
+
} // namespace micro_os_plus::micro_test_plus
|
|
228
|
+
|
|
229
|
+
#if defined(__GNUC__)
|
|
230
|
+
#pragma GCC diagnostic pop
|
|
231
|
+
#endif
|
|
232
|
+
|
|
233
|
+
// ----------------------------------------------------------------------------
|
|
234
|
+
|
|
235
|
+
#endif // __cplusplus
|
|
236
|
+
|
|
237
|
+
// ----------------------------------------------------------------------------
|
|
238
|
+
|
|
239
|
+
#endif // MICRO_TEST_PLUS_TEST_SUITE_H_
|
|
240
|
+
|
|
241
|
+
// ----------------------------------------------------------------------------
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of the µOS++ distribution.
|
|
3
|
+
* (https://github.com/micro-os-plus/)
|
|
4
|
+
* Copyright (c) 2021 Liviu Ionescu.
|
|
5
|
+
*
|
|
6
|
+
* Permission to use, copy, modify, and/or distribute this software
|
|
7
|
+
* for any purpose is hereby granted, under the terms of the MIT license.
|
|
8
|
+
*
|
|
9
|
+
* If a copy of the license was not distributed with this file, it can
|
|
10
|
+
* be obtained from <https://opensource.org/licenses/MIT/>.
|
|
11
|
+
*
|
|
12
|
+
* Major parts of the code are inspired from v1.1.8 of the Boost UT project,
|
|
13
|
+
* released under the terms of the Boost Version 1.0 Software License,
|
|
14
|
+
* which can be obtained from <https://www.boost.org/LICENSE_1_0.txt>.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
#ifndef MICRO_TEST_PLUS_TYPE_TRAITS_H_
|
|
18
|
+
#define MICRO_TEST_PLUS_TYPE_TRAITS_H_
|
|
19
|
+
|
|
20
|
+
// ----------------------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
#ifdef __cplusplus
|
|
23
|
+
|
|
24
|
+
// ----------------------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
#include "math.h"
|
|
27
|
+
|
|
28
|
+
// ----------------------------------------------------------------------------
|
|
29
|
+
|
|
30
|
+
#if defined(__GNUC__)
|
|
31
|
+
#pragma GCC diagnostic push
|
|
32
|
+
#if defined(__clang__)
|
|
33
|
+
#pragma clang diagnostic ignored "-Wc++98-compat"
|
|
34
|
+
#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
|
|
35
|
+
#endif
|
|
36
|
+
#endif
|
|
37
|
+
|
|
38
|
+
namespace micro_os_plus::micro_test_plus
|
|
39
|
+
{
|
|
40
|
+
// --------------------------------------------------------------------------
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @brief Local type traits. Some may have standard equivalents, but
|
|
44
|
+
* better keep them locally.
|
|
45
|
+
*/
|
|
46
|
+
namespace type_traits
|
|
47
|
+
{
|
|
48
|
+
template <class...>
|
|
49
|
+
struct list
|
|
50
|
+
{
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
template <class T, class...>
|
|
54
|
+
struct identity
|
|
55
|
+
{
|
|
56
|
+
using type = T;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
template <class T>
|
|
60
|
+
struct function_traits : function_traits<decltype (&T::operator())>
|
|
61
|
+
{
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
template <class R, class... Args_T>
|
|
65
|
+
struct function_traits<R (*) (Args_T...)>
|
|
66
|
+
{
|
|
67
|
+
using result_type = R;
|
|
68
|
+
using args = list<Args_T...>;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
template <class R, class... Args_T>
|
|
72
|
+
struct function_traits<R (Args_T...)>
|
|
73
|
+
{
|
|
74
|
+
using result_type = R;
|
|
75
|
+
using args = list<Args_T...>;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
template <class R, class T, class... Args_T>
|
|
79
|
+
struct function_traits<R (T::*) (Args_T...)>
|
|
80
|
+
{
|
|
81
|
+
using result_type = R;
|
|
82
|
+
using args = list<Args_T...>;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
template <class R, class T, class... Args_T>
|
|
86
|
+
struct function_traits<R (T::*) (Args_T...) const>
|
|
87
|
+
{
|
|
88
|
+
using result_type = R;
|
|
89
|
+
using args = list<Args_T...>;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
template <class T>
|
|
93
|
+
T&&
|
|
94
|
+
declval ();
|
|
95
|
+
template <class... Ts, class Expr_T>
|
|
96
|
+
constexpr auto
|
|
97
|
+
is_valid (Expr_T expr) -> decltype (expr (declval<Ts...> ()), bool ())
|
|
98
|
+
{
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
template <class...>
|
|
103
|
+
constexpr auto
|
|
104
|
+
is_valid (...) -> bool
|
|
105
|
+
{
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
template <class T>
|
|
110
|
+
static constexpr auto is_container_v
|
|
111
|
+
= is_valid<T> ([] (auto t) -> decltype (t.begin (), t.end (),
|
|
112
|
+
void ()) {});
|
|
113
|
+
|
|
114
|
+
template <class T>
|
|
115
|
+
static constexpr auto has_npos_v
|
|
116
|
+
= is_valid<T> ([] (auto t) -> decltype (void (t.npos)) {});
|
|
117
|
+
|
|
118
|
+
template <class T>
|
|
119
|
+
static constexpr auto has_value_v
|
|
120
|
+
= is_valid<T> ([] (auto t) -> decltype (void (t.value)) {});
|
|
121
|
+
|
|
122
|
+
template <class T>
|
|
123
|
+
static constexpr auto has_epsilon_v
|
|
124
|
+
= is_valid<T> ([] (auto t) -> decltype (void (t.epsilon)) {});
|
|
125
|
+
|
|
126
|
+
template <class T>
|
|
127
|
+
inline constexpr auto is_floating_point_v = false;
|
|
128
|
+
template <>
|
|
129
|
+
inline constexpr auto is_floating_point_v<float> = true;
|
|
130
|
+
template <>
|
|
131
|
+
inline constexpr auto is_floating_point_v<double> = true;
|
|
132
|
+
template <>
|
|
133
|
+
inline constexpr auto is_floating_point_v<long double> = true;
|
|
134
|
+
|
|
135
|
+
#if defined(__clang__) or defined(_MSC_VER)
|
|
136
|
+
template <class From, class To>
|
|
137
|
+
static constexpr auto is_convertible_v = __is_convertible_to(From, To);
|
|
138
|
+
#else
|
|
139
|
+
template <class From, class To>
|
|
140
|
+
constexpr auto
|
|
141
|
+
is_convertible (int) -> decltype (bool (To (declval<From> ())))
|
|
142
|
+
{
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
template <class...>
|
|
146
|
+
constexpr auto
|
|
147
|
+
is_convertible (...)
|
|
148
|
+
{
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
template <class From, class To>
|
|
152
|
+
constexpr auto is_convertible_v = is_convertible<From, To> (0);
|
|
153
|
+
#endif
|
|
154
|
+
|
|
155
|
+
template <bool>
|
|
156
|
+
struct requires_
|
|
157
|
+
{
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
template <>
|
|
161
|
+
struct requires_<true>
|
|
162
|
+
{
|
|
163
|
+
using type = int;
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
template <bool Cond>
|
|
167
|
+
using requires_t = typename requires_<Cond>::type;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* @brief Empty base class of all operators.
|
|
171
|
+
*/
|
|
172
|
+
struct op
|
|
173
|
+
{
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* @brief A generic integral constant.
|
|
178
|
+
* It has a getter and a '-' operator to return the negative value.
|
|
179
|
+
*/
|
|
180
|
+
template <auto N>
|
|
181
|
+
struct integral_constant : op
|
|
182
|
+
{
|
|
183
|
+
using value_type = decltype (N);
|
|
184
|
+
static constexpr auto value = N;
|
|
185
|
+
|
|
186
|
+
[[nodiscard]] constexpr auto
|
|
187
|
+
operator- () const
|
|
188
|
+
{
|
|
189
|
+
return integral_constant<-N>{};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
[[nodiscard]] constexpr explicit operator value_type () const
|
|
193
|
+
{
|
|
194
|
+
return N;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
[[nodiscard]] constexpr auto
|
|
198
|
+
get () const
|
|
199
|
+
{
|
|
200
|
+
return N;
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* @brief A generic floating point constant, with custom size
|
|
206
|
+
* and precision.
|
|
207
|
+
* It has a getter and a '-' operator to return the negative value.
|
|
208
|
+
*/
|
|
209
|
+
template <class T, auto N, auto D, auto Size, auto P = 1>
|
|
210
|
+
struct floating_point_constant : op
|
|
211
|
+
{
|
|
212
|
+
using value_type = T;
|
|
213
|
+
|
|
214
|
+
static constexpr auto epsilon = T (1) / math::pow (T (10), Size - 1);
|
|
215
|
+
static constexpr auto value
|
|
216
|
+
= T (P) * (T (N) + (T (D) / math::pow (T (10), Size)));
|
|
217
|
+
|
|
218
|
+
[[nodiscard]] constexpr auto
|
|
219
|
+
operator- () const
|
|
220
|
+
{
|
|
221
|
+
return floating_point_constant<T, N, D, Size, -1>{};
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
[[nodiscard]] constexpr explicit operator value_type () const
|
|
225
|
+
{
|
|
226
|
+
return value;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
[[nodiscard]] constexpr auto
|
|
230
|
+
get () const
|
|
231
|
+
{
|
|
232
|
+
return value;
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
template <class T>
|
|
237
|
+
struct genuine_integral_value : op
|
|
238
|
+
{
|
|
239
|
+
using value_type = T;
|
|
240
|
+
|
|
241
|
+
constexpr genuine_integral_value (const T& _value) : value_{ _value }
|
|
242
|
+
{
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
[[nodiscard]] constexpr explicit operator T () const
|
|
246
|
+
{
|
|
247
|
+
return value_;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
[[nodiscard]] constexpr decltype (auto)
|
|
251
|
+
get () const
|
|
252
|
+
{
|
|
253
|
+
return value_;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
T value_{};
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
template <class T>
|
|
260
|
+
inline constexpr auto is_op_v = __is_base_of(type_traits::op, T);
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* @brief Class defining a generic value, accessible via a getter.
|
|
264
|
+
*/
|
|
265
|
+
template <class T, class = int>
|
|
266
|
+
struct value : type_traits::op
|
|
267
|
+
{
|
|
268
|
+
using value_type = T;
|
|
269
|
+
|
|
270
|
+
constexpr value (const T& _value) : value_{ _value }
|
|
271
|
+
{
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
[[nodiscard]] constexpr explicit operator T () const
|
|
275
|
+
{
|
|
276
|
+
return value_;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
[[nodiscard]] constexpr decltype (auto)
|
|
280
|
+
get () const
|
|
281
|
+
{
|
|
282
|
+
return value_;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
T value_{};
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* @brief A generic value used to define floating points, which,
|
|
290
|
+
* in addition to the actual value, has an epsilon, to use the
|
|
291
|
+
* desired precision during comparisons.
|
|
292
|
+
* If missing, the default is 1 / (10^decimals).
|
|
293
|
+
*/
|
|
294
|
+
template <class T>
|
|
295
|
+
struct value<T,
|
|
296
|
+
type_traits::requires_t<type_traits::is_floating_point_v<T>>>
|
|
297
|
+
: type_traits::op
|
|
298
|
+
{
|
|
299
|
+
using value_type = T;
|
|
300
|
+
static inline auto epsilon = T{}; // Why static?
|
|
301
|
+
|
|
302
|
+
constexpr value (const T& _value, const T precision) : value_{ _value }
|
|
303
|
+
{
|
|
304
|
+
epsilon = precision;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
constexpr /*explicit(false)*/ value (const T& val)
|
|
308
|
+
: value{ val,
|
|
309
|
+
T (1)
|
|
310
|
+
/ math::pow (T (10),
|
|
311
|
+
math::den_size<unsigned long long> (val)) }
|
|
312
|
+
{
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
[[nodiscard]] constexpr explicit operator T () const
|
|
316
|
+
{
|
|
317
|
+
return value_;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
[[nodiscard]] constexpr decltype (auto)
|
|
321
|
+
get () const
|
|
322
|
+
{
|
|
323
|
+
return value_;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
T value_{};
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
} // namespace type_traits
|
|
330
|
+
|
|
331
|
+
// --------------------------------------------------------------------------
|
|
332
|
+
} // namespace micro_os_plus::micro_test_plus
|
|
333
|
+
|
|
334
|
+
#if defined(__GNUC__)
|
|
335
|
+
#pragma GCC diagnostic pop
|
|
336
|
+
#endif
|
|
337
|
+
|
|
338
|
+
// ----------------------------------------------------------------------------
|
|
339
|
+
|
|
340
|
+
#endif // __cplusplus
|
|
341
|
+
|
|
342
|
+
// ----------------------------------------------------------------------------
|
|
343
|
+
|
|
344
|
+
#endif // MICRO_TEST_PLUS_TYPE_TRAITS_H_
|
|
345
|
+
|
|
346
|
+
// ----------------------------------------------------------------------------
|