summaryrefslogtreecommitdiffhomepage
path: root/serialize
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2024-01-14 21:08:43 +0100
committerStanislaw Halik <sthalik@misaki.pl>2024-01-14 21:08:43 +0100
commitc26f49ebe40d1900229064db473dd721c991582a (patch)
treecd0368daec2fd3e5982d0ba43dcb5301011f7a3b /serialize
parentb5f96dda3de339b2db61c531f6f486f9d3d45866 (diff)
a
Diffstat (limited to 'serialize')
-rw-r--r--serialize/packbits.cpp16
-rw-r--r--serialize/packbits.hpp43
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