diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2024-01-14 21:08:43 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2024-01-14 21:08:43 +0100 |
commit | c26f49ebe40d1900229064db473dd721c991582a (patch) | |
tree | cd0368daec2fd3e5982d0ba43dcb5301011f7a3b /serialize | |
parent | b5f96dda3de339b2db61c531f6f486f9d3d45866 (diff) |
a
Diffstat (limited to 'serialize')
-rw-r--r-- | serialize/packbits.cpp | 16 | ||||
-rw-r--r-- | serialize/packbits.hpp | 43 |
2 files changed, 30 insertions, 29 deletions
diff --git a/serialize/packbits.cpp b/serialize/packbits.cpp index ffca868f..74b9ff90 100644 --- a/serialize/packbits.cpp +++ b/serialize/packbits.cpp @@ -140,7 +140,7 @@ constexpr bool test4() { Tuple_u32 tuple{}; static_assert(lowbits<uint32_t, 17> == 0x1ffffU); - assign_tuple(tuple, Storage<uint32_t, 32>{(uint32_t)-1}, std::make_index_sequence<3>{}, Bits<uint32_t, 17>{}, Bits<uint32_t, 14>{}, Bits<uint32_t, 1>{}); + assign_tuple(tuple, Storage<uint32_t, 32>{(uint32_t)-1}, std::make_index_sequence<3>{}, make_pack<uint32_t, 17, 14, 1>{}); auto [a, b, c] = tuple; fm_assert(a == lowbits<uint32_t, 17>); fm_assert(b == lowbits<uint32_t, 14>); @@ -148,7 +148,7 @@ constexpr bool test4() } { Tuple_u8 tuple{}; - assign_tuple(tuple, Storage<uint8_t, 8>{0b101011}, std::make_index_sequence<3>{}, Bits<uint8_t, 1>{}, Bits<uint8_t, 3>{}, Bits<uint8_t, 2>{}); + assign_tuple(tuple, Storage<uint8_t, 8>{0b101011}, std::make_index_sequence<3>{}, make_pack<uint8_t, 1, 3, 2>{}); auto [a, b, c] = tuple; fm_assert(a == 0b1); fm_assert(b == 0b101); @@ -156,13 +156,13 @@ constexpr bool test4() } { std::tuple<> empty_tuple; - assign_tuple(empty_tuple, Storage<uint8_t, 8>{0}, std::index_sequence<>{}); + assign_tuple(empty_tuple, Storage<uint8_t, 8>{0}, std::index_sequence<>{}, make_pack<uint8_t>{}); Tuple_u8 tuple{}; (void)tuple; - // assign_tuple(empty_tuple, Storage<uint8_t, 8>{1}, std::index_sequence<>{}); - // assign_tuple(tuple, Storage<uint8_t, 5>{0b11111}, std::make_index_sequence<3>{}, Bits<uint8_t, 2>{}, Bits<uint8_t, 2>{}, Bits<uint8_t, 2>{}); - // (void)Storage<uint8_t, 9>{}; - //assign_tuple(empty_tuple, Storage<uint8_t, 8>{}, std::index_sequence<0>{}, Bits<uint8_t, 1>{}); - // assign_tuple(empty_tuple, Storage<uint8_t, 8>{1}, std::index_sequence<>{}, Bits<uint8_t, 1>{}); + //assign_tuple(empty_tuple, Storage<uint8_t, 8>{1}, std::index_sequence<>{}, make_tuple<uint8_t>{}); + //assign_tuple(tuple, Storage<uint8_t, 5>{0b11111}, std::make_index_sequence<3>{}, make_tuple<uint8_t, 2, 2, 2>{}); + //(void)Storage<uint8_t, 9>{}; + //assign_tuple(empty_tuple, Storage<uint8_t, 8>{}, std::index_sequence<0>{}, make_tuple<uint8_t, 1>{}); + //assign_tuple(empty_tuple, Storage<uint8_t, 8>{1}, std::index_sequence<>{}, make_tuple<uint8_t, 1>{}); } return true; diff --git a/serialize/packbits.hpp b/serialize/packbits.hpp index 8a828f94..3fd859d2 100644 --- a/serialize/packbits.hpp +++ b/serialize/packbits.hpp @@ -4,13 +4,18 @@ #include <tuple> #include "compat/assert.hpp" -namespace floormat::Pack { -template<std::unsigned_integral T, size_t N> struct Bits; -} // namespace floormat::Pack - namespace floormat::detail_Pack { -using namespace floormat::Pack; +template<std::unsigned_integral T, size_t N> +struct Bits final +{ + static_assert(std::is_fundamental_v<T>); + static_assert(N > 0); + static_assert(N < sizeof(T)*8); + + using type = T; + static constexpr auto bits = N; +}; template<std::unsigned_integral T, size_t CAPACITY> struct Storage @@ -77,8 +82,11 @@ struct make_tuple_type_ }; template<std::unsigned_integral T, size_t N> using make_tuple_type = typename make_tuple_type_<T, N>::Seq; -template<typename T, typename Place, size_t Left, size_t I, size_t... Is, size_t Size, typename... Sizes> -constexpr void assign_tuple(Place& p, Storage<T, Left> st, std::index_sequence<I, Is...>, Bits<T, Size>, Sizes... sizes) +template<typename... Ts> struct pack_tuple {}; + +template<std::unsigned_integral T, typename Place, size_t Left, size_t I, size_t... Is, size_t Size, typename... Sizes> +requires requires() { sizeof...(Is) == sizeof...(Sizes); } +constexpr void assign_tuple(Place& p, Storage<T, Left> st, std::index_sequence<I, Is...>, pack_tuple<Bits<T, Size>, Sizes...>) { static_assert(Size <= Left, "too many bits requested"); static_assert(I < std::tuple_size_v<Place>, "too few tuple members"); @@ -86,32 +94,25 @@ constexpr void assign_tuple(Place& p, Storage<T, Left> st, std::index_sequence<I using next_type = typename S::template next<Size>; get<I>(p) = st.template get<Size>(); T next_value = st.template advance<Size>(); - assign_tuple(p, next_type{next_value}, std::index_sequence<Is...>{}, sizes...); + assign_tuple(p, next_type{next_value}, std::index_sequence<Is...>{}, pack_tuple<Sizes...>{}); } -template<typename T, typename Place, size_t Left> -constexpr void assign_tuple(Place&, Storage<T, Left> st, std::index_sequence<>) +template<std::unsigned_integral T, typename Place, size_t Left> +constexpr void assign_tuple(Place&, Storage<T, Left> st, std::index_sequence<>, pack_tuple<>) { fm_assert(st.check_zero()); } -template<typename T, typename Place, size_t Left, size_t... Is, typename... Sizes> +template<std::unsigned_integral T, typename Place, size_t Left, size_t... Is, typename... Sizes> requires(sizeof...(Is) != sizeof...(Sizes)) -constexpr void assign_tuple(Place&, Storage<T, Left>, std::index_sequence<Is...>, Sizes...) = delete; +constexpr void assign_tuple(Place&, Storage<T, Left>, std::index_sequence<Is...>, pack_tuple<Sizes...>) = delete; + +template<std::unsigned_integral T, size_t... Ns> using make_pack = pack_tuple<Bits<T, Ns>...>; } // namespace floormat::detail_Pack namespace floormat::Pack { -template<std::unsigned_integral T, size_t N> -struct Bits final -{ - static_assert(std::is_fundamental_v<T>); - static_assert(N > 0); - static_assert(N < sizeof(T)*8); - using type = T; - static constexpr auto bits = N; -}; } // namespace floormat::Pack |