diff --git a/openVulkanoCpp/Math/UInt24.hpp b/openVulkanoCpp/Math/UInt24.hpp new file mode 100644 index 0000000..7a8504e --- /dev/null +++ b/openVulkanoCpp/Math/UInt24.hpp @@ -0,0 +1,166 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include +#include + +namespace OpenVulkano +{ + class uint24 final + { + uint8_t m_internal[3]; + public: + constexpr uint24() : m_internal{ 0, 0, 0 } + {} + + constexpr uint24(const int val) + : m_internal{(uint8_t)(val & 0xff), (uint8_t)((val >> 8) & 0xff), (uint8_t)((val >> 16) & 0xff)} + {} + + constexpr uint24(const uint24& val) : m_internal{ val.m_internal[0], val.m_internal[1], val.m_internal[2] } + {} + + operator int() const { return (m_internal[2] << 16) | (m_internal[1] << 8) | (m_internal[0] << 0); } + + operator float() const + { + return (float)this->operator int(); + } + + uint24& operator =(const uint24& input) + { + m_internal[0] = input.m_internal[0]; + m_internal[1] = input.m_internal[1]; + m_internal[2] = input.m_internal[2]; + return *this; + } + + uint24& operator =(const int input) + { + m_internal[0] = ((unsigned char*)&input)[0]; + m_internal[1] = ((unsigned char*)&input)[1]; + m_internal[2] = ((unsigned char*)&input)[2]; + return *this; + } + +#define INT24_OPERATORS(op) \ + template, bool> = true> \ + uint24 operator op(const T& val) const { return uint24( (int)*this op static_cast(val) ); } \ + template, bool> = true> \ + uint24& operator op##=(const T& val ) { *this = *this op static_cast(val); return *this; } + + INT24_OPERATORS(+) + INT24_OPERATORS(-) + INT24_OPERATORS(*) + INT24_OPERATORS(/) +#undef INT24_OPERATORS + + uint24 operator >>(const int val) const + { + return uint24( (int)*this >> val ); + } + + uint24 operator <<(const int val) const + { + return uint24( (int)*this << val ); + } + + uint24& operator >>=(const int val ) + { + *this = *this >> val; + return *this; + } + + uint24& operator <<=(const int val ) + { + *this = *this << val; + return *this; + } + + operator bool() const + { + return (int)*this != 0; + } + + bool operator !() const + { + return !((int)*this); + } + + uint24 operator -() + { + return uint24( -(int)*this ); + } + + template, bool> = true> + [[nodiscard]] bool operator==(const T& val) const + { + return static_cast(*this) == static_cast(val); + } + + template, bool> = true> + [[nodiscard]] constexpr auto operator<=>(const T& other) const + { + return operator int() <=> static_cast(other); + } + + template friend + struct std::hash; + }; +} + +namespace std +{ + template<> + struct hash + { + std::size_t operator()(const OpenVulkano::uint24& value) const + { + return hash()(static_cast(value)); + } + }; + + template <> + class numeric_limits + { + public: + static const bool is_specialized = true; + static constexpr OpenVulkano::uint24 min() { return OpenVulkano::uint24(0); } + static constexpr OpenVulkano::uint24 max() { return OpenVulkano::uint24(0xFFFFFF); } + static const int radix = 2; + static const int digits = 24; + static const int digits10 = 7; + static const bool is_signed = false; + static const bool is_integer = true; + static const bool is_exact = true; + static const bool traps = false; + static const bool is_modulo = true; + static const bool is_bounded = true; + + static constexpr OpenVulkano::uint24 epsilon() { return OpenVulkano::uint24(1); } + static constexpr OpenVulkano::uint24 round_error() { return OpenVulkano::uint24(0); } + static const int min_exponent10 = 0; + static const int max_exponent10 = 0; + static const int min_exponent = 0; + static const int max_exponent = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const bool is_iec559 = false; + static const bool has_denorm = false; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + + // Not meaningful for uint24... + static constexpr OpenVulkano::uint24 denorm_min() { return OpenVulkano::uint24(0); } + static constexpr OpenVulkano::uint24 infinity() { return OpenVulkano::uint24(0); } + static constexpr OpenVulkano::uint24 quiet_NaN() { return OpenVulkano::uint24(0); } + static constexpr OpenVulkano::uint24 signaling_NaN() { return OpenVulkano::uint24(0); } + }; +} \ No newline at end of file