Files
enduro2d/untests/sources/untests_math/_math.cpp
2020-02-06 17:04:35 +07:00

684 lines
27 KiB
C++

/*******************************************************************************
* This file is part of the "Enduro2D"
* For conditions of distribution and use, see copyright notice in LICENSE.md
* Copyright (C) 2018-2020, by Matvey Cherevko (blackmatov@gmail.com)
******************************************************************************/
#define CATCH_CONFIG_MAIN
#include "_math.hpp"
using namespace e2d;
TEST_CASE("math") {
{
REQUIRE(math::numeric_cast<u32>(1) == 1u);
REQUIRE(math::numeric_cast<i32>(1.2f) == 1);
REQUIRE(math::numeric_cast<i32>(-1.2f) == -1);
REQUIRE(math::numeric_cast<i32>(1.8f) == 1);
REQUIRE(math::numeric_cast<i32>(-1.8f) == -1);
}
{
using math::impl::check_numeric_cast;
// f -> f
REQUIRE(check_numeric_cast<f64>(std::numeric_limits<f64>::max()));
REQUIRE(check_numeric_cast<f64>(std::numeric_limits<f64>::lowest()));
REQUIRE(check_numeric_cast<f64>(std::numeric_limits<f32>::max()));
REQUIRE(check_numeric_cast<f64>(std::numeric_limits<f32>::lowest()));
REQUIRE_FALSE(check_numeric_cast<f32>(std::numeric_limits<f64>::max()));
REQUIRE_FALSE(check_numeric_cast<f32>(std::numeric_limits<f64>::lowest()));
REQUIRE_FALSE(check_numeric_cast<f64>(std::numeric_limits<f64>::infinity()));
REQUIRE_FALSE(check_numeric_cast<f64>(std::numeric_limits<f64>::quiet_NaN()));
REQUIRE_FALSE(check_numeric_cast<f64>(std::numeric_limits<f64>::signaling_NaN()));
// i -> f
REQUIRE(check_numeric_cast<f32>(std::numeric_limits<int>::min()));
REQUIRE(check_numeric_cast<f32>(std::numeric_limits<int>::max()));
REQUIRE(check_numeric_cast<f64>(std::numeric_limits<int>::min()));
REQUIRE(check_numeric_cast<f64>(std::numeric_limits<int>::max()));
// f -> i
REQUIRE(check_numeric_cast<i32>(1.f));
REQUIRE(check_numeric_cast<i32>(-1.f));
REQUIRE_FALSE(check_numeric_cast<i32>(std::numeric_limits<f32>::max()));
REQUIRE_FALSE(check_numeric_cast<i32>(std::numeric_limits<f32>::lowest()));
REQUIRE_FALSE(check_numeric_cast<i32>(std::numeric_limits<f32>::infinity()));
REQUIRE_FALSE(check_numeric_cast<i32>(std::numeric_limits<f32>::quiet_NaN()));
REQUIRE_FALSE(check_numeric_cast<i32>(std::numeric_limits<f32>::signaling_NaN()));
// f -> u
REQUIRE(check_numeric_cast<u32>(1.f));
REQUIRE_FALSE(check_numeric_cast<u32>(-1.f));
REQUIRE_FALSE(check_numeric_cast<u32>(std::numeric_limits<f32>::max()));
REQUIRE_FALSE(check_numeric_cast<u32>(std::numeric_limits<f32>::lowest()));
REQUIRE_FALSE(check_numeric_cast<u32>(std::numeric_limits<f32>::infinity()));
REQUIRE_FALSE(check_numeric_cast<u32>(std::numeric_limits<f32>::quiet_NaN()));
REQUIRE_FALSE(check_numeric_cast<u32>(std::numeric_limits<f32>::signaling_NaN()));
// i -> i
REQUIRE(check_numeric_cast<i8>(-128));
REQUIRE(check_numeric_cast<i8>(127));
REQUIRE(check_numeric_cast<i16>(i8(-128)));
REQUIRE(check_numeric_cast<i16>(i8(127)));
REQUIRE_FALSE(check_numeric_cast<i8>(-129));
REQUIRE_FALSE(check_numeric_cast<i8>(128));
REQUIRE_FALSE(check_numeric_cast<i16>(std::numeric_limits<i32>::max()));
REQUIRE_FALSE(check_numeric_cast<i16>(std::numeric_limits<i32>::lowest()));
REQUIRE(check_numeric_cast<i32>(std::numeric_limits<i32>::max()));
REQUIRE(check_numeric_cast<i32>(std::numeric_limits<i32>::lowest()));
// u -> u
REQUIRE(check_numeric_cast<u8>(255u));
REQUIRE_FALSE(check_numeric_cast<u8>(256u));
REQUIRE_FALSE(check_numeric_cast<u16>(std::numeric_limits<u32>::max()));
REQUIRE(check_numeric_cast<u16>(std::numeric_limits<u32>::lowest()));
REQUIRE(check_numeric_cast<u32>(std::numeric_limits<u32>::max()));
REQUIRE(check_numeric_cast<u32>(std::numeric_limits<u32>::lowest()));
// i -> u
REQUIRE(check_numeric_cast<u8>(255));
REQUIRE_FALSE(check_numeric_cast<u8>(-1));
REQUIRE_FALSE(check_numeric_cast<u8>(256));
// u -> i
REQUIRE(check_numeric_cast<i8>(127u));
REQUIRE_FALSE(check_numeric_cast<i8>(128u));
{
REQUIRE(check_numeric_cast<i8>(127.7f));
REQUIRE(math::numeric_cast<i8>(127.7f) == 127);
REQUIRE(check_numeric_cast<i8>(-127.7f));
REQUIRE(math::numeric_cast<i8>(-127.7f) == -127);
REQUIRE(check_numeric_cast<u8>(255.9f));
REQUIRE(math::numeric_cast<u8>(255.9f) == 255);
}
}
{
enum flag_masks : u32 {
fm_flag0 = 1 << 0,
fm_flag1 = 1 << 1
};
//
// set flags
//
REQUIRE(math::set_flags(0b0000u, 0b0001) == 0b0001u);
REQUIRE(math::set_flags(0b0001u, 0b0001) == 0b0001u);
REQUIRE(math::set_flags(0b0000u, fm_flag0) == 0b0001u);
REQUIRE(math::set_flags(0b0000u, fm_flag1) == 0b0010u);
REQUIRE(math::set_flags(0b0000u, fm_flag0 | fm_flag1) == 0b0011u);
{
u32 f = 0b0000u;
math::set_flags_inplace(f, fm_flag0 | fm_flag1);
REQUIRE(f == 0b0011u);
}
//
// flip flags
//
REQUIRE(math::flip_flags(0b0000u, fm_flag0) == 0b0001u);
REQUIRE(math::flip_flags(0b0001u, fm_flag0) == 0b0000u);
REQUIRE(math::flip_flags(0b0000u, fm_flag1) == 0b0010u);
REQUIRE(math::flip_flags(0b0010u, fm_flag1) == 0b0000u);
REQUIRE(math::flip_flags(0b0000u, fm_flag0 | fm_flag1) == 0b0011u);
REQUIRE(math::flip_flags(0b0011u, fm_flag0 | fm_flag1) == 0b0000u);
REQUIRE(math::flip_flags(0b0001u, fm_flag0 | fm_flag1) == 0b0010u);
REQUIRE(math::flip_flags(0b0010u, fm_flag0 | fm_flag1) == 0b0001u);
{
u32 f = 0b0010u;
math::flip_flags_inplace(f, fm_flag0 | fm_flag1);
REQUIRE(f == 0b0001u);
}
//
// clear flags
//
REQUIRE(math::clear_flags(0b1111u, fm_flag0) == 0b1110u);
REQUIRE(math::clear_flags(0b1111u, fm_flag1) == 0b1101u);
REQUIRE(math::clear_flags(0b1111u, fm_flag0 | fm_flag1) == 0b1100u);
REQUIRE(math::clear_flags(0b0110u, fm_flag0) == 0b0110u);
REQUIRE(math::clear_flags(0b0101u, fm_flag1) == 0b0101u);
REQUIRE(math::clear_flags(0b0100u, fm_flag0 | fm_flag1) == 0b0100u);
{
u32 f = 0b1111u;
math::flip_flags_inplace(f, fm_flag0 | fm_flag1);
REQUIRE(f == 0b1100u);
}
//
// check any flags
//
REQUIRE_FALSE(math::check_any_flags(0b0000u, 0));
REQUIRE_FALSE(math::check_any_flags(0b1111u, 0));
REQUIRE(math::check_any_flags(0b1111u, fm_flag0));
REQUIRE(math::check_any_flags(0b1111u, fm_flag1));
REQUIRE(math::check_any_flags(0b1111u, fm_flag0 | fm_flag1));
REQUIRE(math::check_any_flags(0b1110u, fm_flag0 | fm_flag1));
REQUIRE(math::check_any_flags(0b1101u, fm_flag0 | fm_flag1));
REQUIRE_FALSE(math::check_any_flags(0b1100u, fm_flag0 | fm_flag1));
//
// check all flags
//
REQUIRE(math::check_all_flags(0b0000u, 0));
REQUIRE(math::check_all_flags(0b1111u, 0));
REQUIRE(math::check_all_flags(0b1111u, fm_flag0));
REQUIRE(math::check_all_flags(0b1101u, fm_flag0));
REQUIRE(math::check_all_flags(0b0001u, fm_flag0));
REQUIRE_FALSE(math::check_all_flags(0b1110u, fm_flag0));
REQUIRE_FALSE(math::check_all_flags(0b1100u, fm_flag0));
REQUIRE_FALSE(math::check_all_flags(0b0000u, fm_flag0));
REQUIRE(math::check_all_flags(0b1111u, fm_flag1));
REQUIRE(math::check_all_flags(0b1110u, fm_flag1));
REQUIRE(math::check_all_flags(0b0010u, fm_flag1));
REQUIRE_FALSE(math::check_all_flags(0b1101u, fm_flag1));
REQUIRE_FALSE(math::check_all_flags(0b1100u, fm_flag1));
REQUIRE_FALSE(math::check_all_flags(0b0000u, fm_flag1));
REQUIRE(math::check_all_flags(0b1111u, fm_flag0 | fm_flag1));
REQUIRE(math::check_all_flags(0b0111u, fm_flag0 | fm_flag1));
REQUIRE(math::check_all_flags(0b0011u, fm_flag0 | fm_flag1));
REQUIRE_FALSE(math::check_all_flags(0b1110u, fm_flag0 | fm_flag1));
REQUIRE_FALSE(math::check_all_flags(0b1101u, fm_flag0 | fm_flag1));
REQUIRE_FALSE(math::check_all_flags(0b1100u, fm_flag0 | fm_flag1));
REQUIRE_FALSE(math::check_all_flags(0b0000u, fm_flag0 | fm_flag1));
//
// check_and_set_any_flags
//
{
u32 f = 0b0000u;
REQUIRE(math::check_and_set_any_flags(f, fm_flag0 | fm_flag1));
REQUIRE(f == 0b0011u);
f = 0b0001u;
REQUIRE(math::check_and_set_any_flags(f, fm_flag0 | fm_flag1));
REQUIRE(f == 0b0011u);
f = 0b0010u;
REQUIRE(math::check_and_set_any_flags(f, fm_flag0 | fm_flag1));
REQUIRE(f == 0b0011u);
f = 0b0011u;
REQUIRE_FALSE(math::check_and_set_any_flags(f, fm_flag0 | fm_flag1));
REQUIRE(f == 0b0011u);
}
//
// check_and_set_all_flags
//
{
u32 f = 0b0000u;
REQUIRE(math::check_and_set_all_flags(f, fm_flag0 | fm_flag1));
REQUIRE(f == 0b0011u);
f = 0b0001u;
REQUIRE_FALSE(math::check_and_set_all_flags(f, fm_flag0 | fm_flag1));
REQUIRE(f == 0b0001u);
f = 0b0010u;
REQUIRE_FALSE(math::check_and_set_all_flags(f, fm_flag0 | fm_flag1));
REQUIRE(f == 0b0010u);
f = 0b0011u;
REQUIRE_FALSE(math::check_and_set_all_flags(f, fm_flag0 | fm_flag1));
REQUIRE(f == 0b0011u);
}
//
// check_and_clear_any_flags
//
{
u32 f = 0b1100u;
REQUIRE_FALSE(math::check_and_clear_any_flags(f, fm_flag0 | fm_flag1));
REQUIRE(f == 0b1100u);
f = 0b1101u;
REQUIRE(math::check_and_clear_any_flags(f, fm_flag0 | fm_flag1));
REQUIRE(f == 0b1100u);
f = 0b1110u;
REQUIRE(math::check_and_clear_any_flags(f, fm_flag0 | fm_flag1));
REQUIRE(f == 0b1100u);
f = 0b1111u;
REQUIRE(math::check_and_clear_any_flags(f, fm_flag0 | fm_flag1));
REQUIRE(f == 0b1100u);
}
//
// check_and_clear_all_flags
//
{
u32 f = 0b1100u;
REQUIRE_FALSE(math::check_and_clear_all_flags(f, fm_flag0 | fm_flag1));
REQUIRE(f == 0b1100u);
f = 0b1101u;
REQUIRE_FALSE(math::check_and_clear_all_flags(f, fm_flag0 | fm_flag1));
REQUIRE(f == 0b1101u);
f = 0b1110u;
REQUIRE_FALSE(math::check_and_clear_all_flags(f, fm_flag0 | fm_flag1));
REQUIRE(f == 0b1110u);
f = 0b1111u;
REQUIRE(math::check_and_clear_all_flags(f, fm_flag0 | fm_flag1));
REQUIRE(f == 0b1100u);
}
}
{
REQUIRE(math::is_power_of_2(1u));
REQUIRE(math::is_power_of_2(2u));
REQUIRE(math::is_power_of_2(4u));
REQUIRE(math::is_power_of_2(8u));
REQUIRE_FALSE(math::is_power_of_2(0u));
REQUIRE_FALSE(math::is_power_of_2(3u));
REQUIRE_FALSE(math::is_power_of_2(6u));
REQUIRE_FALSE(math::is_power_of_2(10u));
REQUIRE(math::max_power_of_2<u8>() == (1u << 7));
REQUIRE(math::max_power_of_2<u16>() == (1u << 15));
REQUIRE(math::max_power_of_2<u32>() == (1u << 31));
REQUIRE(math::next_power_of_2(u8(0)) == u8(1));
REQUIRE(math::next_power_of_2(u8(1)) == u8(1));
REQUIRE(math::next_power_of_2(u8(2)) == u8(2));
REQUIRE(math::next_power_of_2(u16(3)) == u16(4));
REQUIRE(math::next_power_of_2(u16(4)) == u16(4));
REQUIRE(math::next_power_of_2(u32(5)) == u32(8));
REQUIRE(math::next_power_of_2(u32(6)) == u32(8));
REQUIRE(math::next_power_of_2(u32(8)) == u32(8));
REQUIRE(math::next_power_of_2(u32(9)) == u32(16));
}
{
REQUIRE(math::abs(2) == 2);
REQUIRE(math::abs(3u) == 3u);
REQUIRE(math::abs(-4) == 4);
REQUIRE(math::approximately(math::abs(1.2f), 1.2f));
REQUIRE(math::approximately(math::abs(-1.2f), 1.2f));
REQUIRE(math::approximately(math::abs(2.3), 2.3));
REQUIRE(math::approximately(math::abs(-2.3), 2.3));
REQUIRE(math::abs(0.f) == 0.f);
REQUIRE(math::abs(-0.f) == 0.f);
REQUIRE(math::abs(0.0) == 0.0);
REQUIRE(math::abs(-0.0) == 0.0);
}
{
REQUIRE(math::mod(6, 3) == 0);
REQUIRE(math::mod(6, 4) == 2);
REQUIRE(math::mod(6, 6) == 0);
REQUIRE(math::mod(6, 7) == 6);
REQUIRE(math::mod(6, -3) == 0);
REQUIRE(math::mod(6, -4) == 2);
REQUIRE(math::mod(6, -6) == 0);
REQUIRE(math::mod(6, -7) == 6);
REQUIRE(math::mod(-6, 3) == -0);
REQUIRE(math::mod(-6, 4) == -2);
REQUIRE(math::mod(-6, 6) == -0);
REQUIRE(math::mod(-6, 7) == -6);
REQUIRE(math::mod(-6, -3) == -0);
REQUIRE(math::mod(-6, -4) == -2);
REQUIRE(math::mod(-6, -6) == -0);
REQUIRE(math::mod(-6, -7) == -6);
REQUIRE(math::approximately(math::mod(6.f, 3.f), 0.f));
REQUIRE(math::approximately(math::mod(6.f, 4.f), 2.f));
REQUIRE(math::approximately(math::mod(6.f, 6.f), 0.f));
REQUIRE(math::approximately(math::mod(6.f, 7.f), 6.f));
REQUIRE(math::approximately(math::mod(6.f, -3.f), 0.f));
REQUIRE(math::approximately(math::mod(6.f, -4.f), 2.f));
REQUIRE(math::approximately(math::mod(6.f, -6.f), 0.f));
REQUIRE(math::approximately(math::mod(6.f, -7.f), 6.f));
REQUIRE(math::approximately(math::mod(-6.f, 3.f), -0.f));
REQUIRE(math::approximately(math::mod(-6.f, 4.f), -2.f));
REQUIRE(math::approximately(math::mod(-6.f, 6.f), -0.f));
REQUIRE(math::approximately(math::mod(-6.f, 7.f), -6.f));
REQUIRE(math::approximately(math::mod(-6.f, -3.f), -0.f));
REQUIRE(math::approximately(math::mod(-6.f, -4.f), -2.f));
REQUIRE(math::approximately(math::mod(-6.f, -6.f), -0.f));
REQUIRE(math::approximately(math::mod(-6.f, -7.f), -6.f));
REQUIRE(math::approximately(math::mod(6.0, 3.0), 0.0));
REQUIRE(math::approximately(math::mod(6.0, 4.0), 2.0));
REQUIRE(math::approximately(math::mod(6.0, 6.0), 0.0));
REQUIRE(math::approximately(math::mod(6.0, 7.0), 6.0));
REQUIRE(math::approximately(math::mod(6.0, -3.0), 0.0));
REQUIRE(math::approximately(math::mod(6.0, -4.0), 2.0));
REQUIRE(math::approximately(math::mod(6.0, -6.0), 0.0));
REQUIRE(math::approximately(math::mod(6.0, -7.0), 6.0));
REQUIRE(math::approximately(math::mod(-6.0, 3.0), -0.0));
REQUIRE(math::approximately(math::mod(-6.0, 4.0), -2.0));
REQUIRE(math::approximately(math::mod(-6.0, 6.0), -0.0));
REQUIRE(math::approximately(math::mod(-6.0, 7.0), -6.0));
REQUIRE(math::approximately(math::mod(-6.0, -3.0), -0.0));
REQUIRE(math::approximately(math::mod(-6.0, -4.0), -2.0));
REQUIRE(math::approximately(math::mod(-6.0, -6.0), -0.0));
REQUIRE(math::approximately(math::mod(-6.0, -7.0), -6.0));
}
{
REQUIRE_FALSE(math::sign(0));
REQUIRE_FALSE(math::sign(1));
REQUIRE(math::sign(-1));
REQUIRE_FALSE(math::sign(0u));
REQUIRE_FALSE(math::sign(1u));
REQUIRE_FALSE(math::sign(0.f));
REQUIRE_FALSE(math::sign(0.1f));
REQUIRE(math::sign(-0.f));
REQUIRE(math::sign(-0.1f));
REQUIRE_FALSE(math::sign(0.0));
REQUIRE_FALSE(math::sign(0.1));
REQUIRE(math::sign(-0.0));
REQUIRE(math::sign(-0.1));
}
{
REQUIRE(math::approximately(math::ceil(1), 1));
REQUIRE(math::approximately(math::floor(1), 1));
REQUIRE(math::approximately(math::round(1), 1));
REQUIRE(math::approximately(math::trunc(1), 1));
REQUIRE(math::approximately(math::ceil(-1), -1));
REQUIRE(math::approximately(math::floor(-1), -1));
REQUIRE(math::approximately(math::round(-1), -1));
REQUIRE(math::approximately(math::trunc(-1), -1));
REQUIRE(math::approximately(math::ceil(0.4f), 1.f));
REQUIRE(math::approximately(math::floor(0.4f), 0.f));
REQUIRE(math::approximately(math::trunc(0.4f), 0.f));
REQUIRE(math::approximately(math::ceil(-0.4f), 0.f));
REQUIRE(math::approximately(math::floor(-0.4f), -1.f));
REQUIRE(math::approximately(math::trunc(-0.4f), 0.f));
REQUIRE(math::approximately(math::ceil(0.6f), 1.f));
REQUIRE(math::approximately(math::floor(0.6f), 0.f));
REQUIRE(math::approximately(math::trunc(0.6f), 0.f));
REQUIRE(math::approximately(math::ceil(-0.6f), 0.f));
REQUIRE(math::approximately(math::floor(-0.6f), -1.f));
REQUIRE(math::approximately(math::trunc(-0.6f), 0.f));
REQUIRE(math::approximately(math::round(0.4f), 0.f));
REQUIRE(math::approximately(math::round(0.6f), 1.f));
REQUIRE(math::approximately(math::round(-0.4f), 0.f));
REQUIRE(math::approximately(math::round(-0.6f), -1.f));
}
{
REQUIRE(math::min(1) == 1);
REQUIRE(math::min(1,1) == 1);
REQUIRE(math::min(1,2) == 1);
REQUIRE(math::min(2,1) == 1);
REQUIRE(math::min(1,1,1) == 1);
REQUIRE(math::min(2,1,1) == 1);
REQUIRE(math::min(1,2,1) == 1);
REQUIRE(math::min(1,1,2) == 1);
REQUIRE(math::min(2,3,4) == 2);
REQUIRE(math::min(2,4,3) == 2);
REQUIRE(math::min(2,3,4,5) == 2);
REQUIRE(math::min(2,4,3,5) == 2);
REQUIRE(math::min(5,3,4,2) == 2);
REQUIRE(math::min(5,4,3,2) == 2);
}
{
REQUIRE(math::max(1) == 1);
REQUIRE(math::max(1,1) == 1);
REQUIRE(math::max(1,2) == 2);
REQUIRE(math::max(2,1) == 2);
REQUIRE(math::max(1,1,1) == 1);
REQUIRE(math::max(2,1,1) == 2);
REQUIRE(math::max(1,2,1) == 2);
REQUIRE(math::max(1,1,2) == 2);
REQUIRE(math::max(2,3,4) == 4);
REQUIRE(math::max(2,3,4,5) == 5);
REQUIRE(math::max(2,4,3,5) == 5);
REQUIRE(math::max(5,3,4,2) == 5);
REQUIRE(math::max(5,4,3,2) == 5);
}
{
REQUIRE(math::minmax(1) == std::make_pair(1,1));
REQUIRE(math::minmax(1,2) == std::make_pair(1,2));
REQUIRE(math::minmax(2,1) == std::make_pair(1,2));
REQUIRE(math::minmax(1,2,3) == std::make_pair(1,3));
REQUIRE(math::minmax(3,2,1) == std::make_pair(1,3));
REQUIRE(math::minmax(1,2,3,4) == std::make_pair(1,4));
REQUIRE(math::minmax(1,3,2,4) == std::make_pair(1,4));
REQUIRE(math::minmax(4,2,3,1) == std::make_pair(1,4));
REQUIRE(math::minmax(4,3,2,1) == std::make_pair(1,4));
}
{
REQUIRE(math::clamp(2,1,3) == 2);
REQUIRE(math::clamp(3,1,3) == 3);
REQUIRE(math::clamp(4,1,3) == 3);
REQUIRE(math::clamp(1,1,3) == 1);
REQUIRE(math::clamp(0,1,3) == 1);
REQUIRE(math::clamp(2,3,1) == 2);
REQUIRE(math::clamp(3,3,1) == 3);
REQUIRE(math::saturate(2) == 1);
REQUIRE(math::saturate(-1) == 0);
REQUIRE(math::saturate(0) == 0);
REQUIRE(math::saturate(1) == 1);
}
{
REQUIRE(math::approximately(math::abs_to_unsigned(1), 1u));
REQUIRE(math::approximately(math::abs_to_unsigned(-1), 1u));
REQUIRE(math::approximately(math::abs_to_unsigned(i8(-128)), u8(128)));
REQUIRE(math::approximately(math::abs_to_unsigned(10u), 10u));
const auto imin = std::numeric_limits<i32>::min();
const auto umax = std::numeric_limits<u32>::max();
REQUIRE(math::approximately(math::abs_to_unsigned(imin), umax/2+1));
}
{
REQUIRE(math::is_near_zero(0));
REQUIRE_FALSE(math::is_near_zero(1));
REQUIRE_FALSE(math::is_near_zero(1u));
REQUIRE(math::is_near_zero(1, 1));
REQUIRE(math::is_near_zero(-1, 1));
REQUIRE(math::is_near_zero(1u, 1u));
REQUIRE(math::is_near_zero(0.000001f));
REQUIRE(math::is_near_zero(-0.000001f));
REQUIRE_FALSE(math::is_near_zero(0.0001f));
REQUIRE_FALSE(math::is_near_zero(-0.0001f));
REQUIRE(math::is_near_zero(0.0001f, 0.001f));
REQUIRE(math::is_near_zero(-0.0001f, 0.001f));
}
{
REQUIRE(math::approximately(math::lerp(1.f, 11.f, 0.f), 1.f));
REQUIRE(math::approximately(math::lerp(1.f, 11.f, 0.5f), 6.f));
REQUIRE(math::approximately(math::lerp(1.f, 11.f, 1.f), 11.f));
REQUIRE(math::approximately(math::lerp(1.f, 11.f, 2.f), 21.f));
REQUIRE(math::approximately(math::inverse_lerp(1.f, 11.f, 1.f), 0.f));
REQUIRE(math::approximately(math::inverse_lerp(1.f, 11.f, 6.f), 0.5f));
REQUIRE(math::approximately(math::inverse_lerp(1.f, 11.f, 11.f), 1.f));
REQUIRE(math::approximately(math::inverse_lerp(1.f, 11.f, 21.f), 2.f));
}
{
static_assert(
std::is_same<u8, math::make_distance_t<i8>>::value,
"static unit test error");
static_assert(
std::is_same<u8, math::make_distance_t<u8>>::value,
"static unit test error");
static_assert(
std::is_same<f32, math::make_distance_t<f32>>::value,
"static unit test error");
static_assert(
std::is_same<f64, math::make_distance_t<f64>>::value,
"static unit test error");
static_assert(
std::is_same<const u8, math::make_distance_t<const i8>>::value,
"static unit test error");
static_assert(
std::is_same<volatile u8, math::make_distance_t<volatile i8>>::value,
"static unit test error");
static_assert(
std::is_same<const volatile u8, math::make_distance_t<const volatile i8>>::value,
"static unit test error");
}
{
REQUIRE(math::distance(1, 10) == 9);
REQUIRE(math::distance(-1, -10) == 9);
REQUIRE(math::distance(-1, 10) == 11);
REQUIRE(math::distance(1, -10) == 11);
REQUIRE(math::distance(10, 3) == 7);
REQUIRE(math::distance(-10, -3) == 7);
REQUIRE(math::distance(10, -3) == 13);
REQUIRE(math::distance(-10, 3) == 13);
REQUIRE(math::distance(
std::numeric_limits<i16>::min(),
i16(0)) == std::numeric_limits<u16>::max()/2 + 1);
REQUIRE(math::distance(
std::numeric_limits<i16>::min(),
i16(-1)) == std::numeric_limits<u16>::max()/2);
REQUIRE(math::distance(
std::numeric_limits<i16>::min(),
std::numeric_limits<i16>::max()) == std::numeric_limits<u16>::max());
REQUIRE(math::distance(
std::numeric_limits<i16>::max(),
std::numeric_limits<i16>::min()) == std::numeric_limits<u16>::max());
REQUIRE(math::distance(
std::numeric_limits<i32>::min(),
i32(0)) == std::numeric_limits<u32>::max()/2 + 1);
REQUIRE(math::distance(
std::numeric_limits<i32>::min(),
i32(-1)) == std::numeric_limits<u32>::max()/2);
REQUIRE(math::distance(
std::numeric_limits<i32>::min(),
std::numeric_limits<i32>::max()) == std::numeric_limits<u32>::max());
REQUIRE(math::distance(
std::numeric_limits<i32>::max(),
std::numeric_limits<i32>::min()) == std::numeric_limits<u32>::max());
REQUIRE(math::distance(
std::numeric_limits<i64>::min(),
i64(0)) == std::numeric_limits<u64>::max()/2 + 1);
REQUIRE(math::distance(
std::numeric_limits<i64>::min(),
i64(-1)) == std::numeric_limits<u64>::max()/2);
REQUIRE(math::distance(
std::numeric_limits<i64>::min(),
std::numeric_limits<i64>::max()) == std::numeric_limits<u64>::max());
REQUIRE(math::distance(
std::numeric_limits<i64>::max(),
std::numeric_limits<i64>::min()) == std::numeric_limits<u64>::max());
REQUIRE(math::distance(
u16(0),
std::numeric_limits<u16>::max()) == std::numeric_limits<u16>::max());
REQUIRE(math::distance(
u32(0),
std::numeric_limits<u32>::max()) == std::numeric_limits<u32>::max());
REQUIRE(math::distance(
u64(0),
std::numeric_limits<u64>::max()) == std::numeric_limits<u64>::max());
REQUIRE(math::approximately(
math::distance(std::numeric_limits<f32>::lowest()/2.f, std::numeric_limits<f32>::max()/2.f),
std::numeric_limits<f32>::max()));
REQUIRE(math::approximately(
math::distance(std::numeric_limits<f32>::max()/2.f, std::numeric_limits<f32>::lowest()/2.f),
std::numeric_limits<f32>::max()));
REQUIRE(math::approximately(
math::distance(std::numeric_limits<f64>::lowest()/2.0, std::numeric_limits<f64>::max()/2.0),
std::numeric_limits<f64>::max()));
REQUIRE(math::approximately(
math::distance(std::numeric_limits<f64>::max()/2.0, std::numeric_limits<f64>::lowest()/2.0),
std::numeric_limits<f64>::max()));
}
{
REQUIRE(math::approximately(1, 1));
REQUIRE(math::approximately(1, 2, 1));
REQUIRE(math::approximately(1, 3, 2));
REQUIRE(math::approximately(1, 3, 3));
REQUIRE(math::approximately(2, 1, 1));
REQUIRE(math::approximately(3, 1, 2));
REQUIRE(math::approximately(3, 1, 3));
REQUIRE_FALSE(math::approximately(1, 2));
REQUIRE_FALSE(math::approximately(1, 2, 0));
REQUIRE_FALSE(math::approximately(1, 3, 1));
REQUIRE_FALSE(math::approximately(2, 1));
REQUIRE_FALSE(math::approximately(2, 1, 0));
REQUIRE_FALSE(math::approximately(3, 1, 1));
REQUIRE(math::approximately(2u, 3u, 1u));
REQUIRE(math::approximately(3u, 2u, 1u));
i32 imin = std::numeric_limits<i32>::min();
i32 imax = std::numeric_limits<i32>::max();
REQUIRE_FALSE(math::approximately<i32>(imin,-1,1));
REQUIRE_FALSE(math::approximately<i32>(imax,-1,1));
REQUIRE_FALSE(math::approximately<i32>(imin,1,1));
REQUIRE_FALSE(math::approximately<i32>(imax,1,1));
REQUIRE_FALSE(math::approximately<i32>(imin,0,1));
REQUIRE_FALSE(math::approximately<i32>(imax,0,1));
REQUIRE_FALSE(math::approximately<i32>(imin,imax,1));
REQUIRE_FALSE(math::approximately<i32>(imax,imin,1));
u32 umin = std::numeric_limits<u32>::min();
u32 umax = std::numeric_limits<u32>::max();
REQUIRE_FALSE(math::approximately<u32>(umax,1,1));
REQUIRE_FALSE(math::approximately<u32>(umax,0,1));
REQUIRE_FALSE(math::approximately<u32>(umin,umax,1));
REQUIRE_FALSE(math::approximately<u32>(umax,umin,1));
}
}