diff --git a/interface/core/i128.h b/interface/core/i128.h index 4c84990..cd4dce7 100644 --- a/interface/core/i128.h +++ b/interface/core/i128.h @@ -2,6 +2,8 @@ #define HD_INC_CORE_I128_H #include "traits/conditional.h" #include "traits/integral_constant.h" +#include "traits/is_signed.h" +#include "traits/is_unsigned.h" #if !defined(HD_INC_CORE_TYPES_H) #error i128.h must be included after or in types.h @@ -12,7 +14,7 @@ #else #include "i128/i128_portable.h" #endif -#include "math.h" +#include "limits.h" namespace hud { @@ -22,7 +24,6 @@ namespace hud class alignas(16) i128 : public details::i128::i128_impl { - private: using super = details::i128::i128_impl; @@ -30,7 +31,7 @@ namespace hud using super::super; /** Construct a i128 from u128. */ - explicit constexpr i128(u128 value) noexcept; + constexpr i128(u128 value) noexcept; /** Retrieves the high part of the i128. */ using super::high; @@ -38,131 +39,43 @@ namespace hud using super::low; /** Cast to bool. */ - [[nodiscard]] constexpr explicit operator bool() const noexcept - { - return *static_cast(this); - } - + using super::operator bool; /** Cast to i8. */ - [[nodiscard]] constexpr explicit operator i8() const noexcept - { - return *static_cast(this); - } - + using super::operator i8; /** Cast to u8. */ - [[nodiscard]] constexpr explicit operator u8() const noexcept - { - return *static_cast(this); - } - + using super::operator u8; /** Cast to i16. */ - [[nodiscard]] constexpr explicit operator i16() const noexcept - { - return *static_cast(this); - } - + using super::operator i16; /** Cast to u16. */ - [[nodiscard]] constexpr explicit operator u16() const noexcept - { - return *static_cast(this); - } - + using super::operator u16; /** Cast to i32. */ - [[nodiscard]] constexpr explicit operator i32() const noexcept - { - return *static_cast(this); - } - + using super::operator i32; /** Cast to u32. */ - [[nodiscard]] constexpr explicit operator u32() const noexcept - { - return *static_cast(this); - } - + using super::operator u32; /** Cast to i64. */ - [[nodiscard]] constexpr explicit operator i64() const noexcept - { - return *static_cast(this); - } - + using super::operator i64; /** Cast to u64. */ - [[nodiscard]] constexpr explicit operator u64() const noexcept - { - return *static_cast(this); - } - + using super::operator u64; /** Cast to ansichar. */ - [[nodiscard]] constexpr explicit operator ansichar() const noexcept - { - return *static_cast(this); - } - + using super::operator ansichar; /** Cast to wchar. */ - [[nodiscard]] constexpr explicit operator wchar() const noexcept - { - return *static_cast(this); - } - + using super::operator wchar; /** Cast to char16. */ - [[nodiscard]] constexpr explicit operator char16() const noexcept - { - return *static_cast(this); - } - + using super::operator char16; /** Cast to char32. */ - [[nodiscard]] constexpr explicit operator char32() const noexcept - { - return *static_cast(this); - } - + using super::operator char32; /** Cast to f32. */ - [[nodiscard]] constexpr explicit operator f32() const noexcept - { - return *static_cast(this); - } - + using super::operator f32; /** Cast to f64. */ - [[nodiscard]] constexpr explicit operator f64() const noexcept - { - return *static_cast(this); - } + using super::operator f64; #if HD_INTRINSIC_INT128_SUPPORTED /** Cast to __int128. */ - [[nodiscard]] constexpr explicit operator __int128() const noexcept - { - return *static_cast(this); - } - + using super::operator __int128; /** Cast to unsigned __int128. */ - [[nodiscard]] constexpr explicit operator unsigned __int128() const noexcept - { - return *static_cast(this); - } + using super::operator unsigned __int128; #endif }; - /** - * Checks whether right and left i128 are equal. - * @param left The left i128 to compare - * @param right The right i128 to compare - * @param true if right and left i128 are equal, false otherwise - */ - [[nodiscard]] HD_FORCEINLINE constexpr bool operator==(const i128 &left, const i128 &right) noexcept - { - return left.low() == right.low() && left.high() == right.high(); - } - - /** - * Checks whether right and left i128 are not equal. - * @param left The left i128 to compare - * @param right The right i128 to compare - * @param true if right and left i128 are equal, false otherwise - */ - [[nodiscard]] HD_FORCEINLINE constexpr bool operator!=(const i128 &left, const i128 &right) noexcept - { - return !(left == right); - } - class alignas(16) u128 : public details::i128::u128_impl { @@ -172,7 +85,7 @@ namespace hud public: using super::super; - explicit constexpr u128(i128 value) noexcept + constexpr u128(i128 value) noexcept : super(static_cast(value)) { } @@ -183,132 +96,43 @@ namespace hud using super::low; /** Cast to bool. */ - [[nodiscard]] constexpr explicit operator bool() const noexcept - { - return *static_cast(this); - } - + using super::operator bool; /** Cast to i8. */ - [[nodiscard]] constexpr explicit operator i8() const noexcept - { - return *static_cast(this); - } - + using super::operator i8; /** Cast to u8. */ - [[nodiscard]] constexpr explicit operator u8() const noexcept - { - return *static_cast(this); - } - + using super::operator u8; /** Cast to i16. */ - [[nodiscard]] constexpr explicit operator i16() const noexcept - { - return *static_cast(this); - } - + using super::operator i16; /** Cast to u16. */ - [[nodiscard]] constexpr explicit operator u16() const noexcept - { - return *static_cast(this); - } - + using super::operator u16; /** Cast to i32. */ - [[nodiscard]] constexpr explicit operator i32() const noexcept - { - return *static_cast(this); - } - + using super::operator i32; /** Cast to u32. */ - [[nodiscard]] constexpr explicit operator u32() const noexcept - { - return *static_cast(this); - } - + using super::operator u32; /** Cast to i64. */ - [[nodiscard]] constexpr explicit operator i64() const noexcept - { - return *static_cast(this); - } - + using super::operator i64; /** Cast to u64. */ - [[nodiscard]] constexpr explicit operator u64() const noexcept - { - return *static_cast(this); - } - + using super::operator u64; /** Cast to ansichar. */ - [[nodiscard]] constexpr explicit operator ansichar() const noexcept - { - return *static_cast(this); - } - + using super::operator ansichar; /** Cast to wchar. */ - [[nodiscard]] constexpr explicit operator wchar() const noexcept - { - return *static_cast(this); - } - + using super::operator wchar; /** Cast to char16. */ - [[nodiscard]] constexpr explicit operator char16() const noexcept - { - return *static_cast(this); - } - + using super::operator char16; /** Cast to char32. */ - [[nodiscard]] constexpr explicit operator char32() const noexcept - { - return *static_cast(this); - } - + using super::operator char32; /** Cast to f32. */ - [[nodiscard]] constexpr explicit operator f32() const noexcept - { - return *static_cast(this); - } - + using super::operator f32; /** Cast to f64. */ - [[nodiscard]] constexpr explicit operator f64() const noexcept - { - return *static_cast(this); - } - + using super::operator f64; #if HD_INTRINSIC_INT128_SUPPORTED /** Cast to __int128. */ - [[nodiscard]] constexpr explicit operator __int128() const noexcept - { - return *static_cast(this); - } - + using super::operator __int128; /** Cast to unsigned __int128. */ - [[nodiscard]] constexpr explicit operator unsigned __int128() const noexcept - { - return *static_cast(this); - } + using super::operator unsigned __int128; #endif }; - /** - * Checks whether right and left u128 are equal. - * @param left The left u128 to compare - * @param right The right u128 to compare - * @param true if right and left u128 are equal, false otherwise - */ - [[nodiscard]] HD_FORCEINLINE constexpr bool operator==(const u128 &left, const u128 &right) noexcept - { - return left.low() == right.low() && left.high() == right.high(); - } - - /** - * Checks whether right and left u128 are not equal. - * @param left The left u128 to compare - * @param right The right u128 to compare - * @param true if right and left u128 are equal, false otherwise - */ - [[nodiscard]] HD_FORCEINLINE constexpr bool operator!=(const u128 &left, const u128 &right) noexcept - { - return !(left == right); - } - /** Construct a i128 from u128. */ constexpr i128::i128(u128 value) noexcept : super(static_cast(value)) @@ -352,37 +176,45 @@ namespace hud static inline constexpr u128 u128_max = u128 {u64_max, u64_max}; static inline constexpr u128 u128_min = u128 {u64_min, 0u}; - namespace math + template<> struct limits { - template<> struct limits - { - static constexpr i128 min {hud::i128_min}; - static constexpr i128 max {hud::i128_max}; - }; + static constexpr i128 min {hud::i128_min}; + static constexpr i128 max {hud::i128_max}; + }; - template<> struct limits - { - static constexpr u128 min {hud::u128_min}; - static constexpr u128 max {hud::u128_max}; - }; + template<> struct limits + { + static constexpr u128 min {hud::u128_min}; + static constexpr u128 max {hud::u128_max}; + }; #if HD_INTRINSIC_INT128_SUPPORTED - template<> struct limits<__int128> - { - static constexpr __int128 min {static_cast<__int128>(i128_min)}; - static constexpr __int128 max {static_cast<__int128>(i128_max)}; - }; + template<> struct limits<__int128> + { + static constexpr __int128 min {static_cast<__int128>(i128_min)}; + static constexpr __int128 max {static_cast<__int128>(i128_max)}; + }; - template<> struct limits - { - static constexpr unsigned __int128 min {static_cast(u128_min)}; - static constexpr unsigned __int128 max {static_cast(u128_max)}; - }; + template<> struct limits + { + static constexpr unsigned __int128 min {static_cast(u128_min)}; + static constexpr unsigned __int128 max {static_cast(u128_max)}; + }; #endif - } // namespace math + template<> + struct is_signed + : hud::true_type + { + }; + + template<> + struct is_unsigned + : hud::true_type + { + }; } // namespace hud #endif // HD_INC_CORE_I128_H \ No newline at end of file diff --git a/interface/core/i128/i128_intrinsics.h b/interface/core/i128/i128_intrinsics.h index f038e8e..4b2670c 100644 --- a/interface/core/i128/i128_intrinsics.h +++ b/interface/core/i128/i128_intrinsics.h @@ -1,6 +1,7 @@ #ifndef HD_INC_CORE_I128_I128_INTRINSICS_H #define HD_INC_CORE_I128_I128_INTRINSICS_H - +#include "../assert.h" +#include "../math.h" #if !defined(HD_INTRINSIC_INT128_SUPPORTED) #error i128_intrinsics.h is included but HD_INTRINSIC_INT128_SUPPORTED is not set #endif @@ -24,7 +25,7 @@ namespace hud * constexpr and avoids undefined behavior. * Modern compilers like Clang and GCC optimize this operation to a no-op on x86-64 architectures. */ - constexpr __int128 bit_cast_to_signed_int128(unsigned __int128 value) + [[nodiscard]] constexpr __int128 bit_cast_to_signed_int128(unsigned __int128 value) noexcept { return value & (static_cast(1) << 127) ? ~static_cast<__int128>(~value) : static_cast<__int128>(value); } @@ -39,7 +40,7 @@ namespace hud * constexpr and avoids undefined behavior. * Compilers like Clang, GCC, and MSVC optimize this operation to a no-op on x86-64 architectures. */ - constexpr i64 bit_cast_to_signed_i64(u64 value) + [[nodiscard]] constexpr i64 bit_cast_to_signed_i64(u64 value) noexcept { return value & (u64 {1} << 63) ? ~static_cast(~value) : static_cast(value); } @@ -95,14 +96,14 @@ namespace hud explicit constexpr i128_intrinsics(u128_intrinsics value) noexcept; /** Construct a i128 from f32. */ - i128_intrinsics(f32 value) noexcept - : value_(value) + constexpr i128_intrinsics(f32 value) noexcept + : value_ {static_cast<__int128>(value)} { } /** Construct a i128 from f64. */ - i128_intrinsics(f64 value) noexcept - : value_(value) + constexpr i128_intrinsics(f64 value) noexcept + : value_ {static_cast<__int128>(value)} { } @@ -119,103 +120,103 @@ namespace hud } /** Cast to bool. */ - [[nodiscard]] constexpr operator bool() const noexcept + [[nodiscard]] explicit constexpr operator bool() const noexcept { return value_ != 0u; } /** Cast to i8. */ - [[nodiscard]] constexpr operator i8() const noexcept + [[nodiscard]] explicit constexpr operator i8() const noexcept { return static_cast(value_); } /** Cast to u8. */ - [[nodiscard]] constexpr operator u8() const noexcept + [[nodiscard]] explicit constexpr operator u8() const noexcept { return static_cast(value_); } /** Cast to i16. */ - [[nodiscard]] constexpr operator i16() const noexcept + [[nodiscard]] explicit constexpr operator i16() const noexcept { return static_cast(value_); } /** Cast to u16. */ - [[nodiscard]] constexpr operator u16() const noexcept + [[nodiscard]] explicit constexpr operator u16() const noexcept { return static_cast(value_); } /** Cast to i32. */ - [[nodiscard]] constexpr operator i32() const noexcept + [[nodiscard]] explicit constexpr operator i32() const noexcept { return static_cast(value_); } /** Cast to u32. */ - [[nodiscard]] constexpr operator u32() const noexcept + [[nodiscard]] explicit constexpr operator u32() const noexcept { return static_cast(value_); } /** Cast to i64. */ - [[nodiscard]] constexpr operator i64() const noexcept + [[nodiscard]] explicit constexpr operator i64() const noexcept { return static_cast(value_); } /** Cast to u64. */ - [[nodiscard]] constexpr operator u64() const noexcept + [[nodiscard]] explicit constexpr operator u64() const noexcept { return value_; } /** Cast to ansichar. */ - [[nodiscard]] constexpr operator ansichar() const noexcept + [[nodiscard]] explicit constexpr operator ansichar() const noexcept { return static_cast(value_); } /** Cast to wchar. */ - [[nodiscard]] constexpr operator wchar() const noexcept + [[nodiscard]] explicit constexpr operator wchar() const noexcept { return static_cast(value_); } /** Cast to char16. */ - [[nodiscard]] constexpr operator char16() const noexcept + [[nodiscard]] explicit constexpr operator char16() const noexcept { return static_cast(value_); } /** Cast to char32. */ - [[nodiscard]] constexpr operator char32() const noexcept + [[nodiscard]] explicit constexpr operator char32() const noexcept { return static_cast(value_); } /** Cast to f32. */ - [[nodiscard]] constexpr operator f32() const noexcept + [[nodiscard]] explicit constexpr operator f32() const noexcept { return static_cast(value_); } /** Cast to f64. */ - [[nodiscard]] constexpr operator f64() const noexcept + [[nodiscard]] explicit constexpr operator f64() const noexcept { return static_cast(value_); } /** Cast to __int128. */ - [[nodiscard]] constexpr operator __int128() const noexcept + [[nodiscard]] explicit constexpr operator __int128() const noexcept { return value_; } /** Cast to unsigned __int128. */ - [[nodiscard]] constexpr operator unsigned __int128() const noexcept + [[nodiscard]] explicit constexpr operator unsigned __int128() const noexcept { return static_cast(value_); } @@ -223,6 +224,72 @@ namespace hud __int128 value_; }; + /** + * Checks whether right and left i128_intrinsics are equal. + * @param left The left i128_intrinsics to compare + * @param right The right i128_intrinsics to compare + * @param true if right and left i128_intrinsics are equal, false otherwise + */ + [[nodiscard]] HD_FORCEINLINE constexpr bool operator==(const i128_intrinsics &left, const i128_intrinsics &right) noexcept + { + return left.value_ == right.value_; + } + + /** + * Checks whether right and left i128_intrinsics are not equal. + * @param left The left i128_intrinsics to compare + * @param right The right i128_intrinsics to compare + * @param true if right and left i128_intrinsics are not equal, false otherwise + */ + [[nodiscard]] HD_FORCEINLINE constexpr bool operator!=(const i128_intrinsics &left, const i128_intrinsics &right) noexcept + { + return left.value_ != right.value_; + } + + /** + * Checks whether left is less than right i128_intrinsics. + * @param left The left i128_intrinsics to compare + * @param right The right i128_intrinsics to compare + * @param true if left is less than right, false otherwise + */ + [[nodiscard]] HD_FORCEINLINE constexpr bool operator<(const i128_intrinsics &left, const i128_intrinsics &right) noexcept + { + return left.value_ < right.value_; + } + + /** + * Checks whether left is less or equal than right i128_intrinsics. + * @param left The left i128_intrinsics to compare + * @param right The right i128_intrinsics to compare + * @param true if left is less or equal than right, false otherwise + */ + [[nodiscard]] HD_FORCEINLINE constexpr bool operator<=(const i128_intrinsics &left, const i128_intrinsics &right) noexcept + { + return left.value_ <= right.value_; + } + + /** + * Checks whether left is greater than right i128_intrinsics. + * @param left The left i128_intrinsics to compare + * @param right The right i128_intrinsics to compare + * @param true if left is greater than right, false otherwise + */ + [[nodiscard]] HD_FORCEINLINE constexpr bool operator>(const i128_intrinsics &left, const i128_intrinsics &right) noexcept + { + return left.value_ > right.value_; + } + + /** + * Checks whether left is greater or equal than right i128_intrinsics. + * @param left The left i128_intrinsics to compare + * @param right The right i128_intrinsics to compare + * @param true if left is greater or equal than right, false otherwise + */ + [[nodiscard]] HD_FORCEINLINE constexpr bool operator>=(const i128_intrinsics &left, const i128_intrinsics &right) noexcept + { + return left.value_ >= right.value_; + } + using i128_impl = i128_intrinsics; struct alignas(16) u128_intrinsics @@ -274,22 +341,33 @@ namespace hud /** Construct a i128 from i128. */ explicit constexpr u128_intrinsics(i128_intrinsics value) noexcept - : value_(static_cast(value)) + : value_ {static_cast(value)} { } /** Construct a i128 from f32. */ constexpr u128_intrinsics(f32 value) noexcept - : value_(value) + : value_ {static_cast(value)} { + // Check value is not NaN or infinite + hud::check(hud::math::is_finite(value)); + // Ensure we are positive + hud::check(value > -1); } /** Construct a i128 from f64. */ constexpr u128_intrinsics(f64 value) noexcept - : value_(value) + : value_ {static_cast(value)} { + // Check value is not NaN or infinite + hud::check(hud::math::is_finite(value)); + // Ensure we are positive + hud::check(value > -1); + // Check value is lower than 2^128 + hud::check(value < hud::math::ldexp(static_cast(1), 128)); } + /////////////////////////// /** Retrieves the low part of the u64. */ [[nodiscard]] constexpr u64 low() const noexcept { @@ -303,103 +381,103 @@ namespace hud } /** Cast to bool. */ - [[nodiscard]] constexpr operator bool() const noexcept + [[nodiscard]] explicit constexpr operator bool() const noexcept { return value_ != 0u; } /** Cast to i8. */ - [[nodiscard]] constexpr operator i8() const noexcept + [[nodiscard]] explicit constexpr operator i8() const noexcept { return static_cast(value_); } /** Cast to u8. */ - [[nodiscard]] constexpr operator u8() const noexcept + [[nodiscard]] explicit constexpr operator u8() const noexcept { return static_cast(value_); } /** Cast to i16. */ - [[nodiscard]] constexpr operator i16() const noexcept + [[nodiscard]] explicit constexpr operator i16() const noexcept { return static_cast(value_); } /** Cast to u16. */ - [[nodiscard]] constexpr operator u16() const noexcept + [[nodiscard]] explicit constexpr operator u16() const noexcept { return static_cast(value_); } /** Cast to i32. */ - [[nodiscard]] constexpr operator i32() const noexcept + [[nodiscard]] explicit constexpr operator i32() const noexcept { return static_cast(value_); } /** Cast to u32. */ - [[nodiscard]] constexpr operator u32() const noexcept + [[nodiscard]] explicit constexpr operator u32() const noexcept { return static_cast(value_); } /** Cast to i64. */ - [[nodiscard]] constexpr operator i64() const noexcept + [[nodiscard]] explicit constexpr operator i64() const noexcept { return static_cast(value_); } /** Cast to u64. */ - [[nodiscard]] constexpr operator u64() const noexcept + [[nodiscard]] explicit constexpr operator u64() const noexcept { return value_; } /** Cast to ansichar. */ - [[nodiscard]] constexpr operator ansichar() const noexcept + [[nodiscard]] explicit constexpr operator ansichar() const noexcept { return static_cast(value_); } /** Cast to wchar. */ - [[nodiscard]] constexpr operator wchar() const noexcept + [[nodiscard]] explicit constexpr operator wchar() const noexcept { return static_cast(value_); } /** Cast to char16. */ - [[nodiscard]] constexpr operator char16() const noexcept + [[nodiscard]] explicit constexpr operator char16() const noexcept { return static_cast(value_); } /** Cast to char32. */ - [[nodiscard]] constexpr operator char32() const noexcept + [[nodiscard]] explicit constexpr operator char32() const noexcept { return static_cast(value_); } /** Cast to f32. */ - [[nodiscard]] constexpr operator f32() const noexcept + [[nodiscard]] explicit constexpr operator f32() const noexcept { return static_cast(value_); } /** Cast to f64. */ - [[nodiscard]] constexpr operator f64() const noexcept + [[nodiscard]] explicit constexpr operator f64() const noexcept { return static_cast(value_); } /** Cast to __int128. */ - [[nodiscard]] constexpr operator __int128() const noexcept + [[nodiscard]] explicit constexpr operator __int128() const noexcept { return bit_cast_to_signed_int128(static_cast<__int128>(value_)); } /** Cast to unsigned __int128. */ - [[nodiscard]] constexpr operator unsigned __int128() const noexcept + [[nodiscard]] explicit constexpr operator unsigned __int128() const noexcept { return value_; } @@ -407,6 +485,72 @@ namespace hud unsigned __int128 value_; }; + /** + * Checks whether right and left u128_intrinsics are equal. + * @param left The left u128_intrinsics to compare + * @param right The right u128_intrinsics to compare + * @param true if right and left u128_intrinsics are equal, false otherwise + */ + [[nodiscard]] HD_FORCEINLINE constexpr bool operator==(const u128_intrinsics &left, const u128_intrinsics &right) noexcept + { + return left.value_ == right.value_; + } + + /** + * Checks whether right and left u128_intrinsics are not equal. + * @param left The left u128_intrinsics to compare + * @param right The right u128_intrinsics to compare + * @param true if right and left u128_intrinsics are not equal, false otherwise + */ + [[nodiscard]] HD_FORCEINLINE constexpr bool operator!=(const i128_intrinsics &left, const u128_intrinsics &right) noexcept + { + return left.value_ != right.value_; + } + + /** + * Checks whether left is less than right u128_intrinsics. + * @param left The left u128_intrinsics to compare + * @param right The right u128_intrinsics to compare + * @param true if left is less than right, false otherwise + */ + [[nodiscard]] constexpr bool operator<(const u128_intrinsics &left, const u128_intrinsics &right) noexcept + { + return left.value_ < right.value_; + } + + /** + * Checks whether left is less or equal than right u128_intrinsics. + * @param left The left u128_intrinsics to compare + * @param right The right u128_intrinsics to compare + * @param true if left is less or equal than right, false otherwise + */ + [[nodiscard]] constexpr bool operator<=(const u128_intrinsics &left, const u128_intrinsics &right) noexcept + { + return left.value_ <= right.value_; + } + + /** + * Checks whether left is greater than right u128_intrinsics. + * @param left The left u128_intrinsics to compare + * @param right The right u128_intrinsics to compare + * @param true if left is greater than right, false otherwise + */ + [[nodiscard]] constexpr bool operator>(const u128_intrinsics &left, const u128_intrinsics &right) noexcept + { + return left.value_ > right.value_; + } + + /** + * Checks whether left is greater or equal than right u128_intrinsics. + * @param left The left u128_intrinsics to compare + * @param right The right u128_intrinsics to compare + * @param true if left is greater or equal than right, false otherwise + */ + [[nodiscard]] constexpr bool operator>=(const u128_intrinsics &left, const u128_intrinsics &right) noexcept + { + return left.value_ >= right.value_; + } + using u128_impl = u128_intrinsics; constexpr i128_intrinsics::i128_intrinsics(u128_intrinsics value) noexcept diff --git a/interface/core/i128/i128_portable.h b/interface/core/i128/i128_portable.h index 55c5e68..fcd9255 100644 --- a/interface/core/i128/i128_portable.h +++ b/interface/core/i128/i128_portable.h @@ -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 diff --git a/interface/core/limits.h b/interface/core/limits.h new file mode 100644 index 0000000..4a7f056 --- /dev/null +++ b/interface/core/limits.h @@ -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 + struct limits; +#define hud_limits_for(type_t) \ + template<> struct limits \ + { \ + 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 \ No newline at end of file diff --git a/interface/core/math.h b/interface/core/math.h index c7559ef..468ca5d 100644 --- a/interface/core/math.h +++ b/interface/core/math.h @@ -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 - struct limits; -#define hud_limits_for(type_t) \ - template<> struct limits \ - { \ - 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 - requires(is_integral_v) - [[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 - [[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 diff --git a/interface/core/memory.h b/interface/core/memory.h index 5ded756..a77dc16 100644 --- a/interface/core/memory.h +++ b/interface/core/memory.h @@ -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" @@ -521,4 +521,4 @@ namespace hud } // namespace hud -#endif // HD_INC_OSABSTRACTIONLAYER_MEMORY_H \ No newline at end of file +#endif // HD_INC_CORE_MEMORY_H \ No newline at end of file diff --git a/interface/core/os_common/cstring.h b/interface/core/os_common/cstring.h index 64bf665..4803359 100644 --- a/interface/core/os_common/cstring.h +++ b/interface/core/os_common/cstring.h @@ -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" @@ -588,4 +588,4 @@ namespace hud::os::common } // namespace hud::os::common -#endif // HD_INC_OSABSTRACTIONLAYER_OS_COMMON_CSTRING_H \ No newline at end of file +#endif // HD_INC_CORE_OS_COMMON_CSTRING_H \ No newline at end of file diff --git a/interface/core/os_common/math.h b/interface/core/os_common/math.h new file mode 100644 index 0000000..9779790 --- /dev/null +++ b/interface/core/os_common/math.h @@ -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 + +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 + requires(hud::is_integral_v) + [[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 + [[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 \ No newline at end of file diff --git a/interface/core/os_common/types.h b/interface/core/os_common/types.h index a544574..ceb4571 100644 --- a/interface/core/os_common/types.h +++ b/interface/core/os_common/types.h @@ -1,5 +1,5 @@ -#ifndef HD_INC_OSABSTRACTIONLAYER_OS_COMMON_TYPES_H -#define HD_INC_OSABSTRACTIONLAYER_OS_COMMON_TYPES_H +#ifndef HD_INC_CORE_OS_COMMON_TYPES_H +#define HD_INC_CORE_OS_COMMON_TYPES_H #include // uint8_t, uint16_t, .... namespace hud::os::common @@ -57,26 +57,42 @@ namespace hud::os::common // Min-Max unsigned common type static inline constexpr bool bool_max = true; static inline constexpr bool bool_min = false; + static inline constexpr bool bool_min_positive = false; static inline constexpr u8 u8_max = 0xFF; static inline constexpr u8 u8_min = 0x00; + static inline constexpr u8 u8_min_positive = 0x00; static inline constexpr u16 u16_max = 0xFFFF; static inline constexpr u16 u16_min = 0x0000; + static inline constexpr u16 u16_min_positive = 0x0000; static inline constexpr u32 u32_max = 0xFFFFFFFF; static inline constexpr u32 u32_min = 0x00000000; + static inline constexpr u32 u32_min_positive = 0x00000000; static inline constexpr u64 u64_max = 0xFFFFFFFFFFFFFFFF; static inline constexpr u64 u64_min = 0x0000000000000000; + static inline constexpr u64 u64_min_positive = 0x0000000000000000; static inline constexpr i8 i8_max = 127; static inline constexpr i8 i8_min = (i8 {-127} - 1); + static inline constexpr i8 i8_min_positive = 0; static inline constexpr i16 i16_max = 32767; static inline constexpr i16 i16_min = (i16 {-32767} - 1); + static inline constexpr i16 i16_min_positive = 0; static inline constexpr i32 i32_max = 2147483647; static inline constexpr i32 i32_min = (i32 {-2147483647} - 1); + static inline constexpr i32 i32_min_positive = 0; static inline constexpr i64 i64_max = 9223372036854775807; static inline constexpr i64 i64_min = (i64 {-9223372036854775807} - 1); + static inline constexpr i64 i64_min_positive = 0; static inline constexpr ansichar ansichar_max = i8_max; static inline constexpr ansichar ansichar_min = i8_min; + static inline constexpr ansichar ansichar_min_positive = i8_min_positive; + static inline constexpr char16 char16_max = u16_max; + static inline constexpr char16 char16_min = u16_min; + static inline constexpr char16 char16_min_positive = u16_min_positive; + static inline constexpr char32 char32_max = u32_max; + static inline constexpr char32 char32_min = u32_min; + static inline constexpr char32 char32_min_positive = u32_min_positive; // Largest finite f32 value. static inline constexpr f32 f32_max = 3.402823466e+38F; @@ -99,23 +115,31 @@ namespace hud::os::common #if defined(HD_TARGET_32_BITS) static inline constexpr uptr uptr_max = u32_max; static inline constexpr uptr uptr_min = u32_min; + static inline constexpr uptr uptr_min_positive = u32_min_positive; static inline constexpr iptr iptr_max = i32_max; static inline constexpr iptr iptr_min = i32_min; + static inline constexpr iptr iptr_min_positive = i32_min_positive; static inline constexpr usize usize_max = u32_max; static inline constexpr usize usize_min = u32_min; + static inline constexpr usize usize_min_positive = u32_min_positive; static inline constexpr isize isize_max = i32_max; static inline constexpr isize isize_min = i32_min; + static inline constexpr isize isize_min_positive = i32_min_positive; #else static inline constexpr uptr uptr_max = u64_max; static inline constexpr uptr uptr_min = u64_min; + static inline constexpr uptr uptr_min_positive = u64_min_positive; static inline constexpr iptr iptr_max = i64_max; static inline constexpr iptr iptr_min = i64_min; + static inline constexpr iptr iptr_min_positive = i64_min_positive; static inline constexpr usize usize_max = u64_max; static inline constexpr usize usize_min = u64_min; + static inline constexpr usize usize_min_positive = u64_min_positive; static inline constexpr isize isize_max = i64_max; static inline constexpr isize isize_min = i64_min; + static inline constexpr isize isize_min_positive = i64_min_positive; #endif }; } // namespace hud::os::common -#endif // HD_INC_OSABSTRACTIONLAYER_OS_COMMON_TYPES_H \ No newline at end of file +#endif // HD_INC_CORE_OS_COMMON_TYPES_H \ No newline at end of file diff --git a/interface/core/os_linux/debugger.h b/interface/core/os_linux/debugger.h index 70162c1..13ad9d9 100644 --- a/interface/core/os_linux/debugger.h +++ b/interface/core/os_linux/debugger.h @@ -9,7 +9,6 @@ namespace hud::os::linux { struct debugger { - /** Checks whether the calling process is being debugged by a user-mode debugger. */ static bool is_present() noexcept; diff --git a/interface/core/os_linux/math.h b/interface/core/os_linux/math.h new file mode 100644 index 0000000..74fe6e3 --- /dev/null +++ b/interface/core/os_linux/math.h @@ -0,0 +1,41 @@ +#ifndef HD_INC_CORE_OS_LINUX_MATH_H +#define HD_INC_CORE_OS_LINUX_MATH_H +#include "../os_common/math.h" +#include "../traits/is_floating_point.h" +#if !defined(HD_OS_LINUX) + #error This file must be included only when targetting Linux OS +#endif +#include + +namespace hud::os::linux +{ + struct math + : public os::common::math + { + + template + [[nodiscard]] static type_t log(const type_t value) noexcept + { + return __builtin_log(value); + } + + [[nodiscard]] static f32 log(const f32 value) noexcept + { + return __builtin_logf(value); + } + + template + [[nodiscard]] static type_t sqrt(const type_t value) noexcept + { + return __builtin_sqrt(value); + } + + [[nodiscard]] static f32 sqrt(const f32 value) noexcept + { + return __builtin_sqrtf(value); + } + }; + +} // namespace hud::os::linux + +#endif /* HD_INC_CORE_OS_LINUX_MATH_H */ \ No newline at end of file diff --git a/interface/core/os_linux/types.h b/interface/core/os_linux/types.h index 3cec213..22c1c69 100644 --- a/interface/core/os_linux/types.h +++ b/interface/core/os_linux/types.h @@ -9,10 +9,12 @@ namespace hud::os::linux { - struct types : public os::common::types + struct types + : public os::common::types { static inline constexpr wchar wchar_max = i32_max; static inline constexpr wchar wchar_min = i32_min; + static inline constexpr wchar wchar_min_positive = i32_min_positive; }; } // namespace hud::os::linux diff --git a/interface/core/os_windows/math.h b/interface/core/os_windows/math.h new file mode 100644 index 0000000..8c75fa5 --- /dev/null +++ b/interface/core/os_windows/math.h @@ -0,0 +1,16 @@ +#ifndef HD_INC_CORE_OS_WINDOWS_MATH_H +#define HD_INC_CORE_OS_WINDOWS_MATH_H +#include "../os_common/math.h" +#if !defined(HD_OS_WINDOWS) + #error This file must be included only when targetting Windows OS +#endif + +namespace hud::os::windows +{ + struct math + : public os::common::math + { + }; +} // namespace hud::os::windows + +#endif /* HD_INC_CORE_OS_WINDOWS_MATH_H */ \ No newline at end of file diff --git a/interface/core/os_windows/types.h b/interface/core/os_windows/types.h index 12870cb..28f0228 100644 --- a/interface/core/os_windows/types.h +++ b/interface/core/os_windows/types.h @@ -13,6 +13,7 @@ namespace hud::os::windows { static inline constexpr wchar wchar_max = u16_max; static inline constexpr wchar wchar_min = u16_min; + static inline constexpr wchar wchar_min_positive = u16_min_positive; }; } // namespace hud::os::windows diff --git a/interface/core/traits/is_signed.h b/interface/core/traits/is_signed.h index 16ab91d..3c485c8 100644 --- a/interface/core/traits/is_signed.h +++ b/interface/core/traits/is_signed.h @@ -16,19 +16,19 @@ namespace hud */ template> struct is_signed - : hud::bool_constant(-1) < remove_cv_t(0)> + : hud::bool_constant(-1) < hud::remove_cv_t(0)> { }; template struct is_signed - : is_floating_point + : hud::is_floating_point { }; /** Equivalent of is_signed::value. */ template - inline constexpr bool is_signed_v = is_signed::value; + inline constexpr bool is_signed_v = hud::is_signed::value; } // namespace hud diff --git a/interface/core/types.h b/interface/core/types.h index d167e24..210bfa0 100644 --- a/interface/core/types.h +++ b/interface/core/types.h @@ -54,50 +54,84 @@ namespace hud // Min-Max unsigned common type // Highest bool value. - static inline constexpr bool bool_max = types::u8_max; + static inline constexpr bool bool_max = types::bool_max; // Lowest bool value. - static inline constexpr bool bool_min = types::u8_min; + static inline constexpr bool bool_min = types::bool_min; + // Lowest positive bool value. + static inline constexpr bool bool_min_positive = types::bool_min_positive; // Highest positive u8 value. static inline constexpr u8 u8_max = types::u8_max; - // Lowest positive u8 value. + // Lowest u8 value. static inline constexpr u8 u8_min = types::u8_min; + // Lowest positive u8 value. + static inline constexpr u8 u8_min_positive = types::u8_min_positive; // Highest positive u16 value. static inline constexpr u16 u16_max = types::u16_max; - // Lowest positive u16 value. + // Lowest u16 value. static inline constexpr u16 u16_min = types::u16_min; + // Lowest positive u16 value. + static inline constexpr u16 u16_min_positive = types::u16_min_positive; // Highest positive u32 value. static inline constexpr u32 u32_max = types::u32_max; - // Lowest positive u32 value. + // Lowest u32 value. static inline constexpr u32 u32_min = types::u32_min; + // Lowest positive u32 value. + static inline constexpr u32 u32_min_positive = types::u32_min_positive; // Highest positive u64 value. static inline constexpr u64 u64_max = types::u64_max; - // Lowest positive u64 value. + // Lowest u64 value. static inline constexpr u64 u64_min = types::u64_min; + // Lowest positive u64 value. + static inline constexpr u64 u64_min_positive = types::u64_min_positive; // Highest positive i8 value. static inline constexpr i8 i8_max = types::i8_max; // Lowest negative i8 value. static inline constexpr i8 i8_min = types::i8_min; + // Lowest positive i8 value. + static inline constexpr i8 i8_min_positive = types::i8_min_positive; // Highest positive i16 value. static inline constexpr i16 i16_max = types::i16_max; // Lowest negative i16 value. static inline constexpr i16 i16_min = types::i16_min; + // Lowest positive i16 value. + static inline constexpr i16 i16_min_positive = types::i16_min_positive; // Highest positive i32 value. static inline constexpr i32 i32_max = types::i32_max; // Lowest negative i32 value. static inline constexpr i32 i32_min = types::i32_min; + // Lowest positive i32 value. + static inline constexpr i32 i32_min_positive = types::i32_min_positive; // Highest positive i64 value. static inline constexpr i64 i64_max = types::i64_max; // Lowest negative i64 value. static inline constexpr i64 i64_min = types::i64_min; + // Lowest positive i64 value. + static inline constexpr i64 i64_min_positive = types::i64_min_positive; // Highest positive ansichar value. static inline constexpr ansichar ansichar_max = types::ansichar_max; // Lowest negative ansichar value. static inline constexpr ansichar ansichar_min = types::ansichar_min; + // Lowest positive ansichar value. + static inline constexpr ansichar ansichar_min_positive = types::ansichar_min_positive; // Highest positive wchar value. static inline constexpr wchar wchar_max = types::wchar_max; // Lowest negative wchar value. static inline constexpr wchar wchar_min = types::wchar_min; + // Lowest positive wchar value. + static inline constexpr wchar wchar_min_positive = types::wchar_min_positive; + // Highest positive char16 value. + static inline constexpr char16 char16_max = types::char16_max; + // Lowest negative char16 value. + static inline constexpr char16 char16_min = types::char16_min; + // Lowest positive char16 value. + static inline constexpr char16 char16_min_positive = types::char16_min_positive; + // Highest positive char32 value. + static inline constexpr char32 char32_max = types::char32_max; + // Lowest negative char32 value. + static inline constexpr char32 char32_min = types::char32_min; + // Lowest positive char32 value. + static inline constexpr char32 char32_min_positive = types::char32_min_positive; // Largest finite f32 value. static inline constexpr f32 f32_max = types::f32_max; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cc29f24..4e7570d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -37,6 +37,7 @@ set( interface ../interface/core/os_common/atomics.h ../interface/core/os_common/character.h ../interface/core/os_common/cstring.h + ../interface/core/os_common/math.h ../interface/core/os_common/memory.h ../interface/core/os_common/types.h ../interface/core/os_common/uuid.h @@ -44,6 +45,7 @@ set( interface ../interface/core/os_linux/character.h ../interface/core/os_linux/cstring.h ../interface/core/os_linux/debugger.h + ../interface/core/os_linux/math.h ../interface/core/os_linux/memory.h ../interface/core/os_linux/types.h ../interface/core/os_linux/uuid.h @@ -52,6 +54,7 @@ set( interface ../interface/core/os_windows/character.h ../interface/core/os_windows/cstring.h ../interface/core/os_windows/debugger.h + ../interface/core/os_windows/math.h ../interface/core/os_windows/memory.h ../interface/core/os_windows/types.h ../interface/core/os_windows/uuid.h @@ -200,6 +203,7 @@ set( interface ../interface/core/debugger.h ../interface/core/defines.h ../interface/core/hash.h + ../interface/core/limits.h ../interface/core/i128.h ../interface/core/iterators ../interface/core/math.h diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 276130d..8f2a9c6 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -253,7 +253,9 @@ set( src tuple/tuple_swap.cpp tuple/tuple_element.cpp tuple/tuple_size.cpp + u128/u128_assign.cpp u128/u128_cast.cpp + u128/u128_comparisons.cpp u128/u128_constructors.cpp u128/u128_operations.cpp unique_pointer/array/unique_pointer_array_assignments.cpp @@ -292,6 +294,7 @@ set( src cstring.cpp debugger.cpp main.cpp + math.cpp precompiled.h slice.cpp types.cpp diff --git a/test/iterators/random_access_iterator.cpp b/test/iterators/random_access_iterator.cpp index a1172bc..f568185 100644 --- a/test/iterators/random_access_iterator.cpp +++ b/test/iterators/random_access_iterator.cpp @@ -1,4 +1,5 @@ #include +#include GTEST_TEST(random_access_iterator, check_const_correctness) { @@ -30,7 +31,8 @@ GTEST_TEST(random_access_iterator, constructor) hud::random_access_iterator it_const(arr_const); return std::tuple { it.operator->() == &arr[0], - it_const.operator->() == &arr_const[0]}; + it_const.operator->() == &arr_const[0] + }; }; // Non constant @@ -140,7 +142,8 @@ GTEST_TEST(random_access_iterator, operator_pre_increment) (++it).operator->() == &arr[3], *it == arr[3], (++it).operator->() == &arr[4], - *it == arr[4]}; + *it == arr[4] + }; hud::random_access_iterator it_const(arr_const); const auto const_it = std::tuple { it_const.operator->() == &arr_const[0], @@ -152,10 +155,12 @@ GTEST_TEST(random_access_iterator, operator_pre_increment) (++it_const).operator->() == &arr_const[3], *it_const == arr_const[3], (++it_const).operator->() == &arr_const[4], - *it_const == arr_const[4]}; + *it_const == arr_const[4] + }; return std::tuple { mutable_it, - const_it}; + const_it + }; }; // Non constant @@ -237,7 +242,8 @@ GTEST_TEST(random_access_iterator, operator_post_increment) (it++).operator->() == &arr[2], *it == arr[3], (it++).operator->() == &arr[3], - *it == arr[4]}; + *it == arr[4] + }; hud::random_access_iterator it_const(arr_const); const auto const_it = std::tuple { it_const.operator->() == &arr_const[0], @@ -249,10 +255,12 @@ GTEST_TEST(random_access_iterator, operator_post_increment) (it_const++).operator->() == &arr_const[2], *it_const == arr_const[3], (it_const++).operator->() == &arr_const[3], - *it_const == arr_const[4]}; + *it_const == arr_const[4] + }; return std::tuple { mutable_it, - const_it}; + const_it + }; }; // Non constant @@ -328,17 +336,20 @@ GTEST_TEST(random_access_iterator, operator_increment_assign) it.operator->() == &arr[0], *it == arr[0], (it += 1).operator->() == &arr[1], - *it == arr[1]}; + *it == arr[1] + }; hud::random_access_iterator it_const(arr_const); const auto const_it = std::tuple { it_const.operator->() == &arr_const[0], *it_const == arr_const[0], (it_const += 1).operator->() == &arr_const[1], - *it_const == arr_const[1]}; + *it_const == arr_const[1] + }; return std::tuple { mutable_it, - const_it}; + const_it + }; }; // Non constant @@ -391,7 +402,8 @@ GTEST_TEST(random_access_iterator, operator_increment) it.operator->() == &arr[0], *it == arr[0], res_it.operator->() == &arr[1], - *res_it == arr[1]}; + *res_it == arr[1] + }; hud::random_access_iterator it_const(arr_const); hud::random_access_iterator res_it_const = it_const + 1; @@ -399,10 +411,12 @@ GTEST_TEST(random_access_iterator, operator_increment) it_const.operator->() == &arr_const[0], *it_const == arr[0], res_it_const.operator->() == &arr_const[1], - *res_it_const == arr_const[1]}; + *res_it_const == arr_const[1] + }; return std::tuple { mutable_it, - const_it}; + const_it + }; }; // Non constant @@ -460,7 +474,8 @@ GTEST_TEST(random_access_iterator, operator_pre_decrement) (--it).operator->() == &arr[1], *it == arr[1], (--it).operator->() == &arr[0], - *it == arr[0]}; + *it == arr[0] + }; hud::random_access_iterator it_const(arr_const, 4); const auto const_it = std::tuple { it_const.operator->() == &arr_const[4], @@ -472,10 +487,12 @@ GTEST_TEST(random_access_iterator, operator_pre_decrement) (--it_const).operator->() == &arr_const[1], *it_const == arr_const[1], (--it_const).operator->() == &arr_const[0], - *it_const == arr_const[0]}; + *it_const == arr_const[0] + }; return std::tuple { mutable_it, - const_it}; + const_it + }; }; // Non constant @@ -557,7 +574,8 @@ GTEST_TEST(random_access_iterator, operator_post_decrement) (it--).operator->() == &arr[2], *it == arr[1], (it--).operator->() == &arr[1], - *it == arr[0]}; + *it == arr[0] + }; hud::random_access_iterator it_const(arr_const, 4); const auto const_it = std::tuple { it_const.operator->() == &arr_const[4], @@ -569,10 +587,12 @@ GTEST_TEST(random_access_iterator, operator_post_decrement) (it_const--).operator->() == &arr_const[2], *it_const == arr_const[1], (it_const--).operator->() == &arr_const[1], - *it_const == arr_const[0]}; + *it_const == arr_const[0] + }; return std::tuple { mutable_it, - const_it}; + const_it + }; }; // Non constant @@ -648,17 +668,20 @@ GTEST_TEST(random_access_iterator, operator_decrement_assign) it.operator->() == &arr[4], *it == arr[4], (it -= 1).operator->() == &arr[3], - *it == arr[3]}; + *it == arr[3] + }; hud::random_access_iterator it_const(arr_const, 4); const auto const_it = std::tuple { it_const.operator->() == &arr_const[4], *it_const == arr_const[4], (it_const -= 1).operator->() == &arr_const[3], - *it_const == arr_const[3]}; + *it_const == arr_const[3] + }; return std::tuple { mutable_it, - const_it}; + const_it + }; }; // Non constant @@ -711,7 +734,8 @@ GTEST_TEST(random_access_iterator, operator_decrement) it.operator->() == &arr[4], *it == arr[4], res_it.operator->() == &arr[3], - *res_it == arr[3]}; + *res_it == arr[3] + }; hud::random_access_iterator it_const(arr_const, 4); hud::random_access_iterator res_it_const = it_const - 1; @@ -719,10 +743,12 @@ GTEST_TEST(random_access_iterator, operator_decrement) it_const.operator->() == &arr_const[4], *it_const == arr[4], res_it_const.operator->() == &arr_const[3], - *res_it_const == arr_const[3]}; + *res_it_const == arr_const[3] + }; return std::tuple { mutable_it, - const_it}; + const_it + }; }; // Non constant @@ -774,7 +800,8 @@ GTEST_TEST(random_access_iterator, equal_operator) it == it_same, it == it_not_same, it != it_not_same, - it != it_same}; + it != it_same + }; }; // Non constant diff --git a/test/math.cpp b/test/math.cpp new file mode 100644 index 0000000..2884ddc --- /dev/null +++ b/test/math.cpp @@ -0,0 +1,83 @@ +#include + +GTEST_TEST(math, limits) +{ + hud_assert_eq(hud::limits::max, std::numeric_limits::max()); + hud_assert_eq(hud::limits::min, std::numeric_limits::min()); + hud_assert_eq(hud::limits::max, std::numeric_limits::max()); + hud_assert_eq(hud::limits::min, std::numeric_limits::min()); + hud_assert_eq(hud::limits::max, std::numeric_limits::max()); + hud_assert_eq(hud::limits::min, std::numeric_limits::min()); + hud_assert_eq(hud::limits::max, std::numeric_limits::max()); + hud_assert_eq(hud::limits::min, std::numeric_limits::min()); + + hud_assert_eq(hud::limits::max, std::numeric_limits::max()); + hud_assert_eq(hud::limits::min, std::numeric_limits::min()); + hud_assert_eq(hud::limits::max, std::numeric_limits::max()); + hud_assert_eq(hud::limits::min, std::numeric_limits::min()); + hud_assert_eq(hud::limits::max, std::numeric_limits::max()); + hud_assert_eq(hud::limits::min, std::numeric_limits::min()); + hud_assert_eq(hud::limits::max, std::numeric_limits::max()); + hud_assert_eq(hud::limits::min, std::numeric_limits::min()); + + hud_assert_eq(hud::limits::max, std::numeric_limits::max()); + hud_assert_eq(hud::limits::min, std::numeric_limits::min()); + + hud_assert_eq(hud::limits::max, std::numeric_limits::max()); + hud_assert_eq(hud::limits::min, std::numeric_limits::min()); + + hud_assert_eq(hud::limits::max, std::numeric_limits::max()); + hud_assert_eq(hud::limits::min, std::numeric_limits::min()); + + hud_assert_eq(hud::limits::max, std::numeric_limits::max()); + hud_assert_eq(hud::limits::min, std::numeric_limits::min()); + + hud_assert_eq(hud::limits::max, std::numeric_limits::max()); + hud_assert_eq(hud::limits::min, std::numeric_limits::lowest()); + hud_assert_eq(hud::f32_min_positive, std::numeric_limits::min()); + hud_assert_eq(hud::limits::max, std::numeric_limits::max()); + hud_assert_eq(hud::limits::min, std::numeric_limits::lowest()); + hud_assert_eq(hud::f64_min_positive, std::numeric_limits::min()); + + hud_assert_eq(hud::limits::max, std::numeric_limits::max()); + hud_assert_eq(hud::limits::min, std::numeric_limits::min()); + hud_assert_eq(hud::limits::max, std::numeric_limits::max()); + hud_assert_eq(hud::limits::min, std::numeric_limits::min()); + + hud_assert_eq(hud::limits::max, std::numeric_limits::max()); + hud_assert_eq(hud::limits::min, std::numeric_limits::min()); + hud_assert_eq(hud::limits::max, std::numeric_limits::max()); + hud_assert_eq(hud::limits::min, std::numeric_limits::min()); + +#if HD_INTRINSIC_INT128_SUPPORTED + hud_assert_eq(hud::limits::max, std::numeric_limits<__int128>::max()); + hud_assert_eq(hud::limits::min, std::numeric_limits<__int128>::min()); + hud_assert_eq(hud::limits::max, std::numeric_limits::max()); + hud_assert_eq(hud::limits::min, std::numeric_limits::min()); + +#endif +} + +GTEST_TEST(math, is_finite) +{ + hud_assert_true(hud::math::is_finite((f32)0.0f)); + hud_assert_true(hud::math::is_finite((f64)0.0)); + hud_assert_true(hud::math::is_finite((f32)1.2f)); + hud_assert_true(hud::math::is_finite((f64)1.2)); + + // Log(0) == infinite + hud_assert_false(hud::math::is_finite(hud::math::log((f32)0.0f))); + hud_assert_false(hud::math::is_finite(hud::math::log((f64)0.0))); + + // sqrt (-1) == NaN + hud_assert_false(hud::math::is_finite(hud::math::sqrt((f32)-1.f))); + hud_assert_false(hud::math::is_finite(hud::math::sqrt((f64)-1.0))); +} + +GTEST_TEST(math, log) +{ +} + +GTEST_TEST(math, sqrt) +{ +} \ No newline at end of file diff --git a/test/optional/optional_misc.cpp b/test/optional/optional_misc.cpp index 01f09a3..61896e0 100644 --- a/test/optional/optional_misc.cpp +++ b/test/optional/optional_misc.cpp @@ -1,5 +1,5 @@ #include -#include +#include GTEST_TEST(optional, less_or_equal_size_as_std_optional) { @@ -157,7 +157,8 @@ GTEST_TEST(optional, value_or) hud::move(option_empty).value_or(type {456, nullptr}).id(), hud::move(option_non_empty).value_or(type {456, nullptr}).id(), hud::move(const_option_empty).value_or(type {456, nullptr}).id(), - hud::move(const_option_non_empty).value_or(type {456, nullptr}).id()}; + hud::move(const_option_non_empty).value_or(type {456, nullptr}).id() + }; }; // Non constant @@ -198,7 +199,8 @@ GTEST_TEST(optional, operator_arrow) const hud::optional const_option {hud::in_place, 456, nullptr}; return std::tuple { option->id(), - const_option->id()}; + const_option->id() + }; }; // Non constant @@ -227,7 +229,8 @@ GTEST_TEST(optional, operator_dereference) const hud::optional const_option {hud::in_place, 456, nullptr}; return std::tuple { (*option).id(), - (*const_option).id()}; + (*const_option).id() + }; }; // Non constant @@ -298,7 +301,8 @@ GTEST_TEST(optional, reset_call_destructor_if_T_is_not_trivially_destructible) has_value_before, destructor_count_before, option.has_value(), - destructor_count}; + destructor_count + }; }; // Non constant diff --git a/test/types.cpp b/test/types.cpp index 223d4d7..8f66ea7 100644 --- a/test/types.cpp +++ b/test/types.cpp @@ -23,6 +23,9 @@ GTEST_TEST(types, size) { hud_assert_eq(sizeof(wchar), 4u); } + hud_assert_eq(sizeof(char16), 2u); + hud_assert_eq(sizeof(char32), 4u); + hud_assert_eq(sizeof(f32), 4u); hud_assert_eq(sizeof(f64), 8u); @@ -40,6 +43,9 @@ GTEST_TEST(types, size) hud_assert_eq(sizeof(isize), 4u); hud_assert_eq(sizeof(usize), 4u); } + + hud_assert_eq(sizeof(i128), 16u); + hud_assert_eq(sizeof(u128), 16u); } GTEST_TEST(types, signed_unsigned) @@ -59,12 +65,16 @@ GTEST_TEST(types, signed_unsigned) #else // HD_OS_LINUX hud_assert_true(hud::is_signed_v); #endif + hud_assert_true(hud::is_unsigned_v); + hud_assert_true(hud::is_unsigned_v); hud_assert_true(hud::is_signed_v); hud_assert_true(hud::is_signed_v); hud_assert_true(hud::is_signed_v); hud_assert_true(hud::is_unsigned_v); hud_assert_true(hud::is_signed_v); hud_assert_true(hud::is_unsigned_v); + hud_assert_true(hud::is_signed_v); + hud_assert_true(hud::is_unsigned_v); } GTEST_TEST(types, limits) @@ -93,6 +103,12 @@ GTEST_TEST(types, limits) hud_assert_eq(hud::wchar_max, std::numeric_limits::max()); hud_assert_eq(hud::wchar_min, std::numeric_limits::min()); + hud_assert_eq(hud::char16_max, std::numeric_limits::max()); + hud_assert_eq(hud::char16_min, std::numeric_limits::min()); + + hud_assert_eq(hud::char32_max, std::numeric_limits::max()); + hud_assert_eq(hud::char32_min, std::numeric_limits::min()); + hud_assert_eq(hud::f32_max, std::numeric_limits::max()); hud_assert_eq(hud::f32_min, std::numeric_limits::lowest()); hud_assert_eq(hud::f32_min_positive, std::numeric_limits::min()); diff --git a/test/u128.cpp b/test/u128.cpp index d4e8fb5..a9f90cc 100644 --- a/test/u128.cpp +++ b/test/u128.cpp @@ -1,4 +1,4 @@ -#include +#include // std::nextafter, std::ldexp GTEST_TEST(u128, default_constructor) { @@ -106,7 +106,7 @@ GTEST_TEST(u128, constructor_f32) // Init to min positive value { - f64 value = hud::f32_min_positive; + f32 value = hud::f32_min_positive; // Check value is not NaN or infinite hud_assert_true(std::isfinite(value)); // Ensure we are positive @@ -120,8 +120,8 @@ GTEST_TEST(u128, constructor_f32) // Init to max value { - // Compute the greatest value just before 2^128 - f32 value = std::nextafterf(std::numeric_limits::max(), 0.0); + // Compute the greatest value + f32 value = hud::f32_max; hud::u128 v {value}; // Check value is not NaN or infinite diff --git a/test/u128/u128_assign.cpp b/test/u128/u128_assign.cpp new file mode 100644 index 0000000..3623ba6 --- /dev/null +++ b/test/u128/u128_assign.cpp @@ -0,0 +1,255 @@ +#include // std::isfinite, std::nextafter,std::ldexp +#include + +GTEST_TEST(u128, assign_i8) +{ + // Init to 0 + { + hud::u128 v {hud::u128_max}; + v = i8 {}; + hud_assert_eq(v, (i8 {})); + } + + // Init to min value + { + hud::u128 v {hud::u128_max}; + v = hud::i8_min; + hud_assert_eq(v, hud::i8_min); + } + + // Init to max value + { + hud::u128 v {hud::u128_max}; + v = hud::i8_max; + hud_assert_eq(v, hud::i8_max); + } +} + +GTEST_TEST(u128, assign_i16) +{ + // Init to 0 + { + hud::u128 v {hud::u128_max}; + v = i16 {}; + hud_assert_eq(v, i16 {}); + } + + // Init to min value + { + hud::u128 v {hud::u128_max}; + v = hud::i16_min; + hud_assert_eq(v, hud::i16_min); + } + + // Init to max value + { + hud::u128 v {hud::u128_max}; + v = hud::i16_max; + hud_assert_eq(v, hud::i16_max); + } +} + +GTEST_TEST(u128, assign_i32) +{ + // Init to 0 + { + hud::u128 v {hud::u128_max}; + v = i32 {}; + hud_assert_eq(v, i32 {}); + } + + // Init to min value + { + hud::u128 v {hud::u128_max}; + v = hud::i32_min; + hud_assert_eq(v, hud::i32_min); + } + + // Init to max value + { + hud::u128 v {hud::u128_max}; + v = hud::i32_max; + hud_assert_eq(v, hud::i32_max); + } +} + +GTEST_TEST(u128, assign_i64) +{ + // Init to 0 + { + hud::u128 v {hud::u128_max}; + v = i64 {}; + hud_assert_eq(v, i64 {}); + } + + // Init to min value + { + hud::u128 v {hud::u128_max}; + v = hud::i64_min; + hud_assert_eq(v, hud::i64_min); + } + + // Init to max value + { + hud::u128 v {hud::u128_max}; + v = hud::i64_max; + hud_assert_eq(v, hud::i64_max); + } +} + +GTEST_TEST(u128, assign_f32) +{ + // Init to 0 + { + hud::u128 v {hud::u128_max}; + v = f32 {}; + hud_assert_eq((float)v, f32 {}); + } + + // Init to min positive value + { + f32 value = hud::f32_min_positive; + hud::u128 v {hud::u128_max}; + v = value; + // Cast to u32 because f32_min is the lowest positive value of an f32 + hud_assert_eq(static_cast(v), static_cast(value)); + } + + // Init to max value + { + // Compute the greatest value just before 2^128 + f32 value = std::nextafterf(std::numeric_limits::max(), 0.0); + + hud::u128 v {hud::u128_max}; + v = value; + hud_assert_eq(static_cast(v), value); + } +} + +GTEST_TEST(u128, assign_f64) +{ + // Init to 0 + { + hud::u128 v {hud::u128_max}; + v = f64 {}; + hud_assert_eq((float)v, f64 {}); + } + + // Init to min positive value + { + f64 value = hud::f64_min_positive; + + hud::u128 v {hud::u128_max}; + v = value; + hud_assert_eq(static_cast(v), static_cast(hud::f64_min)); + } + + // Init to big value + { + // Compute the greatest value just before 2^128 + f64 value = std::nextafter(std::ldexp(1.0, 128), 0.0); + + hud::u128 v {hud::u128_max}; + v = value; + hud_assert_eq(static_cast(v), value); + } +} + +GTEST_TEST(u128, assign_u128) +{ + // Init to 0 + { + hud::u128 v {hud::u128_max}; + v = hud::u128 {0}; + hud_assert_eq(v, hud::u128 {0}); + } + + // Init to min value + { + hud::u128 v {0}; + v = hud::u128_min; + hud_assert_eq(v, hud::u128_min); + } + + // Init to max value + { + hud::u128 v {0}; + v = hud::u128_max; + hud_assert_eq(v, hud::u128_max); + } +} + +GTEST_TEST(u128, assign_i128) +{ + // Init to 0 + { + hud::u128 v {hud::u128_max}; + v = hud::i128 {0}; + hud_assert_eq(v, static_cast(hud::i128 {0})); + } + + // Init to min value + { + hud::u128 v {0}; + v = hud::i128 {hud::i128_min}; + hud_assert_eq(v, static_cast(hud::i128_min)); + } + + // Init to max value + { + hud::u128 v {0}; + v = hud::i128 {hud::i128_max}; + hud_assert_eq(v, static_cast(hud::i128_max)); + } +} + +#if defined(HD_INTRINSIC_INT128_SUPPORTED) +GTEST_TEST(u128, assign__int128) +{ + // Init to 0 + { + hud::u128 v {hud::u128_max}; + v = __int128 {0}; + hud_assert_eq(v, static_cast(hud::i128 {0})); + } + + // Init to min value + { + hud::u128 v {0}; + v = __int128 {hud::i128_min}; + hud_assert_eq(v, static_cast(hud::i128_min)); + } + + // Init to max value + { + hud::u128 v {0}; + v = __int128 {hud::i128_max}; + hud_assert_eq(v, static_cast(hud::i128_max)); + } +} + +GTEST_TEST(u128, assign_unsigned__int128) +{ + // Init to 0 + { + hud::u128 v {hud::u128_max}; + v = (unsigned __int128) {0}; + hud_assert_eq(v, static_cast(hud::i128 {0})); + } + + // Init to min value + { + hud::u128 v {0}; + v = (unsigned __int128) {hud::u128_min}; + hud_assert_eq(v, hud::u128_min); + } + + // Init to max value + { + hud::u128 v {0}; + v = (unsigned __int128) {hud::u128_max}; + hud_assert_eq(v, hud::u128_max); + } +} + +#endif \ No newline at end of file diff --git a/test/u128/u128_cast.cpp b/test/u128/u128_cast.cpp index 36fd40f..9858892 100644 --- a/test/u128/u128_cast.cpp +++ b/test/u128/u128_cast.cpp @@ -1,15 +1,23 @@ +#include // std::nextafter, std::ldexp + GTEST_TEST(u128, cast) { const auto lambda = []() { - u128 v {hud::math::limits::max}; + u128 v {hud::limits::max}; type_t result = static_cast(v); - hud_assert_eq(result, hud::math::limits::max); + hud_assert_eq(result, hud::limits::max); }; - hud_test::for_each_type()(lambda); + hud_test::for_each_type()(lambda); #if HD_INTRINSIC_INT128_SUPPORTED hud_test::for_each_type<__int128, unsigned __int128>()(lambda); #endif + + // Test cast max f64 + f64 max_f64_fit_in_u128 = std::nextafter(std::ldexp(1.0, 128), 0.0); + u128 v {max_f64_fit_in_u128}; + f64 result = static_cast(v); + hud_assert_eq(result, max_f64_fit_in_u128); } \ No newline at end of file diff --git a/test/u128/u128_comparisons.cpp b/test/u128/u128_comparisons.cpp new file mode 100644 index 0000000..e94583c --- /dev/null +++ b/test/u128/u128_comparisons.cpp @@ -0,0 +1,40 @@ + +GTEST_TEST(u128, operator_equal) +{ + hud_assert_true(hud::u128 {0} == hud::u128 {0}); + hud_assert_false(hud::u128 {0} == hud::u128 {1}); +} + +GTEST_TEST(u128, operator_not_equal) +{ + hud_assert_false(hud::u128 {0} != hud::u128 {0}); + hud_assert_true(hud::u128 {0} != hud::u128 {1}); +} + +GTEST_TEST(u128, operator_less) +{ + hud_assert_false(hud::u128 {0} < hud::u128 {0}); + hud_assert_true(hud::u128 {0} < hud::u128 {1}); + hud_assert_false(hud::u128 {1} < hud::u128 {0}); +} + +GTEST_TEST(u128, operator_less_equal) +{ + hud_assert_true(hud::u128 {0} <= hud::u128 {0}); + hud_assert_true(hud::u128 {0} <= hud::u128 {1}); + hud_assert_false(hud::u128 {1} <= hud::u128 {0}); +} + +GTEST_TEST(u128, operator_greater) +{ + hud_assert_false(hud::u128 {0} > hud::u128 {0}); + hud_assert_false(hud::u128 {0} > hud::u128 {1}); + hud_assert_true(hud::u128 {1} > hud::u128 {0}); +} + +GTEST_TEST(u128, operator_greater_equal) +{ + hud_assert_true(hud::u128 {0} >= hud::u128 {0}); + hud_assert_false(hud::u128 {0} >= hud::u128 {1}); + hud_assert_true(hud::u128 {1} >= hud::u128 {0}); +} \ No newline at end of file diff --git a/test/u128/u128_constructors.cpp b/test/u128/u128_constructors.cpp index 93ef245..1e9f975 100644 --- a/test/u128/u128_constructors.cpp +++ b/test/u128/u128_constructors.cpp @@ -262,8 +262,7 @@ GTEST_TEST(u128, constructor_unsigned__int128) { // Init to 0 { - unsigned __int128 value {0}; - hud::u128 v {value}; + hud::u128 v {(unsigned __int128) {0}}; hud_assert_eq(v, static_cast(hud::i128 {0})); } diff --git a/test/unique_pointer/array/unique_pointer_array_misc.cpp b/test/unique_pointer/array/unique_pointer_array_misc.cpp index 12db19b..f0e82e7 100644 --- a/test/unique_pointer/array/unique_pointer_array_misc.cpp +++ b/test/unique_pointer/array/unique_pointer_array_misc.cpp @@ -1,4 +1,5 @@ #include +#include #include // LCOV_EXCL_START diff --git a/test/unique_pointer/single/unique_pointer_single_misc.cpp b/test/unique_pointer/single/unique_pointer_single_misc.cpp index 397c0a3..cba6c9e 100644 --- a/test/unique_pointer/single/unique_pointer_single_misc.cpp +++ b/test/unique_pointer/single/unique_pointer_single_misc.cpp @@ -1,4 +1,5 @@ #include +#include // LCOV_EXCL_START namespace hud_test