42# ifndef TPL_PAGED_VALUE_CODEC_H
43# define TPL_PAGED_VALUE_CODEC_H
53# include <type_traits>
64 template <
typename Codec,
typename Value>
67 const unsigned char *
in,
70 { Codec::storage_id } -> std::convertible_to<std::uint32_t>;
71 { Codec::encoded_size } -> std::convertible_to<size_t>;
72 { Codec::encode(value,
out) } -> std::same_as<void>;
73 { Codec::decode(
in) } -> std::same_as<Value>;
74 { Codec::add_to_crc(
crc, value) } -> std::same_as<std::uint32_t>;
78 const std::uint32_t
seed,
79 const std::uint32_t value)
noexcept
81 return (
seed ^ value) * 16777619u + 0x9E3779B9u;
84 template <
typename UInt>
85 requires(std::is_unsigned_v<UInt>)
88 for (
size_t i = 0; i <
sizeof(
UInt); ++i)
89 out[i] =
static_cast<unsigned char>((value >> (i * 8)) & 0xFFu);
92 template <
typename UInt>
93 requires(std::is_unsigned_v<UInt>)
95 const unsigned char *
in)
noexcept
98 for (
size_t i = 0; i <
sizeof(
UInt); ++i)
99 value |=
static_cast<UInt>(
in[i]) << (i * 8);
103 template <
typename T>
104 requires(std::is_integral_v<T>
and sizeof(
T) == 1)
107 static constexpr std::uint32_t storage_id =
108 0x11000000u | (std::is_signed_v<T> ? 1u : 0u);
109 static constexpr size_t encoded_size = 1;
111 static void encode(
const T value,
unsigned char *
out)
noexcept
113 out[0] =
static_cast<unsigned char>(value);
118 if constexpr (std::is_same_v<T, bool>)
121 return static_cast<T>(
in[0]);
125 const std::uint32_t
crc,
126 const T value)
noexcept
128 unsigned char byte = 0;
129 encode(value, &
byte);
134 template <
typename T>
135 requires(std::is_integral_v<T>
and sizeof(
T) != 1)
136 struct Paged_Value_Codec<
T>
140 static constexpr std::uint32_t storage_id =
141 0x12000000u | (
static_cast<std::uint32_t
>(
sizeof(
T)) << 8)
142 | (std::is_signed_v<T> ? 1u : 0u);
143 static constexpr size_t encoded_size =
sizeof(
T);
145 static void encode(
const T value,
unsigned char *
out)
noexcept
148 std::memcpy(&bits, &value,
sizeof(
T));
156 std::memcpy(&value, &bits,
sizeof(
T));
161 const std::uint32_t
crc,
162 const T value)
noexcept
164 std::array<unsigned char, encoded_size> bytes = {};
165 encode(value, bytes.data());
170 template <
typename T>
171 requires std::is_enum_v<T>
172 struct Paged_Value_Codec<
T>
177 static constexpr std::uint32_t storage_id =
178 mix_codec_id(0x21000000u, underlying_codec::storage_id);
179 static constexpr size_t encoded_size = underlying_codec::encoded_size;
181 static void encode(
const T value,
unsigned char *
out)
noexcept
188 return static_cast<T>(underlying_codec::decode(
in));
192 const std::uint32_t
crc,
193 const T value)
noexcept
195 return underlying_codec::add_to_crc(
200 template <
typename T>
201 requires(std::is_floating_point_v<T>
and std::numeric_limits<T>::is_iec559
202 and (
sizeof(
T) == 4
or sizeof(
T) == 8))
203 struct Paged_Value_Codec<T>
206 std::conditional_t<
sizeof(
T) == 4, std::uint32_t, std::uint64_t>;
208 static constexpr std::uint32_t storage_id =
209 0x31000000u |
static_cast<std::uint32_t
>(
sizeof(
T));
210 static constexpr size_t encoded_size =
sizeof(
T);
212 static void encode(
const T value,
unsigned char *
out)
noexcept
214 const auto bits = std::bit_cast<unsigned_type>(value);
221 return std::bit_cast<T>(bits);
225 const std::uint32_t
crc,
226 const T value)
noexcept
228 std::array<unsigned char, encoded_size> bytes = {};
229 encode(value, bytes.data());
234 template <
typename T,
size_t N>
240 static constexpr std::uint32_t storage_id =
242 static_cast<std::uint32_t
>(
N));
243 static constexpr size_t encoded_size =
N * element_codec::encoded_size;
245 static void encode(
const std::array<T, N> & value,
246 unsigned char *
out)
noexcept
248 for (
size_t i = 0; i <
N; ++i)
249 element_codec::encode(value[i],
250 out + i * element_codec::encoded_size);
256 std::array<T, N> value = {};
257 for (
size_t i = 0; i <
N; ++i)
258 value[i] = element_codec::decode(
in + i * element_codec::encoded_size);
264 const std::array<T, N> & value)
noexcept
266 for (
size_t i = 0; i <
N; ++i)
267 crc = element_codec::add_to_crc(
crc, value[i]);
272 template <
size_t Capacity,
typename SizeType = std::u
int32_t>
273 requires(std::is_unsigned_v<SizeType>)
277 "Paged_Bounded_String_Codec requires Capacity > 0");
279 static constexpr std::uint32_t storage_id =
281 static_cast<std::uint32_t
>(
Capacity)),
282 static_cast<std::uint32_t
>(
sizeof(
SizeType)));
285 static void encode(
const std::string & value,
unsigned char *
out)
288 <<
"Paged_Bounded_String_Codec<" <<
Capacity
289 <<
">::encode(): string size " << value.size()
290 <<
" exceeds capacity " <<
Capacity;
294 if (
not value.empty())
295 std::memcpy(
out +
sizeof(
SizeType), value.data(), value.size());
302 <<
"Paged_Bounded_String_Codec<" <<
Capacity
303 <<
">::decode(): corrupted size " <<
size
304 <<
" exceeds capacity " <<
Capacity;
306 return std::string(
reinterpret_cast<const char *
>(
in +
sizeof(
SizeType)),
307 static_cast<size_t>(
size));
311 const std::uint32_t
crc,
312 const std::string & value)
314 std::array<unsigned char, encoded_size> bytes = {};
315 encode(value, bytes.data());
#define ah_runtime_error_unless(C)
Throws std::runtime_error if condition does NOT hold.
std::uint32_t crc32_add_bytes(std::uint32_t crc, const void *data, const size_t size) noexcept
constexpr std::uint32_t mix_codec_id(const std::uint32_t seed, const std::uint32_t value) noexcept
UInt decode_unsigned_le(const unsigned char *in) noexcept
void encode_unsigned_le(UInt value, unsigned char *out) noexcept
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
size_t size(Node *root) noexcept
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
std::decay_t< typename HeadC::Item_Type > T
static void encode(const std::string &value, unsigned char *out)
static std::string decode(const unsigned char *in)
static std::uint32_t add_to_crc(const std::uint32_t crc, const std::string &value)
std::make_unsigned_t< T > unsigned_type
static T decode(const unsigned char *in) noexcept
static std::uint32_t add_to_crc(const std::uint32_t crc, const T value) noexcept
std::underlying_type_t< T > underlying_type
static void encode(const T value, unsigned char *out) noexcept
static std::array< T, N > decode(const unsigned char *in) noexcept
static std::uint32_t add_to_crc(std::uint32_t crc, const std::array< T, N > &value) noexcept
static void encode(const std::array< T, N > &value, unsigned char *out) noexcept
Helpers for durable paged-tree files.