summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2024-01-14 14:55:25 +0100
committerStanislaw Halik <sthalik@misaki.pl>2024-01-14 14:55:25 +0100
commit9b957f519620a07597fa28f796c09bdbef2e8fab (patch)
tree5d4e086f8d2a0c6ab74027572cfdea0288378013
parent9b8fb9c6099630e404df5dd976f3f1fa185470cc (diff)
aa
-rw-r--r--serialize/packbits.cpp18
-rw-r--r--serialize/packbits.hpp38
2 files changed, 49 insertions, 7 deletions
diff --git a/serialize/packbits.cpp b/serialize/packbits.cpp
index c908634b..6ed898c7 100644
--- a/serialize/packbits.cpp
+++ b/serialize/packbits.cpp
@@ -9,7 +9,13 @@ namespace {
template<size_t Val> using us_bits = Bits_<uint16_t, Val>;
-static_assert(!Storage<uint8_t, 0>{42}.check_zero());
+static_assert(!Storage<uint32_t, 3>{65535}.check_zero());
+static_assert(Storage<uint32_t, 30>{65535}.advance<16>() == 0);
+
+static_assert(Storage<uint32_t, 30>::next<16>{
+ Storage<uint32_t, 30>{65535}.advance<16>()
+}.check_zero());
+static_assert(Storage<uint32_t, 30>::next<16>{}.Capacity == 14);
constexpr bool test1()
{
@@ -100,6 +106,16 @@ constexpr bool test3()
}
static_assert(test3());
+static_assert(std::is_same_v< make_tuple_type<uint8_t, 3>, std::tuple<uint8_t, uint8_t, uint8_t> >);
+
+constexpr bool test4()
+{
+ auto t = std::tuple<unsigned, unsigned, unsigned>();
+
+ return true;
+}
+static_assert(test4());
+
} // namespace
} // namespace floormat
diff --git a/serialize/packbits.hpp b/serialize/packbits.hpp
index cb91602f..12c1dd31 100644
--- a/serialize/packbits.hpp
+++ b/serialize/packbits.hpp
@@ -1,6 +1,8 @@
#pragma once
#include <type_traits>
#include <concepts>
+#include <tuple>
+#include "compat/assert.hpp"
namespace floormat::Pack {
template<std::unsigned_integral T, uint8_t N> struct Bits_;
@@ -55,7 +57,7 @@ struct Storage
}
constexpr bool operator==(const Storage&) const noexcept = default;
- constexpr bool check_zero() const = delete;
+ [[nodiscard]] constexpr inline bool check_zero() const { return value == T(0); }
template<size_t N> using next = Storage<T, Capacity - N>;
};
@@ -70,11 +72,7 @@ struct Storage<T, 0>
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;
-
- [[nodiscard]] constexpr inline bool check_zero() const
- {
- return value == T(0);
- }
+ [[nodiscard]] constexpr inline bool check_zero() const { return true; }
template<size_t N> struct next
{
@@ -83,6 +81,34 @@ struct Storage<T, 0>
};
};
+template<std::unsigned_integral T, size_t N>
+struct make_tuple_type_
+{
+ template<size_t> using index_to_type = T;
+ template<typename> struct aux;
+ template<size_t... Is> struct aux<std::index_sequence<Is...>>
+ {
+ static_assert(sizeof...(Is) > 0);
+ using type = std::tuple<index_to_type<Is>...>;
+ };
+ using Seq = typename aux<std::make_index_sequence<N>>::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>
+static void assign_to_tuple(Place&, Storage<T, Left> st, std::index_sequence<>)
+{
+ fm_assert(st.check_zero());
+}
+
+template<typename T, typename Place, size_t Left, size_t Size, size_t... Sizes>
+static void assign_to_tuple(Place& p, Storage<T, Left> st, std::index_sequence<Size, Sizes...>)
+{
+ using std::get;
+ get<Size>(p) = st.template get<Size>(st);
+ assign_to_tuple(p, st.template advance<Size>(), std::index_sequence<Sizes...>{});
+}
+
} // namespace floormat::detail_Pack
namespace floormat::Pack {