Skip to content

Commit

Permalink
Get rid of complex wrap helpers (#843)
Browse files Browse the repository at this point in the history
Signed-off-by: Juan Cruz Viotti <[email protected]>
  • Loading branch information
jviotti authored Oct 8, 2024
1 parent 3dc921a commit c9743d0
Show file tree
Hide file tree
Showing 15 changed files with 268 additions and 271 deletions.
1 change: 0 additions & 1 deletion src/runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ noa_library(NAMESPACE sourcemeta PROJECT jsonbinpack NAME runtime
output_stream.h
encoder_context.h
encoding.h
encoding_wrap.h
SOURCES
input_stream.cc
output_stream.cc
Expand Down
33 changes: 19 additions & 14 deletions src/runtime/decoder_any.cc
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
#include <sourcemeta/jsonbinpack/numeric.h>
#include <sourcemeta/jsonbinpack/runtime_decoder.h>

#include <sourcemeta/jsonbinpack/runtime_encoding_wrap.h>

#include "unreachable.h"

#include <cassert> // assert
#include <cstdint> // std::uint8_t, std::uint16_t, std::uint64_t
#include <memory> // std::make_shared

namespace sourcemeta::jsonbinpack {

Expand Down Expand Up @@ -118,28 +117,34 @@ auto Decoder::ANY_PACKED_TYPE_TAG_BYTE_PREFIX(
case TYPE_ARRAY:
return subtype == 0 ? this->FIXED_TYPED_ARRAY(
{this->get_varint() + uint_max<5>,
wrap(sourcemeta::jsonbinpack::
ANY_PACKED_TYPE_TAG_BYTE_PREFIX{}),
std::make_shared<Encoding>(
sourcemeta::jsonbinpack::
ANY_PACKED_TYPE_TAG_BYTE_PREFIX{}),
{}})
: this->FIXED_TYPED_ARRAY(
{static_cast<std::uint64_t>(subtype - 1),
wrap(sourcemeta::jsonbinpack::
ANY_PACKED_TYPE_TAG_BYTE_PREFIX{}),
std::make_shared<Encoding>(
sourcemeta::jsonbinpack::
ANY_PACKED_TYPE_TAG_BYTE_PREFIX{}),
{}});
case TYPE_OBJECT:
return subtype == 0
? this->FIXED_TYPED_ARBITRARY_OBJECT(
{this->get_varint() + uint_max<5>,
wrap(sourcemeta::jsonbinpack::
PREFIX_VARINT_LENGTH_STRING_SHARED{}),
wrap(sourcemeta::jsonbinpack::
ANY_PACKED_TYPE_TAG_BYTE_PREFIX{})})
std::make_shared<Encoding>(
sourcemeta::jsonbinpack::
PREFIX_VARINT_LENGTH_STRING_SHARED{}),
std::make_shared<Encoding>(
sourcemeta::jsonbinpack::
ANY_PACKED_TYPE_TAG_BYTE_PREFIX{})})
: this->FIXED_TYPED_ARBITRARY_OBJECT(
{static_cast<std::uint64_t>(subtype - 1),
wrap(sourcemeta::jsonbinpack::
PREFIX_VARINT_LENGTH_STRING_SHARED{}),
wrap(sourcemeta::jsonbinpack::
ANY_PACKED_TYPE_TAG_BYTE_PREFIX{})});
std::make_shared<Encoding>(
sourcemeta::jsonbinpack::
PREFIX_VARINT_LENGTH_STRING_SHARED{}),
std::make_shared<Encoding>(
sourcemeta::jsonbinpack::
ANY_PACKED_TYPE_TAG_BYTE_PREFIX{})});
}

// We should never get here. If so, it is definitely a bug
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/decoder_array.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ auto Decoder::FIXED_TYPED_ARRAY(const struct FIXED_TYPED_ARRAY &options)
sourcemeta::jsontoolkit::JSON::make_array();
for (std::size_t index = 0; index < options.size; index++) {
const Encoding &encoding{prefix_encodings > index
? options.prefix_encodings[index].value
: options.encoding->value};
? options.prefix_encodings[index]
: *(options.encoding)};
result.push_back(this->read(encoding));
}

