4
4
* Copyright (c) 2011-2012, 2014-2015, Niklas Hauser
5
5
* Copyright (c) 2015, Sascha Schade
6
6
* Copyright (c) 2020, Christopher Durand
7
+ * Copyright (c) 2022, Thomas Sommer
7
8
*
8
9
* This file is part of the modm project.
9
10
*
13
14
*/
14
15
// ----------------------------------------------------------------------------
15
16
16
- #ifndef MODM_MATH_UTILS_MISC_HPP
17
- #define MODM_MATH_UTILS_MISC_HPP
17
+ #pragma once
18
18
19
19
#include < cstddef>
20
20
#include < cmath>
21
21
#include < stdint.h>
22
22
#include < type_traits>
23
+ #include < utility>
23
24
24
25
#include < modm/architecture/utils.hpp>
25
26
@@ -56,74 +57,58 @@ pow(uint32_t base, uint8_t exponent)
56
57
}
57
58
58
59
/* *
59
- * This does what you think it does.
60
+ * @brief Variadic min for 2-∞ objects
61
+ *
62
+ * @param a first object to compare
63
+ * @param b second object to compare
64
+ * @param cs Further objects for comparison
60
65
*
61
- * @param a A thing of arbitrary type.
62
- * @param b Another thing of arbitrary type.
63
- * @return The lesser of the parameters.
66
+ * @return The smallest object
64
67
*
65
- * This is the simple classic generic implementation. It will work on
66
- * temporary expressions, since they are only evaluated once, unlike a
67
- * preprocessor macro.
68
+ * @see https://stackoverflow.com/questions/23815138/implementing-variadic-min-max-functions
68
69
*/
69
70
template <typename T>
70
- inline const T&
71
- min (const T& a, const T& b)
71
+ constexpr T vmin (T a, T b)
72
72
{
73
- if (b < a)
74
- return b;
75
- else
76
- return a;
73
+ return a < b ? a : b;
77
74
}
78
75
79
- /* *
80
- * This does what you think it does.
81
- *
82
- * @param a A thing of arbitrary type.
83
- * @param b Another thing of arbitrary type.
84
- * @return The greater of the parameters.
85
- *
86
- * This is the simple classic generic implementation. It will work on
87
- * temporary expressions, since they are only evaluated once, unlike a
88
- * preprocessor macro.
89
- */
90
- template <typename T>
91
- inline const T&
92
- max (const T& a, const T& b)
76
+ template <typename T, typename ... Ts>
77
+ constexpr T vmin (T a, T b, Ts&&... cs)
93
78
{
94
- if (a < b)
95
- return b;
96
- else
97
- return a;
79
+ return a < b ? vmin (a, cs...) : vmin (b, cs...);
98
80
}
99
81
100
82
/* *
101
83
* This does what you think it does.
102
84
*
103
- * @param a A thing of arbitrary type.
104
- * @param b Another thing of arbitrary type.
105
- * @param c Something else of arbitrary type.
106
- * @return The greater of the three parameters.
85
+ * @param a first object to compare
86
+ * @param b second object to compare
87
+ * @param cs Further objects to compare
107
88
*
108
- * This is the simple classic generic implementation. It will work on
109
- * temporary expressions, since they are only evaluated once, unlike a
110
- * preprocessor macro.
89
+ * @return The biggest object
90
+ *
91
+ * @see https://stackoverflow.com/questions/23815138/implementing-variadic-min-max-functions
111
92
*/
112
93
template <typename T>
113
- constexpr T
114
- max (const T a, const T b, const T c)
94
+ constexpr T vmax (T& a, T& b)
115
95
{
116
- return ( ( (b > c) ? b : c ) > a ) ?
117
- ( (b > c) ? b : c) : a;
96
+ return a > b ? a : b;
97
+ }
98
+
99
+ template <typename T, typename ... Ts>
100
+ constexpr T vmax (T& a, T& b, Ts&... cs)
101
+ {
102
+ return a > b ? vmax (a, cs...) : vmax (b, cs...);
118
103
}
119
104
120
105
/* *
121
106
* This does what you think it does.
122
107
*
123
- * @param a A thing of arbitrary type.
124
- * @param b Another thing of arbitrary type.
108
+ * @param a A thing of arbitrary type.
109
+ * @param b Another thing of arbitrary type.
125
110
* @param compare A comparison functor.
126
- * @return The lesser of the parameters.
111
+ * @return The lesser of the parameters.
127
112
*
128
113
* This will work on temporary expressions, since they are only evaluated
129
114
* once, unlike a preprocessor macro.
@@ -132,19 +117,16 @@ template<typename T, typename Compare>
132
117
inline const T&
133
118
min (const T& a, const T& b, Compare compare)
134
119
{
135
- if (compare (b, a))
136
- return b;
137
- else
138
- return a;
120
+ return compare (b, a) ? b : a;
139
121
}
140
122
141
123
/* *
142
124
* This does what you think it does.
143
125
*
144
- * @param a A thing of arbitrary type.
145
- * @param b Another thing of arbitrary type.
146
- * @param compare A comparison functor.
147
- * @return The greater of the parameters.
126
+ * @param a A thing of arbitrary type.
127
+ * @param b Another thing of arbitrary type.
128
+ * @param compare A comparison functor.
129
+ * @return The greater of the parameters.
148
130
*
149
131
* This will work on temporary expressions, since they are only evaluated
150
132
* once, unlike a preprocessor macro.
@@ -153,25 +135,16 @@ template<typename T, typename Compare>
153
135
inline const T&
154
136
max (const T& a, const T& b, Compare compare)
155
137
{
156
- if (compare (a, b))
157
- return b;
158
- else
159
- return a;
138
+ return compare (a, b) ? b : a;
160
139
}
161
140
162
141
// / constexpr implementation of fabs
163
- template <typename Float>
164
- requires std::is_floating_point_v<Float>
142
+ template <std::floating_point Float>
165
143
constexpr Float constexpr_fabs (Float number)
166
144
{
167
- if (number >= 0 ) {
168
- return number;
169
- } else {
170
- return -number;
171
- }
145
+ return number >= 0 ? number : -number;
172
146
}
173
147
174
148
// / @}
175
- } // namespace modm
176
149
177
- # endif
150
+ } // namespace modm
0 commit comments