Files
OpenVulkano/openVulkanoCpp/Math/UInt24.hpp
Vladyslav Baranovskyi 9f39ecbe80 UInt24 class
2024-11-10 19:46:32 +02:00

166 lines
4.5 KiB
C++

/*
* 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 <cinttypes>
#include <type_traits>
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<typename T, std::enable_if_t<std::is_convertible_v<T, int>, bool> = true> \
uint24 operator op(const T& val) const { return uint24( (int)*this op static_cast<int>(val) ); } \
template<typename T, std::enable_if_t<std::is_convertible_v<T, int>, bool> = true> \
uint24& operator op##=(const T& val ) { *this = *this op static_cast<int>(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<typename T, std::enable_if_t<std::is_convertible_v<T, int>, bool> = true>
[[nodiscard]] bool operator==(const T& val) const
{
return static_cast<int>(*this) == static_cast<int>(val);
}
template<typename T, std::enable_if_t<std::is_convertible_v<T, int>, bool> = true>
[[nodiscard]] constexpr auto operator<=>(const T& other) const
{
return operator int() <=> static_cast<int>(other);
}
template<typename Key> friend
struct std::hash;
};
}
namespace std
{
template<>
struct hash<OpenVulkano::uint24>
{
std::size_t operator()(const OpenVulkano::uint24& value) const
{
return hash<int>()(static_cast<int>(value));
}
};
template <>
class numeric_limits<OpenVulkano::uint24>
{
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); }
};
}