summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2024-01-15 09:50:59 +0100
committerStanislaw Halik <sthalik@misaki.pl>2024-01-15 09:50:59 +0100
commit8ecfad7829cfa3b4342e41b9c52f9f5557b3cb16 (patch)
tree2607787693d26859746ef9289e1d3dfb41f9f461
parent6c30d003dfe391e186cc6e08bb00ec99532e5545 (diff)
aw
-rw-r--r--serialize/packbits-read.hpp21
-rw-r--r--serialize/packbits-write.cpp2
-rw-r--r--serialize/packbits-write.hpp31
3 files changed, 29 insertions, 25 deletions
diff --git a/serialize/packbits-read.hpp b/serialize/packbits-read.hpp
index ff132913..dc21d7ee 100644
--- a/serialize/packbits-read.hpp
+++ b/serialize/packbits-read.hpp
@@ -38,15 +38,24 @@ struct input
{
static_assert(CAPACITY <= sizeof(T)*8);
static constexpr size_t Capacity = CAPACITY;
+
T value;
template<size_t N>
+ struct next_
+ {
+ static_assert(N <= Capacity);
+ using type = input<T, Capacity - N>;
+ };
+ template<size_t N> using next = typename next_<N>::type;
+
+ template<size_t N>
constexpr T get() const
{
static_assert(N > 0);
static_assert(N <= sizeof(T)*8);
static_assert(N <= Capacity);
- return T(value & (T(1) << N) - T(1));
+ return T(value & (T{1} << N) - T{1});
}
template<size_t N>
@@ -58,15 +67,7 @@ struct input
}
constexpr bool operator==(const input&) const noexcept = default;
- [[nodiscard]] constexpr inline bool check_zero() const { return value == T(0); }
-
- template<size_t N>
- struct next_
- {
- static_assert(N <= Capacity);
- using type = input<T, Capacity - N>;
- };
- template<size_t N> using next = typename next_<N>::type;
+ [[nodiscard]] constexpr inline bool check_zero() const { return value == T{0}; }
};
template<std::unsigned_integral T>
diff --git a/serialize/packbits-write.cpp b/serialize/packbits-write.cpp
index 0b4fb4f1..efdf1602 100644
--- a/serialize/packbits-write.cpp
+++ b/serialize/packbits-write.cpp
@@ -6,6 +6,8 @@ using u32 = uint32_t;
using u8 = uint8_t;
template u32 write_(output<u32, 32>, output_field<u32, 1>);
+
static_assert(output<u32, 32>::next<1>::Capacity == 31);
+static_assert(output<u32, 32>::next<1>::next<2>::Capacity == 29);
} // namespace floormat::detail_Pack_output
diff --git a/serialize/packbits-write.hpp b/serialize/packbits-write.hpp
index faa3ff00..4217d739 100644
--- a/serialize/packbits-write.hpp
+++ b/serialize/packbits-write.hpp
@@ -25,6 +25,15 @@ struct output
T value{0};
template<size_t N>
+ struct next_
+ {
+ static_assert(N > 0);
+ static_assert(N <= CAPACITY);
+ using type = output<T, CAPACITY - N>;
+ };
+ template<size_t N> using next = typename next_<N>::type;
+
+ template<size_t N>
constexpr T set(T x, output_bits<N>) const
{
static_assert(N <= CAPACITY, "data type too small");
@@ -37,27 +46,19 @@ struct output
value_ |= x_;
return value_;
}
-
- template<size_t N>
- struct next_
- {
- static_assert(N > 0);
- static_assert(N <= CAPACITY);
- using type = output<T, CAPACITY - N>;
- };
-
- template<size_t N> using next = typename next_<N>::type;
};
-template<typename T, size_t N>
-using output_field = std::pair<T, output_bits<N>>;
-
-template<typename... Ts> struct empty_pack_tuple {}; // todo copypasta
+template<typename T, size_t LENGTH>
+struct output_field
+{
+ T value;
+ static constexpr size_t Length = LENGTH;
+};
template<typename T, size_t Left, size_t F, typename... Fields>
constexpr T write_(output<T, Left> st, output_field<T, F> field, Fields... fields)
{
- T value = st.set(field.first, field.second);
+ T value = st.set(field.value, output_bits<F>{});
using next = typename output<T, Left>::template next<F>;
return write_(next{value}, fields...);
}