Skip to content

Commit

Permalink
Improve u128
Browse files Browse the repository at this point in the history
  • Loading branch information
HUD-Software committed Jun 19, 2024
1 parent 0258189 commit 334146c
Show file tree
Hide file tree
Showing 29 changed files with 1,106 additions and 393 deletions.
306 changes: 69 additions & 237 deletions interface/core/i128.h

Large diffs are not rendered by default.

232 changes: 188 additions & 44 deletions interface/core/i128/i128_intrinsics.h

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion interface/core/i128/i128_portable.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ namespace hud

static inline void u128_from_f64(f64 value, u64 &high, u64 &low) noexcept
{

// TODO, put this in cpp and use hud functions

// Check not NaN
Expand Down
40 changes: 40 additions & 0 deletions interface/core/limits.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#ifndef HD_INC_CORE_LIMITS_H
#define HD_INC_CORE_LIMITS_H

namespace hud
{

/**
* Defines limits of types
* @tparam type_t The type to define
*/
template<typename type_t>
struct limits;
#define hud_limits_for(type_t) \
template<> struct limits<type_t> \
{ \
static constexpr type_t min {hud::type_t##_min}; \
static constexpr type_t max {hud::type_t##_max}; \
static constexpr type_t min_positive {hud::type_t##_min_positive}; \
};
hud_limits_for(bool);
hud_limits_for(i8);
hud_limits_for(u8);
hud_limits_for(i16);
hud_limits_for(u16);
hud_limits_for(i32);
hud_limits_for(u32);
hud_limits_for(i64);
hud_limits_for(u64);
hud_limits_for(f32);
hud_limits_for(f64);
hud_limits_for(ansichar);
hud_limits_for(wchar);
hud_limits_for(char16);
hud_limits_for(char32);

#undef hud_limits_for

} // namespace hud

#endif // HD_INC_CORE_LIMITS_H
66 changes: 15 additions & 51 deletions interface/core/math.h
Original file line number Diff line number Diff line change
@@ -1,61 +1,25 @@
#ifndef HD_INC_CORE_MATH_H
#define HD_INC_CORE_MATH_H
#include "traits/make_unsigned.h"
#include "traits/is_integral.h"

#if defined(HD_OS_WINDOWS)
#include "os_windows/math.h"
#elif defined(HD_OS_LINUX)
#include "os_linux/math.h"
#else
#error Targeted OS not supported
#endif

namespace hud
{
namespace math
struct math :
#if defined(HD_OS_WINDOWS)
os::windows::math
#elif defined(HD_OS_LINUX)
os::linux::math
#endif
{
/**
* Defines limits of types
* @tparam type_t The type to define
*/
template<typename type_t>
struct limits;
#define hud_limits_for(type_t) \
template<> struct limits<type_t> \
{ \
static constexpr type_t min {hud::type_t##_min}; \
static constexpr type_t max {hud::type_t##_max}; \
};
hud_limits_for(bool);
hud_limits_for(i8);
hud_limits_for(u8);
hud_limits_for(i16);
hud_limits_for(u16);
hud_limits_for(i32);
hud_limits_for(u32);
hud_limits_for(i64);
hud_limits_for(u64);
#undef hud_limits_for

/**
* Check wheter the given number is a power of two or not
* Requires type_t to be an integral type
* @param value The value to test
* @return true if value is a power of two, false otherwise
*/
template<typename type_t>
requires(is_integral_v<type_t>)
[[nodiscard]] static constexpr bool is_power_of_two(const type_t value) noexcept

{
return value && !(value & (value - 1));
}

/**
* Check that a value is in range [min, max]
* @param value The value to check
* @param min The minimum value of the range
* @param max The maximum value of the range
* @return true if value >= min and value <= max, false otherwise
*/
template<typename type_t>
[[nodiscard]] static constexpr bool is_in_range_inclusive(const type_t value, const type_t min, const type_t max) noexcept
{
return value >= min && value <= max;
}

}; // namespace math

} // namespace hud
Expand Down
6 changes: 3 additions & 3 deletions interface/core/memory.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef HD_INC_OSABSTRACTIONLAYER_MEMORY_H
#define HD_INC_OSABSTRACTIONLAYER_MEMORY_H
#ifndef HD_INC_CORE_MEMORY_H
#define HD_INC_CORE_MEMORY_H
#include "traits/is_bitwise_comparable.h"
#include "traits/is_bitwise_copy_assignable.h"
#include "traits/is_bitwise_copy_constructible.h"
Expand Down Expand Up @@ -521,4 +521,4 @@ namespace hud

} // namespace hud

#endif // HD_INC_OSABSTRACTIONLAYER_MEMORY_H
#endif // HD_INC_CORE_MEMORY_H
6 changes: 3 additions & 3 deletions interface/core/os_common/cstring.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef HD_INC_OSABSTRACTIONLAYER_OS_COMMON_CSTRING_H
#define HD_INC_OSABSTRACTIONLAYER_OS_COMMON_CSTRING_H
#ifndef HD_INC_CORE_OS_COMMON_CSTRING_H
#define HD_INC_CORE_OS_COMMON_CSTRING_H
#include "../character.h"
#include "../assert.h"
#include "../traits/is_one_of_types.h"
Expand Down Expand Up @@ -588,4 +588,4 @@ namespace hud::os::common

} // namespace hud::os::common

#endif // HD_INC_OSABSTRACTIONLAYER_OS_COMMON_CSTRING_H
#endif // HD_INC_CORE_OS_COMMON_CSTRING_H
176 changes: 176 additions & 0 deletions interface/core/os_common/math.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
#ifndef HD_INC_CORE_OS_COMMON_MATH_H
#define HD_INC_CORE_OS_COMMON_MATH_H
#include "../traits/is_integral.h"
#include <cmath>

namespace hud::os::common
{
struct math
{

/**
* Check wheter the given number is a power of two or not
* Requires type_t to be an integral type
* @param value The value to test
* @return true if value is a power of two, false otherwise
*/
template<typename type_t>
requires(hud::is_integral_v<type_t>)
[[nodiscard]] static constexpr bool is_power_of_two(const type_t value) noexcept
{
return value && !(value & (value - 1));
}

/**
* Check that a value is in range [min, max]
* @param value The value to check
* @param min The minimum value of the range
* @param max The maximum value of the range
* @return true if value >= min and value <= max, false otherwise
*/
template<typename type_t>
[[nodiscard]] static constexpr bool is_in_range_inclusive(const type_t value, const type_t min, const type_t max) noexcept
{
return value >= min && value <= max;
}

/**
* Categorizes floating point value num into the following categories: zero, subnormal, normal, infinite, NAN.
* @param value The value to categorize.
* @return FP_INFINITE, FP_NAN, FP_NORMAL, FP_SUBNORMAL, FP_ZERO */
[[nodiscard]] static constexpr int fpclassify(double value) noexcept
{
// FROM musl __fpclassify.c
union
{
f64 f;
u64 i;
} u = {value};

int e = u.i >> 52 & 0x7ff;
if (!e)
return u.i << 1 ? FP_SUBNORMAL : FP_ZERO;
if (e == 0x7ff)
return u.i << 12 ? FP_NAN : FP_INFINITE;
return FP_NORMAL;
}

/**
* Categorizes floating point value num into the following categories: zero, subnormal, normal, infinite, NAN.
* @param value The value to categorize.
* @return FP_INFINITE, FP_NAN, FP_NORMAL, FP_SUBNORMAL, FP_ZERO */
[[nodiscard]] static constexpr int fpclassify(float value) noexcept
{
// FROM musl __fpclassifyf.c
union
{
f32 f;
u32 i;
} u = {value};

int e = u.i >> 23 & 0xff;
if (!e)
return u.i << 1 ? FP_SUBNORMAL : FP_ZERO;
if (e == 0xff)
return u.i << 9 ? FP_NAN : FP_INFINITE;
return FP_NORMAL;
}

/**
* Check if the given floating point number has finite value (not infinite or NaN)
* @param value The value to test
* @return true if value if finite, false otherwise
*/
[[nodiscard]] static constexpr bool is_finite(const float value) noexcept
{
return std::isfinite(value);
}

/**
* Check if the given floating point number has finite value (not infinite or NaN)
* @param value The value to test
* @return true if value if finite, false otherwise
*/
[[nodiscard]] static constexpr bool is_finite(const double value) noexcept
{
return std::isfinite(value);
}

/** Check if the given floating point number is a infinite value
* @param vlaue The value to test
* @return true if value is infinite, false otherwise
*/
[[nodiscard]] static constexpr bool is_infinite(const float value) noexcept
{
return std::isinf(value);
}

/** Check if the given floating point number is a infinite value
* @param vlaue The value to test
* @return true if value is infinite, false otherwise
*/
[[nodiscard]] static constexpr bool is_infinite(const double value) noexcept
{
return std::isinf(value);
}

/** Check if the given floating point number is a NaN value
* @param vlaue The value to test
* @return true if value is infinite, false otherwise
*/
[[nodiscard]] static constexpr bool is_nan(const float value) noexcept
{
return std::isnan(value);
}

/** Check if the given floating point number is a normal value
* @param vlaue The value to test
* @return true if value is infinite, false otherwise
*/
[[nodiscard]] static constexpr bool is_nan(const double value) noexcept
{
return std::isnan(value);
}

/** Check if the given floating point number is a normal value
* @param vlaue The value to test
* @return true if value is infinite, false otherwise
*/
[[nodiscard]] static constexpr bool is_normal(const float value) noexcept
{
return std::isnormal(value);
}

/** Check if the given floating point number is a normal value
* @param vlaue The value to test
* @return true if value is infinite, false otherwise
*/
[[nodiscard]] static constexpr bool is_normal(const double value) noexcept
{
return std::isnormal(value);
}

/**
* Multiplies a floating point value by the number 2 raised to the exp power.
* @param value The value to compute
* @param exp The exponent
* @return value*(2^exp)
*/
[[nodiscard]] static constexpr f32 ldexp(f32 value, i32 exp) noexcept
{
return std::ldexp(value, exp);
}

/**
* Multiplies a floating point value by the number 2 raised to the exp power.
* @param value The value to compute
* @param exp The exponent
* @return value*(2^exp)
*/
[[nodiscard]] static constexpr f64 ldexp(f64 value, i32 exp) noexcept
{
return std::ldexp(value, exp);
}
};
} // namespace hud::os::common
#endif // HD_INC_CORE_OS_COMMON_MATH_H
Loading

0 comments on commit 334146c

Please sign in to comment.