Updated bundled protozero to v1.7.0

This commit is contained in:
Denis Chaplygin
2020-10-16 10:25:52 +03:00
parent df3ed43d70
commit a8362d75b5
126 changed files with 18489 additions and 11079 deletions
+2
View File
@@ -8,8 +8,10 @@
set(UNIT_TESTS data_view
basic
buffer
endian
exceptions
iterators
varint
zigzag)
+84 -44
View File
@@ -1,6 +1,36 @@
#include <test.hpp>
#include <type_traits>
template <typename T>
struct movable_not_copyable {
constexpr static bool value = !std::is_copy_constructible<T>::value &&
!std::is_copy_assignable<T>::value &&
std::is_nothrow_move_constructible<T>::value &&
std::is_nothrow_move_assignable<T>::value;
};
static_assert(movable_not_copyable<protozero::pbf_writer>::value, "pbf_writer should be nothrow movable, but not copyable");
enum class dummy : protozero::pbf_tag_type {};
static_assert(movable_not_copyable<protozero::pbf_builder<dummy>>::value, "pbf_builder should be nothrow movable, but not copyable");
static_assert(movable_not_copyable<protozero::packed_field_bool>::value, "packed_field_bool should be nothrow movable, but not copyable");
static_assert(movable_not_copyable<protozero::packed_field_enum>::value, "packed_field_enum should be nothrow movable, but not copyable");
static_assert(movable_not_copyable<protozero::packed_field_int32>::value, "packed_field_int32 should be nothrow movable, but not copyable");
static_assert(movable_not_copyable<protozero::packed_field_sint32>::value, "packed_field_sint32 should be nothrow movable, but not copyable");
static_assert(movable_not_copyable<protozero::packed_field_uint32>::value, "packed_field_uint32 should be nothrow movable, but not copyable");
static_assert(movable_not_copyable<protozero::packed_field_int64>::value, "packed_field_int64 should be nothrow movable, but not copyable");
static_assert(movable_not_copyable<protozero::packed_field_sint64>::value, "packed_field_sint64 should be nothrow movable, but not copyable");
static_assert(movable_not_copyable<protozero::packed_field_uint64>::value, "packed_field_uint64 should be nothrow movable, but not copyable");
static_assert(movable_not_copyable<protozero::packed_field_fixed32>::value, "packed_field_fixed32 should be nothrow movable, but not copyable");
static_assert(movable_not_copyable<protozero::packed_field_sfixed32>::value, "packed_field_sfixed32 should be nothrow movable, but not copyable");
static_assert(movable_not_copyable<protozero::packed_field_fixed64>::value, "packed_field_fixed64 should be nothrow movable, but not copyable");
static_assert(movable_not_copyable<protozero::packed_field_sfixed64>::value, "packed_field_sfixed64 should be nothrow movable, but not copyable");
static_assert(movable_not_copyable<protozero::packed_field_float>::value, "packed_field_float should be nothrow movable, but not copyable");
static_assert(movable_not_copyable<protozero::packed_field_double>::value, "packed_field_double should be nothrow movable, but not copyable");
TEST_CASE("default constructed pbf_reader is okay") {
protozero::pbf_reader item;
@@ -19,10 +49,10 @@ TEST_CASE("empty buffer in pbf_reader is okay") {
}
TEST_CASE("check every possible value for single byte in buffer") {
char buffer;
char buffer[1];
for (int i = 0; i <= 255; ++i) {
buffer = static_cast<char>(i);
protozero::pbf_reader item{&buffer, 1};
buffer[0] = static_cast<char>(i);
protozero::pbf_reader item{buffer, 1};
REQUIRE(item.length() == 1);
REQUIRE_FALSE(!item); // test operator bool()
@@ -31,54 +61,64 @@ TEST_CASE("check every possible value for single byte in buffer") {
}
TEST_CASE("next() should throw when illegal wire type is encountered") {
const char buffer = 1u << 3u | 7u;
const char buffer[1] = {1U << 3U | 7U};
protozero::pbf_reader item{&buffer, 1};
REQUIRE_THROWS_AS(item.next(), const protozero::unknown_pbf_wire_type_exception&);
protozero::pbf_reader item{buffer, 1};
REQUIRE_THROWS_AS(item.next(), protozero::unknown_pbf_wire_type_exception);
}
TEST_CASE("next() should throw when illegal tag is encountered") {
TEST_CASE("next() should throw when illegal tag 0 is encountered") {
std::string data;
SECTION("tag 0") {
protozero::write_varint(std::back_inserter(data), 0u << 3u | 1u);
}
SECTION("tag 19000") {
protozero::write_varint(std::back_inserter(data), 19000u << 3u | 1u);
}
SECTION("tag 19001") {
protozero::write_varint(std::back_inserter(data), 19001u << 3u | 1u);
}
SECTION("tag 19999") {
protozero::write_varint(std::back_inserter(data), 19999u << 3u | 1u);
}
protozero::add_varint_to_buffer(&data, 0U << 3U | 1U);
protozero::pbf_reader item{data};
REQUIRE_THROWS_AS(item.next(), const protozero::invalid_tag_exception&);
REQUIRE_THROWS_AS(item.next(), protozero::invalid_tag_exception);
}
TEST_CASE("next() works when a legal tag is encountered") {
TEST_CASE("next() should throw when illegal tag 19000 is encountered") {
std::string data;
protozero::add_varint_to_buffer(&data, 19000U << 3U | 1U);
protozero::pbf_reader item{data};
REQUIRE_THROWS_AS(item.next(), protozero::invalid_tag_exception);
}
SECTION("tag 1") {
protozero::write_varint(std::back_inserter(data), 1u << 3u | 1u);
}
TEST_CASE("next() should throw when illegal tag 19001 is encountered") {
std::string data;
protozero::add_varint_to_buffer(&data, 19001U << 3U | 1U);
protozero::pbf_reader item{data};
REQUIRE_THROWS_AS(item.next(), protozero::invalid_tag_exception);
}
SECTION("tag 18999") {
protozero::write_varint(std::back_inserter(data), 18999u << 3u | 1u);
}
TEST_CASE("next() should throw when illegal tag 19999 is encountered") {
std::string data;
protozero::add_varint_to_buffer(&data, 19999U << 3U | 1U);
protozero::pbf_reader item{data};
REQUIRE_THROWS_AS(item.next(), protozero::invalid_tag_exception);
}
SECTION("tag 20000") {
protozero::write_varint(std::back_inserter(data), 20000u << 3u | 1u);
}
TEST_CASE("next() works when legal tag 1 is encountered") {
std::string data;
protozero::add_varint_to_buffer(&data, 1U << 3U | 1U);
protozero::pbf_reader item{data};
REQUIRE(item.next());
}
SECTION("tag 1^29 - 1") {
protozero::write_varint(std::back_inserter(data), ((1u << 29u) - 1u) << 3u | 1u);
}
TEST_CASE("next() works when legal tag 18999 is encountered") {
std::string data;
protozero::add_varint_to_buffer(&data, 18999U << 3U | 1U);
protozero::pbf_reader item{data};
REQUIRE(item.next());
}
TEST_CASE("next() works when legal tag 20000 is encountered") {
std::string data;
protozero::add_varint_to_buffer(&data, 20000U << 3U | 1U);
protozero::pbf_reader item{data};
REQUIRE(item.next());
}
TEST_CASE("next() works when legal tag 1^29 - 1 is encountered") {
std::string data;
protozero::add_varint_to_buffer(&data, ((1UL << 29U) - 1U) << 3U | 1U);
protozero::pbf_reader item{data};
REQUIRE(item.next());
}
@@ -87,15 +127,15 @@ TEST_CASE("pbf_writer asserts on invalid tags") {
std::string data;
protozero::pbf_writer writer{data};
REQUIRE_THROWS_AS(writer.add_int32(0, 123), const assert_error&);
REQUIRE_THROWS_AS(writer.add_int32(0, 123), assert_error);
writer.add_int32(1, 123);
writer.add_int32(2, 123);
writer.add_int32(18999, 123);
REQUIRE_THROWS_AS(writer.add_int32(19000, 123), const assert_error&);
REQUIRE_THROWS_AS(writer.add_int32(19001, 123), const assert_error&);
REQUIRE_THROWS_AS(writer.add_int32(19999, 123), const assert_error&);
REQUIRE_THROWS_AS(writer.add_int32(19000, 123), assert_error);
REQUIRE_THROWS_AS(writer.add_int32(19001, 123), assert_error);
REQUIRE_THROWS_AS(writer.add_int32(19999, 123), assert_error);
writer.add_int32(20000, 123);
writer.add_int32((1u << 29u) - 1u, 123);
REQUIRE_THROWS_AS(writer.add_int32(1u << 29u, 123), const assert_error&);
writer.add_int32((1U << 29U) - 1U, 123);
REQUIRE_THROWS_AS(writer.add_int32(1U << 29U, 123), assert_error);
}
+50
View File
@@ -0,0 +1,50 @@
#include <buffer.hpp>
#include <algorithm>
#include <array>
#include <stdexcept>
#include <type_traits>
TEMPLATE_TEST_CASE("Use various buffer types", "", buffer_test_string, buffer_test_vector, buffer_test_array, buffer_test_external) {
TestType tt;
auto* buffer = &tt.buffer();
using bc = protozero::buffer_customization<typename TestType::type>;
REQUIRE(bc::size(buffer) == 0);
bc::append(buffer, "abc def ghi", 11);
REQUIRE(bc::size(buffer) == 11);
bc::append_zeros(buffer, 3);
REQUIRE(bc::size(buffer) == 14);
bc::resize(buffer, 11);
REQUIRE(bc::size(buffer) == 11);
bc::append(buffer, " jkl", 4);
REQUIRE(bc::size(buffer) == 15);
bc::erase_range(buffer, 4, 8);
REQUIRE(bc::size(buffer) == 11);
REQUIRE(std::equal(bc::at_pos(buffer, 0),
bc::at_pos(buffer, bc::size(buffer)),
"abc ghi jkl"));
buffer->push_back(' ');
buffer->push_back('x');
buffer->push_back('y');
REQUIRE(bc::size(buffer) == 14);
REQUIRE(std::equal(bc::at_pos(buffer, 0),
bc::at_pos(buffer, bc::size(buffer)),
"abc ghi jkl xy"));
REQUIRE(std::equal(buffer->cbegin(), buffer->cend(), "abc ghi jkl xy"));
}
TEST_CASE("fixed_size_buffer_adaptor has limited size") {
std::array<char, 5> data = {{0}};
protozero::fixed_size_buffer_adaptor fsba{&*data.begin(), data.size()};
REQUIRE_THROWS_AS(protozero::buffer_customization<protozero::fixed_size_buffer_adaptor>::append(&fsba, "0123456789", 10), std::length_error);
}
+1 -1
View File
@@ -61,7 +61,7 @@ TEST_CASE("convert data_view to std::string") {
// that one contains the protozero_assert() which generates the exception.
TEST_CASE("converting default constructed data_view to string fails") {
const protozero::data_view view{};
REQUIRE_THROWS_AS(view.to_string(), const assert_error&);
REQUIRE_THROWS_AS(view.to_string(), assert_error);
}
#endif
+18 -18
View File
@@ -7,14 +7,14 @@
#include <protozero/byteswap.hpp>
static int32_t check_swap_4(int32_t data) noexcept {
protozero::detail::byteswap_inplace(&data);
protozero::detail::byteswap_inplace(&data);
protozero::byteswap_inplace(&data);
protozero::byteswap_inplace(&data);
return data;
}
static int64_t check_swap_8(int64_t data) noexcept {
protozero::detail::byteswap_inplace(&data);
protozero::detail::byteswap_inplace(&data);
protozero::byteswap_inplace(&data);
protozero::byteswap_inplace(&data);
return data;
}
@@ -30,43 +30,43 @@ TEST_CASE("byte swapping") {
REQUIRE(0 == check_swap_8(0));
REQUIRE(1 == check_swap_8(1));
REQUIRE(-1 == check_swap_8(-1));
REQUIRE(395503ll == check_swap_8(395503ll));
REQUIRE(-804022ll == check_swap_8(-804022ll));
REQUIRE(3280329805ll == check_swap_8(3280329805ll));
REQUIRE(-2489204041ll == check_swap_8(-2489204041ll));
REQUIRE(395503LL == check_swap_8(395503LL));
REQUIRE(-804022LL == check_swap_8(-804022LL));
REQUIRE(3280329805LL == check_swap_8(3280329805LL));
REQUIRE(-2489204041LL == check_swap_8(-2489204041LL));
REQUIRE(std::numeric_limits<int64_t>::max() == check_swap_8(std::numeric_limits<int64_t>::max()));
REQUIRE(std::numeric_limits<int64_t>::min() == check_swap_8(std::numeric_limits<int64_t>::min()));
}
TEST_CASE("byte swap uint32_t") {
uint32_t a = 17;
protozero::detail::byteswap_inplace(&a);
protozero::detail::byteswap_inplace(&a);
protozero::byteswap_inplace(&a);
protozero::byteswap_inplace(&a);
REQUIRE(17 == a);
}
TEST_CASE("byte swap uint64_t") {
uint64_t a = 347529808;
protozero::detail::byteswap_inplace(&a);
protozero::detail::byteswap_inplace(&a);
protozero::byteswap_inplace(&a);
protozero::byteswap_inplace(&a);
REQUIRE(347529808 == a);
}
TEST_CASE("byte swap double") {
double a = 1.1;
protozero::detail::byteswap_inplace(&a);
protozero::detail::byteswap_inplace(&a);
protozero::byteswap_inplace(&a);
protozero::byteswap_inplace(&a);
REQUIRE(a == Approx(1.1));
}
TEST_CASE("byte swap float") {
float a = 1.1f;
protozero::detail::byteswap_inplace(&a);
protozero::detail::byteswap_inplace(&a);
float a = 1.1F;
protozero::byteswap_inplace(&a);
protozero::byteswap_inplace(&a);
REQUIRE(a == Approx(1.1f));
REQUIRE(a == Approx(1.1F));
}
+18
View File
@@ -0,0 +1,18 @@
#include <test.hpp>
TEST_CASE("default constructed varint_iterators are equal") {
protozero::const_varint_iterator<uint32_t> a{};
protozero::const_varint_iterator<uint32_t> b{};
protozero::iterator_range<protozero::const_varint_iterator<uint32_t>> r{};
REQUIRE(a == a);
REQUIRE(a == b);
REQUIRE(a == r.begin());
REQUIRE(a == r.end());
REQUIRE(r.empty());
REQUIRE(r.size() == 0); // NOLINT(readability-container-size-empty)
REQUIRE(r.begin() == r.end());
}
+74 -20
View File
@@ -26,12 +26,12 @@ TEST_CASE("varint") {
}
SECTION("encode/decode uint32") {
pw.add_uint32(1, 17u);
pw.add_uint32(1, 17U);
protozero::pbf_reader item{buffer};
REQUIRE(item.next());
SECTION("get") {
REQUIRE(17u == item.get_uint32());
REQUIRE(17U == item.get_uint32());
}
SECTION("skip") {
@@ -42,12 +42,12 @@ TEST_CASE("varint") {
}
SECTION("encode/decode uint64") {
pw.add_uint64(1, (1ull << 40u));
pw.add_uint64(1, (1ULL << 40U));
protozero::pbf_reader item{buffer};
REQUIRE(item.next());
SECTION("get") {
REQUIRE((1ull << 40u) == item.get_uint64());
REQUIRE((1ULL << 40U) == item.get_uint64());
}
SECTION("skip") {
@@ -58,47 +58,47 @@ TEST_CASE("varint") {
}
SECTION("short buffer while parsing varint") {
pw.add_uint64(1, (1ull << 40u));
pw.add_uint64(1, (1ULL << 40U));
buffer.resize(buffer.size() - 1); // "remove" last byte from buffer
protozero::pbf_reader item{buffer};
REQUIRE(item.next());
SECTION("get") {
REQUIRE_THROWS_AS(item.get_uint64(), const protozero::end_of_buffer_exception&);
REQUIRE_THROWS_AS(item.get_uint64(), protozero::end_of_buffer_exception);
}
SECTION("skip") {
REQUIRE_THROWS_AS(item.skip(), const protozero::end_of_buffer_exception&);
REQUIRE_THROWS_AS(item.skip(), protozero::end_of_buffer_exception);
}
}
SECTION("data corruption in buffer while parsing varint)") {
pw.add_uint64(1, (1ull << 20u));
buffer[buffer.size() - 1] += 0x80; // pretend the varint goes on
pw.add_uint64(1, (1ULL << 20U));
buffer[buffer.size() - 1] += static_cast<char>(0x80); // pretend the varint goes on
protozero::pbf_reader item{buffer};
REQUIRE(item.next());
SECTION("get") {
REQUIRE_THROWS_AS(item.get_uint64(), const protozero::end_of_buffer_exception&);
REQUIRE_THROWS_AS(item.get_uint64(), protozero::end_of_buffer_exception);
}
SECTION("skip") {
REQUIRE_THROWS_AS(item.skip(), const protozero::end_of_buffer_exception&);
REQUIRE_THROWS_AS(item.skip(), protozero::end_of_buffer_exception);
}
}
SECTION("data corruption in buffer while parsing varint (max length varint)") {
pw.add_uint64(1, std::numeric_limits<uint64_t>::max());
buffer[buffer.size() - 1] += 0x80; // pretend the varint goes on
buffer[buffer.size() - 1] += static_cast<char>(0x80); // pretend the varint goes on
protozero::pbf_reader item{buffer};
REQUIRE(item.next());
SECTION("get") {
REQUIRE_THROWS_AS(item.get_uint64(), const protozero::varint_too_long_exception&);
REQUIRE_THROWS_AS(item.get_uint64(), protozero::varint_too_long_exception);
}
SECTION("skip") {
REQUIRE_THROWS_AS(item.skip(), const protozero::varint_too_long_exception&);
REQUIRE_THROWS_AS(item.skip(), protozero::varint_too_long_exception);
}
}
}
@@ -107,15 +107,15 @@ TEST_CASE("10-byte varint") {
std::string buffer;
protozero::pbf_writer pw{buffer};
pw.add_uint64(1, 1);
buffer.back() = static_cast<char>(0xffu);
buffer.back() = static_cast<char>(0xffU);
for (int i = 0; i < 9; ++i) {
buffer.push_back(static_cast<char>(0xffu));
buffer.push_back(static_cast<char>(0xffU));
}
buffer.push_back(0x02);
protozero::pbf_reader item{buffer};
REQUIRE(item.next());
REQUIRE_THROWS_AS(item.get_uint64(), const protozero::varint_too_long_exception&);
REQUIRE_THROWS_AS(item.get_uint64(), protozero::varint_too_long_exception);
}
TEST_CASE("lots of varints back and forth") {
@@ -152,7 +152,7 @@ TEST_CASE("lots of varints back and forth") {
}
for (uint32_t i = 0; i < 63; ++i) {
const auto n = static_cast<int64_t>(1ull << i);
const auto n = static_cast<int64_t>(1ULL << i);
protozero::pbf_writer pw{buffer};
pw.add_int64(1, n);
protozero::pbf_reader item{buffer};
@@ -163,7 +163,7 @@ TEST_CASE("lots of varints back and forth") {
}
for (uint32_t i = 0; i < 63; ++i) {
const int64_t n = - static_cast<int64_t>(1ull << i);
const int64_t n = - static_cast<int64_t>(1ULL << i);
protozero::pbf_writer pw{buffer};
pw.add_int64(1, n);
protozero::pbf_reader item{buffer};
@@ -174,7 +174,7 @@ TEST_CASE("lots of varints back and forth") {
}
for (uint32_t i = 0; i < 64; ++i) {
const uint64_t n = 1ull << i;
const uint64_t n = 1ULL << i;
protozero::pbf_writer pw{buffer};
pw.add_uint64(1, n);
protozero::pbf_reader item{buffer};
@@ -185,3 +185,57 @@ TEST_CASE("lots of varints back and forth") {
}
}
TEST_CASE("skip_varint with empty buffer throws") {
const char* buffer = "";
REQUIRE_THROWS_AS(protozero::skip_varint(&buffer, buffer), protozero::end_of_buffer_exception);
}
TEST_CASE("call skip_varint with every possible value for single byte in buffer") {
char buffer[1];
for (int i = 0; i <= 127; ++i) {
buffer[0] = static_cast<char>(i);
const char* b = buffer;
protozero::skip_varint(&b, buffer + 1);
REQUIRE(b == buffer + 1);
}
for (int i = 128; i <= 255; ++i) {
buffer[0] = static_cast<char>(i);
const char* b = buffer;
REQUIRE_THROWS_AS(protozero::skip_varint(&b, buffer + 1), protozero::end_of_buffer_exception);
}
}
TEST_CASE("decode_varint with empty buffer throws") {
const char* buffer = "";
REQUIRE_THROWS_AS(protozero::decode_varint(&buffer, buffer), protozero::end_of_buffer_exception);
}
TEST_CASE("call decode_varint with every possible value for single byte in buffer") {
char buffer[1];
for (unsigned int i = 0; i <= 127; ++i) {
REQUIRE(protozero::length_of_varint(i) == 1);
buffer[0] = static_cast<char>(i);
const char* b = buffer;
REQUIRE(protozero::decode_varint(&b, buffer + 1) == i);
REQUIRE(b == buffer + 1);
}
for (unsigned int i = 128; i <= 255; ++i) {
REQUIRE(protozero::length_of_varint(i) == 2);
buffer[0] = static_cast<char>(i);
const char* b = buffer;
REQUIRE_THROWS_AS(protozero::decode_varint(&b, buffer + 1), protozero::end_of_buffer_exception);
}
}
TEST_CASE("check lengths of varint") {
REQUIRE(protozero::length_of_varint(0) == 1);
REQUIRE(protozero::length_of_varint(127) == 1);
REQUIRE(protozero::length_of_varint(128) == 2);
REQUIRE(protozero::length_of_varint(16383) == 2);
REQUIRE(protozero::length_of_varint(16384) == 3);
REQUIRE(protozero::length_of_varint(2097151) == 3);
REQUIRE(protozero::length_of_varint(2097152) == 4);
REQUIRE(protozero::length_of_varint(0xffffffffULL) == 5);
REQUIRE(protozero::length_of_varint(0xffffffffffffffffULL) == 10);
}
+9 -3
View File
@@ -22,22 +22,28 @@ static_assert(protozero::decode_zigzag32(1UL) == -1L, "test constexpr zigzag fun
static_assert(protozero::decode_zigzag32(2UL) == 1L, "test constexpr zigzag functions");
static_assert(protozero::decode_zigzag32(3UL) == -2L, "test constexpr zigzag functions");
static_assert(protozero::decode_zigzag32(4UL) == 2L, "test constexpr zigzag functions");
static_assert(protozero::decode_zigzag32(0xfffffffeUL) == 0x7fffffffL, "test constexpr zigzag functions");
static_assert(protozero::decode_zigzag32(0xfffffffdUL) == -0x7fffffffL, "test constexpr zigzag functions");
static_assert(protozero::decode_zigzag32(2 * static_cast<uint32_t>(std::numeric_limits<int32_t>::max()) ) == std::numeric_limits<int32_t>::max(), "test constexpr zigzag functions");
static_assert(protozero::decode_zigzag32(2 * static_cast<uint32_t>(std::numeric_limits<int32_t>::max()) - 1) == -std::numeric_limits<int32_t>::max(), "test constexpr zigzag functions");
// fails on Visual Studio 2017
//static_assert(protozero::decode_zigzag32(2 * static_cast<uint32_t>(std::numeric_limits<int32_t>::max()) - 1) == -std::numeric_limits<int32_t>::max(), "test constexpr zigzag functions");
static_assert(protozero::decode_zigzag64(0ULL) == 0LL, "test constexpr zigzag functions");
static_assert(protozero::decode_zigzag64(1ULL) == -1LL, "test constexpr zigzag functions");
static_assert(protozero::decode_zigzag64(2ULL) == 1LL, "test constexpr zigzag functions");
static_assert(protozero::decode_zigzag64(3ULL) == -2LL, "test constexpr zigzag functions");
static_assert(protozero::decode_zigzag64(4ULL) == 2LL, "test constexpr zigzag functions");
static_assert(protozero::decode_zigzag64(0xfffffffffffffffeULL) == 0x7fffffffffffffffLL, "test constexpr zigzag functions");
static_assert(protozero::decode_zigzag64(0xfffffffffffffffdULL) == -0x7fffffffffffffffLL, "test constexpr zigzag functions");
static_assert(protozero::decode_zigzag64(2 * static_cast<uint64_t>(std::numeric_limits<int64_t>::max()) ) == std::numeric_limits<int64_t>::max(), "test constexpr zigzag functions");
static_assert(protozero::decode_zigzag64(2 * static_cast<uint64_t>(std::numeric_limits<int64_t>::max()) - 1) == -std::numeric_limits<int64_t>::max(), "test constexpr zigzag functions");
inline constexpr int32_t zz32(int32_t val) {
inline constexpr int32_t zz32(int32_t val) noexcept {
return protozero::decode_zigzag32(protozero::encode_zigzag32(val));
}
inline constexpr int64_t zz64(int64_t val) {
inline constexpr int64_t zz64(int64_t val) noexcept {
return protozero::decode_zigzag64(protozero::encode_zigzag64(val));
}