diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2024-01-14 14:55:25 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2024-01-14 14:55:25 +0100 |
commit | 9b957f519620a07597fa28f796c09bdbef2e8fab (patch) | |
tree | 5d4e086f8d2a0c6ab74027572cfdea0288378013 /serialize | |
parent | 9b8fb9c6099630e404df5dd976f3f1fa185470cc (diff) |
aa
Diffstat (limited to 'serialize')
-rw-r--r-- | serialize/packbits.cpp | 18 | ||||
-rw-r--r-- | serialize/packbits.hpp | 38 |
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 { |