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;
|
||||
}
|
||||
|
||||
template < typename T, typename... Ts >
|
||||
[[nodiscard]] std::enable_if_t<
|
||||
std::is_arithmetic_v<T>,
|
||||
std::common_type_t<T, Ts...>>
|
||||
constexpr min(T x, T y, Ts... ts) noexcept {
|
||||
return min(min(x, y), ts...);
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr T min(std::initializer_list<T> xs) {
|
||||
auto iter = xs.begin();
|
||||
auto smallest = iter++;
|
||||
for ( auto last = xs.end(); iter != last; ++iter ) {
|
||||
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 >
|
||||
@@ -100,12 +116,28 @@ namespace vmath_hpp
|
||||
return x < y ? y : x;
|
||||
}
|
||||
|
||||
template < typename T, typename... Ts >
|
||||
[[nodiscard]] std::enable_if_t<
|
||||
std::is_arithmetic_v<T>,
|
||||
std::common_type_t<T, Ts...>>
|
||||
constexpr max(T x, T y, Ts... ts) noexcept {
|
||||
return max(max(x, y), ts...);
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr T max(std::initializer_list<T> xs) {
|
||||
auto iter = xs.begin();
|
||||
auto largest = iter++;
|
||||
for ( auto last = xs.end(); iter != last; ++iter ) {
|
||||
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 >
|
||||
@@ -422,7 +454,7 @@ namespace vmath_hpp
|
||||
if constexpr ( std::is_floating_point_v<T> ) {
|
||||
// http://www.realtimecollisiondetection.net/pubs/Tolerances
|
||||
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 {
|
||||
return x == y;
|
||||
}
|
||||
@@ -433,7 +465,7 @@ namespace vmath_hpp
|
||||
constexpr approx(T x, T y, T epsilon) noexcept {
|
||||
if constexpr ( std::is_floating_point_v<T> ) {
|
||||
// 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 {
|
||||
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(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(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(2.5f, 2.f, 3.f) == uapprox(2.5f));
|
||||
|
||||
Reference in New Issue
Block a user