mirror of
https://github.com/BlackMATov/vmath.hpp.git
synced 2025-12-15 04:35:25 +07:00
fun: initializer_list min/max instead variadic
This commit is contained in:
@@ -86,12 +86,28 @@ namespace vmath_hpp
|
|||||||
return x < y ? x : y;
|
return x < y ? x : y;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T, typename... Ts >
|
template < typename T >
|
||||||
[[nodiscard]] std::enable_if_t<
|
[[nodiscard]] constexpr T min(std::initializer_list<T> xs) {
|
||||||
std::is_arithmetic_v<T>,
|
auto iter = xs.begin();
|
||||||
std::common_type_t<T, Ts...>>
|
auto smallest = iter++;
|
||||||
constexpr min(T x, T y, Ts... ts) noexcept {
|
for ( auto last = xs.end(); iter != last; ++iter ) {
|
||||||
return min(min(x, y), ts...);
|
if ( *iter < *smallest ) {
|
||||||
|
smallest = iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *smallest;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T, class Compare >
|
||||||
|
[[nodiscard]] constexpr T min(std::initializer_list<T> xs, Compare comp) {
|
||||||
|
auto iter = xs.begin();
|
||||||
|
auto smallest = iter++;
|
||||||
|
for ( auto last = xs.end(); iter != last; ++iter ) {
|
||||||
|
if ( comp(*iter, *smallest) ) {
|
||||||
|
smallest = iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *smallest;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
@@ -100,12 +116,28 @@ namespace vmath_hpp
|
|||||||
return x < y ? y : x;
|
return x < y ? y : x;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T, typename... Ts >
|
template < typename T >
|
||||||
[[nodiscard]] std::enable_if_t<
|
[[nodiscard]] constexpr T max(std::initializer_list<T> xs) {
|
||||||
std::is_arithmetic_v<T>,
|
auto iter = xs.begin();
|
||||||
std::common_type_t<T, Ts...>>
|
auto largest = iter++;
|
||||||
constexpr max(T x, T y, Ts... ts) noexcept {
|
for ( auto last = xs.end(); iter != last; ++iter ) {
|
||||||
return max(max(x, y), ts...);
|
if ( *largest < *iter ) {
|
||||||
|
largest = iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *largest;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T, class Compare >
|
||||||
|
[[nodiscard]] constexpr T max(std::initializer_list<T> xs, Compare comp) {
|
||||||
|
auto iter = xs.begin();
|
||||||
|
auto largest = iter++;
|
||||||
|
for ( auto last = xs.end(); iter != last; ++iter ) {
|
||||||
|
if ( comp(*largest, *iter) ) {
|
||||||
|
largest = iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *largest;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
@@ -422,7 +454,7 @@ namespace vmath_hpp
|
|||||||
if constexpr ( std::is_floating_point_v<T> ) {
|
if constexpr ( std::is_floating_point_v<T> ) {
|
||||||
// http://www.realtimecollisiondetection.net/pubs/Tolerances
|
// http://www.realtimecollisiondetection.net/pubs/Tolerances
|
||||||
const T epsilon = std::numeric_limits<T>::epsilon();
|
const T epsilon = std::numeric_limits<T>::epsilon();
|
||||||
return abs(x - y) <= epsilon * max(T(1), abs(x), abs(y));
|
return abs(x - y) <= epsilon * max({T(1), abs(x), abs(y)});
|
||||||
} else {
|
} else {
|
||||||
return x == y;
|
return x == y;
|
||||||
}
|
}
|
||||||
@@ -433,7 +465,7 @@ namespace vmath_hpp
|
|||||||
constexpr approx(T x, T y, T epsilon) noexcept {
|
constexpr approx(T x, T y, T epsilon) noexcept {
|
||||||
if constexpr ( std::is_floating_point_v<T> ) {
|
if constexpr ( std::is_floating_point_v<T> ) {
|
||||||
// http://www.realtimecollisiondetection.net/pubs/Tolerances
|
// http://www.realtimecollisiondetection.net/pubs/Tolerances
|
||||||
return abs(x - y) <= epsilon * max(T(1), abs(x), abs(y));
|
return abs(x - y) <= epsilon * max({T(1), abs(x), abs(y)});
|
||||||
} else {
|
} else {
|
||||||
return abs(x - y) <= epsilon;
|
return abs(x - y) <= epsilon;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,12 +86,32 @@ TEST_CASE("vmath/fun") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
STATIC_REQUIRE(min(0.f, 1.f) == uapprox(0.f));
|
STATIC_REQUIRE(min(0.f, 1.f) == uapprox(0.f));
|
||||||
STATIC_REQUIRE(min(3.f, 2.f, 1.f) == uapprox(1.f));
|
|
||||||
STATIC_REQUIRE(min(4.f, 3.f, 2.f, 1.f) == uapprox(1.f));
|
|
||||||
|
|
||||||
STATIC_REQUIRE(max(0.f, 1.f) == uapprox(1.f));
|
STATIC_REQUIRE(max(0.f, 1.f) == uapprox(1.f));
|
||||||
STATIC_REQUIRE(max(3.f, 2.f, 1.f) == uapprox(3.f));
|
|
||||||
STATIC_REQUIRE(max(4.f, 3.f, 2.f, 1.f) == uapprox(4.f));
|
STATIC_REQUIRE(min({0.f}) == uapprox(0.f));
|
||||||
|
STATIC_REQUIRE(min({0.f, 1.f}) == uapprox(0.f));
|
||||||
|
STATIC_REQUIRE(min({3.f, 2.f, 1.f}) == uapprox(1.f));
|
||||||
|
STATIC_REQUIRE(min({4.f, 3.f, 2.f, 1.f}) == uapprox(1.f));
|
||||||
|
|
||||||
|
STATIC_REQUIRE(min({0.f}, [](auto x, auto y){return x < y;}) == uapprox(0.f));
|
||||||
|
STATIC_REQUIRE(min({0.f, 1.f}, [](auto x, auto y){return x < y;}) == uapprox(0.f));
|
||||||
|
STATIC_REQUIRE(min({3.f, 2.f, 1.f}, [](auto x, auto y){return x < y;}) == uapprox(1.f));
|
||||||
|
STATIC_REQUIRE(min({4.f, 3.f, 2.f, 1.f}, [](auto x, auto y){return x < y;}) == uapprox(1.f));
|
||||||
|
|
||||||
|
STATIC_REQUIRE(min({0.f}, [](auto x, auto y){return x > y;}) == uapprox(0.f));
|
||||||
|
STATIC_REQUIRE(min({0.f, 1.f}, [](auto x, auto y){return x > y;}) == uapprox(1.f));
|
||||||
|
STATIC_REQUIRE(min({3.f, 2.f, 1.f}, [](auto x, auto y){return x > y;}) == uapprox(3.f));
|
||||||
|
STATIC_REQUIRE(min({4.f, 3.f, 2.f, 1.f}, [](auto x, auto y){return x > y;}) == uapprox(4.f));
|
||||||
|
|
||||||
|
STATIC_REQUIRE(max({0.f}, [](auto x, auto y){return x < y;}) == uapprox(0.f));
|
||||||
|
STATIC_REQUIRE(max({0.f, 1.f}, [](auto x, auto y){return x < y;}) == uapprox(1.f));
|
||||||
|
STATIC_REQUIRE(max({3.f, 2.f, 1.f}, [](auto x, auto y){return x < y;}) == uapprox(3.f));
|
||||||
|
STATIC_REQUIRE(max({4.f, 3.f, 2.f, 1.f}, [](auto x, auto y){return x < y;}) == uapprox(4.f));
|
||||||
|
|
||||||
|
STATIC_REQUIRE(max({0.f}, [](auto x, auto y){return x > y;}) == uapprox(0.f));
|
||||||
|
STATIC_REQUIRE(max({0.f, 1.f}, [](auto x, auto y){return x > y;}) == uapprox(0.f));
|
||||||
|
STATIC_REQUIRE(max({3.f, 2.f, 1.f}, [](auto x, auto y){return x > y;}) == uapprox(1.f));
|
||||||
|
STATIC_REQUIRE(max({4.f, 3.f, 2.f, 1.f}, [](auto x, auto y){return x > y;}) == uapprox(1.f));
|
||||||
|
|
||||||
STATIC_REQUIRE(clamp(1.0f, 2.f, 3.f) == uapprox(2.0f));
|
STATIC_REQUIRE(clamp(1.0f, 2.f, 3.f) == uapprox(2.0f));
|
||||||
STATIC_REQUIRE(clamp(2.5f, 2.f, 3.f) == uapprox(2.5f));
|
STATIC_REQUIRE(clamp(2.5f, 2.f, 3.f) == uapprox(2.5f));
|
||||||
|
|||||||
Reference in New Issue
Block a user