diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2024-01-13 01:09:20 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2024-01-13 02:29:09 +0100 |
commit | eb2766a55358d1724ace532231892facd8fe2d75 (patch) | |
tree | 8c1649b5ff7121aa70ad00d2736c4ac6c5c5cba8 /serialize | |
parent | aeb346ea244f15faf75b948de6fdf33c1431a6b1 (diff) |
w
Diffstat (limited to 'serialize')
-rw-r--r-- | serialize/packbits.cpp | 41 | ||||
-rw-r--r-- | serialize/packbits.hpp | 29 |
2 files changed, 47 insertions, 23 deletions
diff --git a/serialize/packbits.cpp b/serialize/packbits.cpp index 12f80791..976e7f6e 100644 --- a/serialize/packbits.cpp +++ b/serialize/packbits.cpp @@ -1,4 +1,5 @@ #include "packbits.hpp" +#include "compat/assert.hpp" namespace floormat { @@ -8,15 +9,37 @@ namespace { constexpr bool test1() { - using S1 = Storage<uint8_t, 8>; - S1 st1{0b10111011}; - fm_assert(st1.value == 0b10111011); - - fm_assert(st1.get<3>() == 0b011); - using S2 = typename S1::next<3>; - S2 st2{st1.advance<3>()}; - static_assert(std::is_same_v<S2, Storage<uint8_t, 5>>); - fm_assert(st2.value == 0b10111); + constexpr size_t left[] = { 8, 3, 2, 1, 0 }; + constexpr size_t rest[] = { 0, 5, 6, 7, 8 }; + constexpr size_t bits[] = { 5, 2, 1, 1 }; + constexpr size_t vals[] = { 8, 3, 1, 0 }; + constexpr auto S0 = Storage<uint8_t, left[0]>{0b10111011uz}; + constexpr auto S1 = Storage<uint8_t, left[1]>{0b00000101uz}; + constexpr auto S2 = Storage<uint8_t, left[2]>{0b00000010uz}; + constexpr auto S3 = Storage<uint8_t, left[3]>{0b00000001uz}; + constexpr auto S4 = Storage<uint8_t, left[4]>{0b00000000uz}; + static_assert(S0.Capacity == 8 - rest[0]); + static_assert(S1.Capacity == 8 - rest[1]); + static_assert(S2.Capacity == 8 - rest[2]); + static_assert(S3.Capacity == 8 - rest[3]); + static_assert(S4.Capacity == 8 - rest[4]); + static_assert(S0.advance<left[0] - left[1]>() == S1.value); + static_assert(S1.advance<left[1] - left[2]>() == S2.value); + static_assert(S2.advance<left[2] - left[3]>() == S3.value); + static_assert(S3.advance<left[3] - left[4]>() == S4.value); + using P0 = std::decay_t<decltype(S0)>; + using P1 = P0::next<bits[0]>; + using P2 = P1::next<bits[1]>; + using P3 = P2::next<bits[2]>; + static_assert(P0::Capacity == vals[0]); + static_assert(P1::Capacity == vals[1]); + static_assert(P2::Capacity == vals[2]); + static_assert(P3::Capacity == vals[3]); + static_assert(std::is_same_v<P1, Storage<uint8_t, vals[1]>>); + static_assert(std::is_same_v<P2, Storage<uint8_t, vals[2]>>); + static_assert(std::is_same_v<P3, Storage<uint8_t, vals[3]>>); + static_assert(std::is_same_v<P4, Storage<uint8_t, vals[4]>>); + return true; } diff --git a/serialize/packbits.hpp b/serialize/packbits.hpp index 6e388846..41e15177 100644 --- a/serialize/packbits.hpp +++ b/serialize/packbits.hpp @@ -1,5 +1,4 @@ #pragma once -#include "compat/assert.hpp" #include <type_traits> #include <concepts> @@ -29,14 +28,15 @@ struct check_size_overflow<T, Sum> static constexpr bool result = Sum <= sizeof(T)*8; }; -template<std::unsigned_integral T, size_t Capacity> +template<std::unsigned_integral T, size_t CAPACITY> struct Storage { - static_assert(Capacity <= sizeof(T)*8); + static_assert(CAPACITY <= sizeof(T)*8); + static constexpr size_t Capacity = CAPACITY; T value; template<size_t N> - constexpr T get() + constexpr T get() const { static_assert(N <= sizeof(T)*8); static_assert(N <= Capacity); @@ -44,37 +44,38 @@ struct Storage } template<size_t N> - constexpr T advance() + constexpr T advance() const { static_assert(N <= sizeof(T)*8); static_assert(N <= Capacity); return T(value >> N); } - template<size_t N> [[maybe_unused]] constexpr bool check_zero() = delete; + constexpr bool operator==(const Storage&) const noexcept = default; + constexpr bool check_zero() const = delete; - template<size_t N> - using next = Storage<T, Capacity - N>; + template<size_t N> using next = Storage<T, Capacity - N>; }; template<std::unsigned_integral T> struct Storage<T, 0> { + static constexpr size_t Capacity = 0; T value; - template<size_t N> [[maybe_unused]] constexpr T get() = delete; - template<size_t N> [[maybe_unused]] constexpr T advance() = delete; + template<size_t N> [[maybe_unused]] constexpr T get() const = delete; + template<size_t N> [[maybe_unused]] constexpr T advance() const = delete; + constexpr bool operator==(const Storage&) const noexcept = default; - template<size_t N> constexpr inline bool check_zero() + [[nodiscard]] constexpr inline bool check_zero() const { - fm_assert(value == T(0)); - return true; + return value == T(0); } template<size_t N> struct next { static_assert(!std::is_same_v<T, void>, "reading past the end"); - static_assert( std::is_same_v<T, void>, "can't happen!"); + static_assert( std::is_same_v<T, void>, "reading past the end"); }; }; |