summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2024-01-14 20:47:15 +0100
committerStanislaw Halik <sthalik@misaki.pl>2024-01-14 20:47:15 +0100
commitb5f96dda3de339b2db61c531f6f486f9d3d45866 (patch)
tree21da3c8f9d9a3ced8aeef25ccbf184148184da5f
parent97fc4fcd50272dab1d2c6e94019502d42deb4a2c (diff)
a
-rw-r--r--serialize/packbits.cpp63
-rw-r--r--serialize/packbits.hpp70
2 files changed, 47 insertions, 86 deletions
diff --git a/serialize/packbits.cpp b/serialize/packbits.cpp
index 634191fc..ffca868f 100644
--- a/serialize/packbits.cpp
+++ b/serialize/packbits.cpp
@@ -7,10 +7,11 @@ using namespace floormat::detail_Pack;
namespace {
+#if 0
template<std::unsigned_integral T, size_t Sum, typename... Xs> struct check_size_overflow;
template<std::unsigned_integral T, std::unsigned_integral U, size_t Sum, size_t N, typename... Xs>
-struct check_size_overflow<T, Sum, Bits_<U, N>, Xs...>
+struct check_size_overflow<T, Sum, Bits<U, N>, Xs...>
{
static_assert(std::is_same_v<T, U>);
static constexpr auto acc = Sum + size_t{N};
@@ -25,10 +26,10 @@ struct check_size_overflow<T, Sum>
static constexpr size_t size = Sum;
static constexpr bool result = Sum <= sizeof(T)*8;
};
+#endif
template<std::unsigned_integral T, size_t N> constexpr inline T lowbits = (T{1} << N)-T{1};
-
-template<size_t Val> using us_bits = Bits_<uint16_t, Val>;
+template<size_t Val> using us_bits = Bits<uint16_t, Val>;
static_assert(!Storage<uint32_t, 3>{65535}.check_zero());
static_assert(Storage<uint32_t, 30>{65535}.advance<16>() == 0);
@@ -72,6 +73,7 @@ constexpr bool test1()
}
static_assert(test1());
+#if 0
constexpr bool test2()
{
using foo1 = us_bits<2>;
@@ -107,6 +109,7 @@ constexpr bool test2()
return true;
}
static_assert(test2());
+#endif
constexpr bool test3()
{
@@ -131,30 +134,36 @@ static_assert(std::is_same_v< make_tuple_type<uint8_t, 3>, std::tuple<uint8_t,
constexpr bool test4()
{
- using Tuple = std::tuple<uint32_t, uint32_t, uint32_t>;
- Tuple tuple{};
- assign_tuple2(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>{});
- auto [a, b, c] = tuple;
-
- static_assert(lowbits<uint32_t, 17> != 0);
- fm_assert(a == lowbits<uint32_t, 17>);
- fm_assert(b == lowbits<uint32_t, 14>);
- fm_assert(c & 1);
-
- //Assign::do_tuple(tuple, Storage<uint32_t, 32>{(uint32_t)-1});
-
- return true;
-}
-static_assert(test4());
-
-constexpr bool test5()
-{
- auto st = Storage<uint32_t, 32>{0xB16B00B5};
- uint32_t a, b, c;
- using Tuple = std::tuple<uint32_t&, uint32_t&, uint32_t&>;
- auto t = Tuple{a, b, c};
- //assign_tuple<uint32_t, std::make_index_sequence<3>, Tuple,
+ using Tuple_u32 = make_tuple_type<uint32_t, 3>;
+ static_assert(std::is_same_v<Tuple_u32, std::tuple<uint32_t, uint32_t, uint32_t>>);
+ using Tuple_u8 = make_tuple_type<uint8_t, 3>;
+ {
+ 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>{});
+ auto [a, b, c] = tuple;
+ fm_assert(a == lowbits<uint32_t, 17>);
+ fm_assert(b == lowbits<uint32_t, 14>);
+ fm_assert(c & 1);
+ }
+ {
+ 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>{});
+ auto [a, b, c] = tuple;
+ fm_assert(a == 0b1);
+ fm_assert(b == 0b101);
+ fm_assert(c == 0b10);
+ }
+ {
+ std::tuple<> empty_tuple;
+ assign_tuple(empty_tuple, Storage<uint8_t, 8>{0}, std::index_sequence<>{});
+ 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>{});
+ }
return true;
}
diff --git a/serialize/packbits.hpp b/serialize/packbits.hpp
index c94f96d7..8a828f94 100644
--- a/serialize/packbits.hpp
+++ b/serialize/packbits.hpp
@@ -5,14 +5,13 @@
#include "compat/assert.hpp"
namespace floormat::Pack {
-template<std::unsigned_integral T, size_t N> struct Bits_;
+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 CAPACITY>
struct Storage
{
@@ -79,80 +78,33 @@ 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_tuple2(Place& p, Storage<T, Left> st, std::index_sequence<I, Is...>, Bits_<T, Size>, Sizes... sizes)
+constexpr void assign_tuple(Place& p, Storage<T, Left> st, std::index_sequence<I, Is...>, Bits<T, Size>, Sizes... sizes)
{
+ static_assert(Size <= Left, "too many bits requested");
+ static_assert(I < std::tuple_size_v<Place>, "too few tuple members");
using S = Storage<T, Left>;
using next_type = typename S::template next<Size>;
get<I>(p) = st.template get<Size>();
T next_value = st.template advance<Size>();
- assign_tuple2(p, next_type{next_value}, std::index_sequence<Is...>{}, sizes...);
+ assign_tuple(p, next_type{next_value}, std::index_sequence<Is...>{}, sizes...);
}
template<typename T, typename Place, size_t Left>
-constexpr void assign_tuple2(Place&, Storage<T, Left>, std::index_sequence<>)
+constexpr void assign_tuple(Place&, Storage<T, Left> st, std::index_sequence<>)
{
+ fm_assert(st.check_zero());
}
-#if 0
-template<typename T, typename Indexes, typename... Sizes> struct assign_tuple;
-
-template<typename T, size_t Index, size_t... Indexes, size_t Size, typename... Sizes>
-struct assign_tuple<T, std::index_sequence<Index, Indexes...>, Bits_<T, Size>, Sizes...>
-{
- static_assert(Size <= sizeof(T)*8, "bit count can't be larger than sizeof(T)*8");
- static_assert(Size > 0, "bit count can't be zero");
-
- template<typename Place, size_t Left>
- static constexpr inline void do_tuple(Place& p, Storage<T, Left> st)
- {
- static_assert(requires (Place& p) { std::get<0>(p) = T{0}; });
- static_assert(std::tuple_size_v<Place> >= sizeof...(Indexes) + 1);
- static_assert(Size <= Left, "not enough bits for element");
-
- get<Index>(p) = st.template get<Size>(st.value);
- using Next = typename Storage<T, Left>::template next<Size>;
- assign_tuple<T, std::index_sequence<Indexes...>, Sizes...>::
- template do_tuple<Place, Next>(p, Next{st.template advance<Size>()});
- }
-
- static constexpr bool is_empty = false;
-};
-
-template<typename T, size_t Index, size_t... Indexes>
-struct assign_tuple<T, std::index_sequence<Index, Indexes...>>
-{
- static_assert(sizeof(T) == (size_t)-1, "too few lhs elements");
- static_assert(sizeof(T) != (size_t)-1);
-};
-
-template<typename T, size_t Size, typename... Sizes>
-struct assign_tuple<T, std::index_sequence<>, Bits_<T, Size>, Sizes...>
-{
- static_assert(sizeof(T) == (size_t)-1, "too few rhs elements");
- static_assert(sizeof(T) != (size_t)-1);
-};
-
-template<typename T>
-struct assign_tuple<T, std::index_sequence<>>
-{
- template<typename Place, size_t Left>
- static constexpr inline void do_tuple(Place&, Storage<T, Left> st)
- {
- fm_assert(st.check_zero());
- }
-
- static constexpr bool is_empty = true;
- using type = T;
-};
-
-#endif
+template<typename 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;
} // namespace floormat::detail_Pack
namespace floormat::Pack {
template<std::unsigned_integral T, size_t N>
-struct Bits_ final
+struct Bits final
{
static_assert(std::is_fundamental_v<T>);
static_assert(N > 0);