From 6c30d003dfe391e186cc6e08bb00ec99532e5545 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Mon, 15 Jan 2024 09:33:30 +0100 Subject: a --- serialize/packbits-read.cpp | 112 ++++++++++++++++++++++++++++++++++++++++++ serialize/packbits-read.hpp | 8 +-- serialize/packbits-write.cpp | 11 +++++ serialize/packbits-write.hpp | 63 ++++++++++++++++++++---- serialize/packbits.cpp | 114 ------------------------------------------- 5 files changed, 180 insertions(+), 128 deletions(-) create mode 100644 serialize/packbits-read.cpp create mode 100644 serialize/packbits-write.cpp delete mode 100644 serialize/packbits.cpp diff --git a/serialize/packbits-read.cpp b/serialize/packbits-read.cpp new file mode 100644 index 00000000..f21a0de9 --- /dev/null +++ b/serialize/packbits-read.cpp @@ -0,0 +1,112 @@ +#include "packbits-read.hpp" +#include "compat/assert.hpp" + +namespace floormat { + +using namespace floormat::detail_Pack_input; + +namespace { + +template constexpr inline T lowbits = (T{1} << N)-T{1}; + +static_assert(!input{65535}.check_zero()); +static_assert(input{65535}.advance<16>() == 0); + +static_assert(input::next<16>{ input{65535}.advance<16>() }.check_zero()); +static_assert(input::next<16>{}.Capacity == 14); + +constexpr bool test1() +{ + constexpr size_t bits[] = { 5, 2, 1 }; + constexpr size_t vals[] = { 8, 3, 1, 0 }; + + constexpr auto S0 = input{0b10111011}; + constexpr auto S1 = input{0b00000101}; + constexpr auto S2 = input{0b00000001}; + constexpr auto S3 = input{0b00000000}; + + using P0 = std::decay_t; + using P1 = P0::next; + using P2 = P1::next; + using P3 = P2::next; + + static_assert(std::is_same_v>); + static_assert(std::is_same_v>); + static_assert(std::is_same_v>); + static_assert(std::is_same_v>); + + static_assert(S0.advance< 0>() == S0.value); + static_assert(S0.advance() == S1.value); + static_assert(S1.advance() == S2.value); + static_assert(S2.advance() == S3.value); + + static_assert(S0.get() == (S0.value & (1<() == (S1.value & (1<() == (S2.value & (1<{0b1110100110001011}; + constexpr auto S1 = input{0b1110}; + constexpr auto S2 = input{0b1}; + + static_assert(S0.get<12>() == 0b100110001011); + static_assert(S0.advance<12>() == S1.value); + + static_assert(S1.get<3>() == 0b110); + static_assert(S1.advance<3>() == S2.value); + + static_assert(S2.get<1>() == 0b1); + static_assert(S2.advance<1>() == 0); + + return true; +} +static_assert(test3()); + +static_assert(std::is_same_v< make_tuple_type, std::tuple >); + +constexpr bool test4() +{ + using Tuple_u32 = make_tuple_type; + static_assert(std::is_same_v>); + using Tuple_u8 = make_tuple_type; + { + Tuple_u32 tuple{}; + static_assert(lowbits == 0x1ffffU); + read_(tuple, input{(uint32_t)-1}, std::make_index_sequence<3>{}, make_pack{}); + auto [a, b, c] = tuple; + fm_assert(a == lowbits); + fm_assert(b == lowbits); + fm_assert(c & 1); + } + { + Tuple_u8 tuple{}; + read_(tuple, input{0b101011}, std::make_index_sequence<3>{}, make_pack{}); + auto [a, b, c] = tuple; + fm_assert(a == 0b1); + fm_assert(b == 0b101); + fm_assert(c == 0b10); + } + { + std::tuple<> empty_tuple; + read_(empty_tuple, input{0}, std::index_sequence<>{}, make_pack{}); + Tuple_u8 tuple{}; (void)tuple; + //read_(empty_tuple, input{1}, std::index_sequence<>{}, make_tuple{}); + //read_(tuple, input{0b11111}, std::make_index_sequence<3>{}, make_tuple{}); + //(void)input{}; + //read_(empty_tuple, input{}, std::index_sequence<0>{}, make_tuple{}); + //read_(empty_tuple, input{1}, std::index_sequence<>{}, make_tuple{}); + } + + return true; +} +static_assert(test4()); + +} // namespace + +} // namespace floormat diff --git a/serialize/packbits-read.hpp b/serialize/packbits-read.hpp index 67b2efcb..ff132913 100644 --- a/serialize/packbits-read.hpp +++ b/serialize/packbits-read.hpp @@ -89,7 +89,7 @@ struct input }; template -constexpr void read(Place& p, input st, std::index_sequence, empty_pack_tuple, Sizes...>) +constexpr void read_(Place& p, input st, std::index_sequence, empty_pack_tuple, Sizes...>) { static_assert(sizeof...(Is) == sizeof...(Sizes)); static_assert(Size <= Left, "data type too small"); @@ -98,18 +98,18 @@ constexpr void read(Place& p, input st, std::index_sequence, using next_type = typename S::template next; get(p) = st.template get(); T next_value = st.template advance(); - read(p, next_type{ next_value }, std::index_sequence{}, empty_pack_tuple{}); + read_(p, next_type{ next_value }, std::index_sequence{}, empty_pack_tuple{}); } template -constexpr void read(Place&, input st, std::index_sequence<>, empty_pack_tuple<>) +constexpr void read_(Place&, input st, std::index_sequence<>, empty_pack_tuple<>) { fm_assert(st.check_zero()); } template requires(sizeof...(Is) != sizeof...(Sizes)) -constexpr void read(Place&, input, std::index_sequence, empty_pack_tuple) = delete; +constexpr void read_(Place&, input, std::index_sequence, empty_pack_tuple) = delete; template using make_pack = empty_pack_tuple...>; diff --git a/serialize/packbits-write.cpp b/serialize/packbits-write.cpp new file mode 100644 index 00000000..0b4fb4f1 --- /dev/null +++ b/serialize/packbits-write.cpp @@ -0,0 +1,11 @@ +#include "packbits-write.hpp" + +namespace floormat::detail_Pack_output { + +using u32 = uint32_t; +using u8 = uint8_t; + +template u32 write_(output, output_field); +static_assert(output::next<1>::Capacity == 31); + +} // namespace floormat::detail_Pack_output diff --git a/serialize/packbits-write.hpp b/serialize/packbits-write.hpp index 34fc140f..faa3ff00 100644 --- a/serialize/packbits-write.hpp +++ b/serialize/packbits-write.hpp @@ -1,28 +1,71 @@ #pragma once +#include "compat/assert.hpp" +#include +#include #include namespace floormat::detail_Pack_output { -template +template +struct output_bits final +{ + static_assert(N > 0); + static_assert(N < sizeof(size_t)*8); + + static constexpr size_t length = N; +}; + +template struct output { - T value = 0; - uint8_t capacity = sizeof(T)*8; + static_assert(std::is_fundamental_v); + static_assert(CAPACITY <= sizeof(T)*8); + static constexpr size_t Capacity = CAPACITY; + + T value{0}; - constexpr inline output next(T x, uint8_t bits) const + template + constexpr T set(T x, output_bits) const { - fm_assert(bits > 0 && bits <= capacity); - auto val = value; - val <<= bits; - T x_ = T(x & (T{1} << bits)- T{1}); + static_assert(N <= CAPACITY, "data type too small"); + static_assert(N > 0); + T value_{value}; + if constexpr(CAPACITY != sizeof(T)*8) + value_ <<= CAPACITY; + auto x_ = T(x & (T{1}< + struct next_ + { + static_assert(N > 0); + static_assert(N <= CAPACITY); + using type = output; + }; + + template using next = typename next_::type; }; +template +using output_field = std::pair>; +template struct empty_pack_tuple {}; // todo copypasta +template +constexpr T write_(output st, output_field field, Fields... fields) +{ + T value = st.set(field.first, field.second); + using next = typename output::template next; + return write_(next{value}, fields...); +} +template +constexpr T write_(output st) +{ + return st.value; +} } // namespace floormat::detail_Pack_output diff --git a/serialize/packbits.cpp b/serialize/packbits.cpp deleted file mode 100644 index e9ce54bc..00000000 --- a/serialize/packbits.cpp +++ /dev/null @@ -1,114 +0,0 @@ -#include "packbits-read.hpp" -#include "packbits-write.hpp" -#include "compat/assert.hpp" - -namespace floormat { - -using namespace floormat::detail_Pack_input; - -namespace { - -template constexpr inline T lowbits = (T{1} << N)-T{1}; - -static_assert(!input{65535}.check_zero()); -static_assert(input{65535}.advance<16>() == 0); - -static_assert(input::next<16>{ input{65535}.advance<16>() -}.check_zero()); -static_assert(input::next<16>{}.Capacity == 14); - -constexpr bool test1() -{ - constexpr size_t bits[] = { 5, 2, 1 }; - constexpr size_t vals[] = { 8, 3, 1, 0 }; - - constexpr auto S0 = input{0b10111011}; - constexpr auto S1 = input{0b00000101}; - constexpr auto S2 = input{0b00000001}; - constexpr auto S3 = input{0b00000000}; - - using P0 = std::decay_t; - using P1 = P0::next; - using P2 = P1::next; - using P3 = P2::next; - - static_assert(std::is_same_v>); - static_assert(std::is_same_v>); - static_assert(std::is_same_v>); - static_assert(std::is_same_v>); - - static_assert(S0.advance< 0>() == S0.value); - static_assert(S0.advance() == S1.value); - static_assert(S1.advance() == S2.value); - static_assert(S2.advance() == S3.value); - - static_assert(S0.get() == (S0.value & (1<() == (S1.value & (1<() == (S2.value & (1<{0b1110100110001011}; - constexpr auto S1 = input{0b1110}; - constexpr auto S2 = input{0b1}; - - static_assert(S0.get<12>() == 0b100110001011); - static_assert(S0.advance<12>() == S1.value); - - static_assert(S1.get<3>() == 0b110); - static_assert(S1.advance<3>() == S2.value); - - static_assert(S2.get<1>() == 0b1); - static_assert(S2.advance<1>() == 0); - - return true; -} -static_assert(test3()); - -static_assert(std::is_same_v< make_tuple_type, std::tuple >); - -constexpr bool test4() -{ - using Tuple_u32 = make_tuple_type; - static_assert(std::is_same_v>); - using Tuple_u8 = make_tuple_type; - { - Tuple_u32 tuple{}; - static_assert(lowbits == 0x1ffffU); - read(tuple, input{(uint32_t)-1}, std::make_index_sequence<3>{}, make_pack{}); - auto [a, b, c] = tuple; - fm_assert(a == lowbits); - fm_assert(b == lowbits); - fm_assert(c & 1); - } - { - Tuple_u8 tuple{}; - read(tuple, input{0b101011}, std::make_index_sequence<3>{}, make_pack{}); - auto [a, b, c] = tuple; - fm_assert(a == 0b1); - fm_assert(b == 0b101); - fm_assert(c == 0b10); - } - { - std::tuple<> empty_tuple; - read(empty_tuple, input{0}, std::index_sequence<>{}, make_pack{}); - Tuple_u8 tuple{}; (void)tuple; - //read(empty_tuple, input{1}, std::index_sequence<>{}, make_tuple{}); - //read(tuple, input{0b11111}, std::make_index_sequence<3>{}, make_tuple{}); - //(void)input{}; - //read(empty_tuple, input{}, std::index_sequence<0>{}, make_tuple{}); - //read(empty_tuple, input{1}, std::index_sequence<>{}, make_tuple{}); - } - - return true; -} -static_assert(test4()); - -} // namespace - -} // namespace floormat -- cgit v1.2.3