44 * Copyright (c) 2011-2012, 2014-2015, Niklas Hauser
55 * Copyright (c) 2015, Sascha Schade
66 * Copyright (c) 2020, Christopher Durand
7+ * Copyright (c) 2022, Thomas Sommer
78 *
89 * This file is part of the modm project.
910 *
1314 */
1415// ----------------------------------------------------------------------------
1516
16- #ifndef MODM_MATH_UTILS_MISC_HPP
17- #define MODM_MATH_UTILS_MISC_HPP
17+ #pragma once
1818
1919#include < cstddef>
2020#include < cmath>
2121#include < stdint.h>
2222#include < type_traits>
23+ #include < utility>
2324
2425#include < modm/architecture/utils.hpp>
2526
@@ -56,74 +57,58 @@ pow(uint32_t base, uint8_t exponent)
5657}
5758
5859/* *
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
6065 *
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
6467 *
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
6869 */
6970template <typename T>
70- inline const T&
71- min (const T& a, const T& b)
71+ constexpr T vmin (T a, T b)
7272{
73- if (b < a)
74- return b;
75- else
76- return a;
73+ return a < b ? a : b;
7774}
7875
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)
9378{
94- if (a < b)
95- return b;
96- else
97- return a;
79+ return a < b ? vmin (a, cs...) : vmin (b, cs...);
9880}
9981
10082/* *
10183 * This does what you think it does.
10284 *
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
10788 *
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
11192 */
11293template <typename T>
113- constexpr T
114- max (const T a, const T b, const T c)
94+ constexpr T vmax (T& a, T& b)
11595{
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...);
118103}
119104
120105/* *
121106 * This does what you think it does.
122107 *
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.
125110 * @param compare A comparison functor.
126- * @return The lesser of the parameters.
111+ * @return The lesser of the parameters.
127112 *
128113 * This will work on temporary expressions, since they are only evaluated
129114 * once, unlike a preprocessor macro.
@@ -132,19 +117,16 @@ template<typename T, typename Compare>
132117inline const T&
133118min (const T& a, const T& b, Compare compare)
134119{
135- if (compare (b, a))
136- return b;
137- else
138- return a;
120+ return compare (b, a) ? b : a;
139121}
140122
141123/* *
142124 * This does what you think it does.
143125 *
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.
148130 *
149131 * This will work on temporary expressions, since they are only evaluated
150132 * once, unlike a preprocessor macro.
@@ -153,25 +135,16 @@ template<typename T, typename Compare>
153135inline const T&
154136max (const T& a, const T& b, Compare compare)
155137{
156- if (compare (a, b))
157- return b;
158- else
159- return a;
138+ return compare (a, b) ? b : a;
160139}
161140
162141// / constexpr implementation of fabs
163- template <typename Float>
164- requires std::is_floating_point_v<Float>
142+ template <std::floating_point Float>
165143constexpr Float constexpr_fabs (Float number)
166144{
167- if (number >= 0 ) {
168- return number;
169- } else {
170- return -number;
171- }
145+ return number >= 0 ? number : -number;
172146}
173147
174148// / @}
175- } // namespace modm
176149
177- # endif
150+ } // namespace modm
0 commit comments