Expand Down
8 changes: 4 additions & 4 deletions src/runtime/decoder_object.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ auto Decoder::FIXED_TYPED_ARBITRARY_OBJECT(
sourcemeta::jsontoolkit::JSON::make_object();
for (std::size_t index = 0; index < options.size; index++) {
const sourcemeta::jsontoolkit::JSON key =
this->read(options.key_encoding->value);
this->read(*(options.key_encoding));
assert(key.is_string());
document.assign(key.to_string(), this->read(options.encoding->value));
document.assign(key.to_string(), this->read(*(options.encoding)));
}

assert(document.size() == options.size);
Expand All @@ -29,9 +29,9 @@ auto Decoder::VARINT_TYPED_ARBITRARY_OBJECT(
sourcemeta::jsontoolkit::JSON::make_object();
for (std::size_t index = 0; index < size; index++) {
const sourcemeta::jsontoolkit::JSON key =
this->read(options.key_encoding->value);
this->read(*(options.key_encoding));
assert(key.is_string());
document.assign(key.to_string(), this->read(options.encoding->value));
document.assign(key.to_string(), this->read(*(options.encoding)));
}

assert(document.size() == size);
Expand Down
9 changes: 5 additions & 4 deletions src/runtime/encoder_any.cc
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#include <sourcemeta/jsonbinpack/numeric.h>
#include <sourcemeta/jsonbinpack/runtime_encoder.h>
#include <sourcemeta/jsonbinpack/runtime_encoding_wrap.h>

#include "unreachable.h"

#include <algorithm> // std::find_if
#include <cassert> // assert
#include <cstdint> // std::uint8_t, std::int64_t, std::uint64_t
#include <iterator> // std::cbegin, std::cend, std::distance
#include <memory> // std::make_shared
#include <utility> // std::move

namespace sourcemeta::jsonbinpack {
Expand Down Expand Up @@ -161,7 +161,8 @@ auto Encoder::ANY_PACKED_TYPE_TAG_BYTE_PREFIX(

Encoding encoding{
sourcemeta::jsonbinpack::ANY_PACKED_TYPE_TAG_BYTE_PREFIX{}};
this->FIXED_TYPED_ARRAY(document, {size, wrap(std::move(encoding)), {}});
this->FIXED_TYPED_ARRAY(
document, {size, std::make_shared<Encoding>(std::move(encoding)), {}});
} else if (document.is_object()) {
const auto size{document.size()};
if (size >= uint_max<5>) {
Expand All @@ -177,8 +178,8 @@ auto Encoder::ANY_PACKED_TYPE_TAG_BYTE_PREFIX(
Encoding value_encoding{
sourcemeta::jsonbinpack::ANY_PACKED_TYPE_TAG_BYTE_PREFIX{}};
this->FIXED_TYPED_ARBITRARY_OBJECT(
document,
{size, wrap(std::move(key_encoding)), wrap(std::move(value_encoding))});
document, {size, std::make_shared<Encoding>(std::move(key_encoding)),
std::make_shared<Encoding>(std::move(value_encoding))});
} else {
// We should never get here
unreachable();
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/encoder_array.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ auto Encoder::FIXED_TYPED_ARRAY(const sourcemeta::jsontoolkit::JSON &document,
assert(prefix_encodings <= document.size());
for (std::size_t index = 0; index < options.size; index++) {
const Encoding &encoding{prefix_encodings > index
? options.prefix_encodings[index].value
: options.encoding->value};
? options.prefix_encodings[index]
: *(options.encoding)};
this->write(document.at(index), encoding);
}
}
Expand Down
10 changes: 4 additions & 6 deletions src/runtime/encoder_object.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ auto Encoder::FIXED_TYPED_ARBITRARY_OBJECT(
assert(document.size() == options.size);

for (const auto &[key, value] : document.as_object()) {
this->write(sourcemeta::jsontoolkit::JSON{key},
options.key_encoding->value);
this->write(value, options.encoding->value);
this->write(sourcemeta::jsontoolkit::JSON{key}, *(options.key_encoding));
this->write(value, *(options.encoding));
}
}

Expand All @@ -25,9 +24,8 @@ auto Encoder::VARINT_TYPED_ARBITRARY_OBJECT(
this->put_varint(size);

for (const auto &[key, value] : document.as_object()) {
this->write(sourcemeta::jsontoolkit::JSON{key},
options.key_encoding->value);
this->write(value, options.encoding->value);
this->write(sourcemeta::jsontoolkit::JSON{key}, *(options.key_encoding));
this->write(value, *(options.encoding));
}
}

Expand Down
95 changes: 53 additions & 42 deletions src/runtime/include/sourcemeta/jsonbinpack/runtime_encoding.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,47 @@

namespace sourcemeta::jsonbinpack {

// We cannot directly create an Encoding variant type whose values potentially
// include other Encoding instances. As a workaround, we have a helper
// encoding wrapper that we can use as an incomplete type
struct __internal_encoding_wrapper;
// Use these alias types. Never use the internal wrapper type directly
using SingleEncoding = std::shared_ptr<__internal_encoding_wrapper>;
using MultipleEncodings = std::vector<__internal_encoding_wrapper>;
// Forward declarations for the sole purpose of being bale to define circular
// structures
#ifndef DOXYGEN
struct BOUNDED_MULTIPLE_8BITS_ENUM_FIXED;
struct FLOOR_MULTIPLE_ENUM_VARINT;
struct ROOF_MULTIPLE_MIRROR_ENUM_VARINT;
struct ARBITRARY_MULTIPLE_ZIGZAG_VARINT;
struct DOUBLE_VARINT_TUPLE;
struct BYTE_CHOICE_INDEX;
struct LARGE_CHOICE_INDEX;
struct TOP_LEVEL_BYTE_CHOICE_INDEX;
struct CONST_NONE;
struct UTF8_STRING_NO_LENGTH;
struct FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED;
struct ROOF_VARINT_PREFIX_UTF8_STRING_SHARED;
struct BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED;
struct RFC3339_DATE_INTEGER_TRIPLET;
struct PREFIX_VARINT_LENGTH_STRING_SHARED;
struct FIXED_TYPED_ARRAY;
struct BOUNDED_8BITS_TYPED_ARRAY;
struct FLOOR_TYPED_ARRAY;
struct ROOF_TYPED_ARRAY;
struct FIXED_TYPED_ARBITRARY_OBJECT;
struct VARINT_TYPED_ARBITRARY_OBJECT;
struct ANY_PACKED_TYPE_TAG_BYTE_PREFIX;
#endif

/// @ingroup runtime
/// Represents an encoding
using Encoding = std::variant<
BOUNDED_MULTIPLE_8BITS_ENUM_FIXED, FLOOR_MULTIPLE_ENUM_VARINT,
ROOF_MULTIPLE_MIRROR_ENUM_VARINT, ARBITRARY_MULTIPLE_ZIGZAG_VARINT,
DOUBLE_VARINT_TUPLE, BYTE_CHOICE_INDEX, LARGE_CHOICE_INDEX,
TOP_LEVEL_BYTE_CHOICE_INDEX, CONST_NONE, UTF8_STRING_NO_LENGTH,
FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED,
ROOF_VARINT_PREFIX_UTF8_STRING_SHARED,
BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED, RFC3339_DATE_INTEGER_TRIPLET,
PREFIX_VARINT_LENGTH_STRING_SHARED, FIXED_TYPED_ARRAY,
BOUNDED_8BITS_TYPED_ARRAY, FLOOR_TYPED_ARRAY, ROOF_TYPED_ARRAY,
FIXED_TYPED_ARBITRARY_OBJECT, VARINT_TYPED_ARBITRARY_OBJECT,
ANY_PACKED_TYPE_TAG_BYTE_PREFIX>;

/// @ingroup runtime
/// @defgroup encoding_integer Integer Encodings
Expand Down Expand Up @@ -703,9 +737,9 @@ struct FIXED_TYPED_ARRAY {
/// The array length
const std::uint64_t size;
/// Element encoding
const SingleEncoding encoding;
const std::shared_ptr<Encoding> encoding;
/// Positional encodings
const MultipleEncodings prefix_encodings;
const std::vector<Encoding> prefix_encodings;
};

// clang-format off
Expand Down Expand Up @@ -754,9 +788,9 @@ struct BOUNDED_8BITS_TYPED_ARRAY {
/// The maximum length of the array
const std::uint64_t maximum;
/// Element encoding
const SingleEncoding encoding;
const std::shared_ptr<Encoding> encoding;
/// Positional encodings
const MultipleEncodings prefix_encodings;
const std::vector<Encoding> prefix_encodings;
};

// clang-format off
Expand Down Expand Up @@ -800,9 +834,9 @@ struct FLOOR_TYPED_ARRAY {
/// The minimum length of the array
const std::uint64_t minimum;
/// Element encoding
const SingleEncoding encoding;
const std::shared_ptr<Encoding> encoding;
/// Positional encodings
const MultipleEncodings prefix_encodings;
const std::vector<Encoding> prefix_encodings;
};

// clang-format off
Expand Down Expand Up @@ -845,9 +879,9 @@ struct ROOF_TYPED_ARRAY {
/// The maximum length of the array
const std::uint64_t maximum;
/// Element encoding
const SingleEncoding encoding;
const std::shared_ptr<Encoding> encoding;
/// Positional encodings
const MultipleEncodings prefix_encodings;
const std::vector<Encoding> prefix_encodings;
};

/// @}
Expand Down Expand Up @@ -902,9 +936,9 @@ struct FIXED_TYPED_ARBITRARY_OBJECT {
/// The object size
const std::uint64_t size;
/// Key encoding
const SingleEncoding key_encoding;
const std::shared_ptr<Encoding> key_encoding;
/// Value encoding
const SingleEncoding encoding;
const std::shared_ptr<Encoding> encoding;
};

// clang-format off
Expand Down Expand Up @@ -946,9 +980,9 @@ struct FIXED_TYPED_ARBITRARY_OBJECT {
// clang-format on
struct VARINT_TYPED_ARBITRARY_OBJECT {
/// Key encoding
const SingleEncoding key_encoding;
const std::shared_ptr<Encoding> key_encoding;
/// Value encoding
const SingleEncoding encoding;
const std::shared_ptr<Encoding> encoding;
};

/// @}
Expand Down Expand Up @@ -1013,29 +1047,6 @@ static_assert(SUBTYPE_LONG_STRING_BASE_EXPONENT_10 == 10);
/// @}
// clang-format on

/// @ingroup runtime
/// Represents an encoding
using Encoding = std::variant<
BOUNDED_MULTIPLE_8BITS_ENUM_FIXED, FLOOR_MULTIPLE_ENUM_VARINT,
ROOF_MULTIPLE_MIRROR_ENUM_VARINT, ARBITRARY_MULTIPLE_ZIGZAG_VARINT,
DOUBLE_VARINT_TUPLE, BYTE_CHOICE_INDEX, LARGE_CHOICE_INDEX,
TOP_LEVEL_BYTE_CHOICE_INDEX, CONST_NONE, UTF8_STRING_NO_LENGTH,
FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED,
ROOF_VARINT_PREFIX_UTF8_STRING_SHARED,
BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED, RFC3339_DATE_INTEGER_TRIPLET,
PREFIX_VARINT_LENGTH_STRING_SHARED, FIXED_TYPED_ARRAY,
BOUNDED_8BITS_TYPED_ARRAY, FLOOR_TYPED_ARRAY, ROOF_TYPED_ARRAY,
FIXED_TYPED_ARBITRARY_OBJECT, VARINT_TYPED_ARBITRARY_OBJECT,
ANY_PACKED_TYPE_TAG_BYTE_PREFIX>;

// Helper definitions that rely on the Encoding data type
#ifndef DOXYGEN
// Ignore this definition on the documentation
struct __internal_encoding_wrapper {
const Encoding value;
};
#endif

} // namespace sourcemeta::jsonbinpack

#endif
54 changes: 0 additions & 54 deletions src/runtime/include/sourcemeta/jsonbinpack/runtime_encoding_wrap.h

This file was deleted.

Loading

0 comments on commit c9743d0

Please sign in to comment.