8#if !((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L)
9#error "C++17 support was not detected."
14static_assert(CHAR_BIT == 8,
"CHAR_BIT must be 8");
18static_assert(std::numeric_limits<float>::is_iec559,
"IEEE 754 not supported");
41#define NNL_PACK(...) __VA_ARGS__ __attribute__((__packed__))
45#define NNL_PACK(...) __pragma(pack(push, 1)) __VA_ARGS__ __pragma(pack(pop))
57using u64 = std::uint64_t;
58using i64 = std::int64_t;
60using u32 = std::uint32_t;
61using i32 = std::int32_t;
62using u16 = std::uint16_t;
63using i16 = std::int16_t;
64using u8 = std::uint8_t;
65using i8 = std::int8_t;
75 static_assert(std::is_trivially_copyable_v<T>);
78 static constexpr std::size_t length()
noexcept {
return 4; }
82 constexpr Vec4()
noexcept =
default;
84 constexpr Vec4(T x, T y, T z, T w) noexcept : x(x), y(y), z(z), w(w) {}
86 constexpr Vec4(T val) noexcept : x(val), y(val), z(val), w(val) {}
89 constexpr explicit Vec4(
const Vec4<A>& vec)
noexcept {
90 x =
static_cast<T
>(vec.x);
91 y =
static_cast<T
>(vec.y);
92 z =
static_cast<T
>(vec.z);
93 w =
static_cast<T
>(vec.w);
96 constexpr bool operator==(
const Vec4& rhs)
const noexcept {
97 return (x == rhs.x) && (y == rhs.y) && (z == rhs.z) && (w == rhs.w);
100 constexpr bool operator!=(
const Vec4& rhs)
const noexcept {
return !(this->operator==(rhs)); }
102 constexpr const T& operator[](std::size_t i)
const {
103 assert(i < length());
104 return this->*kMembers[i];
107 constexpr T& operator[](std::size_t i) {
108 assert(i < length());
109 return this->*kMembers[i];
113 using Members = T
Vec4::*
const[length()];
115 static inline constexpr Members kMembers{&Vec4::x, &Vec4::y, &Vec4::z, &Vec4::w};
125 static_assert(std::is_trivially_copyable_v<T>);
128 static constexpr std::size_t length()
noexcept {
return 3; }
130 using value_type = T;
132 constexpr Vec3() noexcept = default;
134 constexpr Vec3(T x, T y, T z) noexcept : x(x), y(y), z(z) {}
136 constexpr Vec3(T val) noexcept : x(val), y(val), z(val) {}
138 template <
typename A>
139 constexpr explicit Vec3(
const Vec3<A>& vec)
noexcept {
140 x =
static_cast<T
>(vec.x);
141 y =
static_cast<T
>(vec.y);
142 z =
static_cast<T
>(vec.z);
145 constexpr bool operator==(
const Vec3& rhs)
const noexcept {
return (x == rhs.x) && (y == rhs.y) && (z == rhs.z); }
147 constexpr bool operator!=(
const Vec3& rhs)
const noexcept {
return !(this->operator==(rhs)); }
149 constexpr const T& operator[](std::size_t i)
const {
150 assert(i < length());
151 return this->*kMembers[i];
154 constexpr T& operator[](std::size_t i) {
155 assert(i < length());
156 return this->*kMembers[i];
160 using Members = T
Vec3::*
const[length()];
162 static inline constexpr Members kMembers{&Vec3::x, &Vec3::y, &Vec3::z};
172 static_assert(std::is_trivially_copyable_v<T>);
175 static constexpr std::size_t length()
noexcept {
return 2; }
177 using value_type = T;
179 constexpr Vec2() noexcept = default;
181 constexpr Vec2(T x, T y) noexcept : x(x), y(y) {}
183 constexpr Vec2(T val) noexcept : x(val), y(val) {}
185 template <
typename A>
186 constexpr explicit Vec2(
const Vec2<A>& vec)
noexcept {
187 x =
static_cast<T
>(vec.x);
188 y =
static_cast<T
>(vec.y);
191 constexpr bool operator==(
const Vec2& rhs)
const noexcept {
return (x == rhs.x) && (y == rhs.y); }
193 constexpr bool operator!=(
const Vec2& rhs)
const noexcept {
return !(this->operator==(rhs)); }
195 constexpr const T& operator[](std::size_t i)
const {
196 assert(i < length());
197 return this->*kMembers[i];
200 constexpr T& operator[](std::size_t i) {
201 assert(i < length());
202 return this->*kMembers[i];
206 using Members = T
Vec2::*
const[length()];
208 static inline constexpr Members kMembers{&Vec2::x, &Vec2::y};
217static_assert(
sizeof(
Vec4<u8>) == 0x4);
219static_assert(
sizeof(
Vec4<i8>) == 0x4);
229static_assert(
sizeof(
Vec3<i8>) == 0x3);
231static_assert(
sizeof(
Vec3<u8>) == 0x3);
235static_assert(
sizeof(
Vec2<i8>) == 0x2);
237static_assert(
sizeof(
Vec2<u8>) == 0x2);
250 static_assert(std::is_trivially_copyable_v<T>);
254 static constexpr std::size_t length()
noexcept {
return 4; }
256 using value_type = Vec4<T>;
258 constexpr Mat4() noexcept = default;
260 constexpr Mat4(Vec4<T> r0, Vec4<T> r1, Vec4<T> r2, Vec4<T> r3) noexcept : r0(r0), r1(r1), r2(r2), r3(r3) {}
262 constexpr bool operator==(
const Mat4& rhs)
const noexcept {
263 return (r0 == rhs.r0) && (r1 == rhs.r1) && (r2 == rhs.r2) && (r3 == rhs.r3);
266 constexpr bool operator!=(
const Mat4& rhs)
const noexcept {
return !(*
this == rhs); }
268 constexpr const Vec4<T>& operator[](std::size_t i)
const {
269 assert(i < length());
270 return this->*kMembers[i];
273 constexpr Vec4<T>& operator[](std::size_t i) {
274 assert(i < length());
275 return this->*kMembers[i];
281 static inline constexpr Members kMembers{&Mat4::r0, &Mat4::r1, &Mat4::r2, &Mat4::r3};
4D vector template with packed storage
Definition fixed_type.hpp:116
4x4 matrix template with packed storage
Definition fixed_type.hpp:282
2D vector template with packed storage
Definition fixed_type.hpp:209
3D vector template with packed storage
Definition fixed_type.hpp:163
std::uint16_t u16
16-bit unsigned integer
Definition fixed_type.hpp:62
std::int32_t i32
32-bit signed integer
Definition fixed_type.hpp:61
std::int16_t i16
16-bit signed integer
Definition fixed_type.hpp:63
std::int8_t i8
8-bit signed integer
Definition fixed_type.hpp:65
std::uint64_t u64
64-bit unsigned integer
Definition fixed_type.hpp:57
float f32
32-bit floating point
Definition fixed_type.hpp:59
std::uint32_t u32
32-bit unsigned integer
Definition fixed_type.hpp:60
std::uint8_t u8
8-bit unsigned integer
Definition fixed_type.hpp:64
std::int64_t i64
64-bit signed integer
Definition fixed_type.hpp:58
#define NNL_PACK(...)
A structure packing directive.
Definition fixed_type.hpp:41
Definition exception.hpp:56