Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions include/glaze/beve/read.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2096,7 +2096,7 @@ namespace glz
};

template <class T>
requires(tuple_t<T> || is_std_tuple<T>)
requires(tuple_t<T> || std_tuple_protocol<T>)
struct from<BEVE, T> final
{
template <auto Opts>
Expand All @@ -2113,17 +2113,23 @@ namespace glz
++it;

using V = std::decay_t<T>;
constexpr auto N = glz::tuple_size_v<V>;
static constexpr bool use_std_protocol = std_tuple_protocol<V> && !tuple_t<V>;
constexpr auto N = []() constexpr {
if constexpr (use_std_protocol)
return std::tuple_size_v<V>;
else
return glz::tuple_size_v<V>;
}();
if constexpr (Opts.partial_read) {
const auto n = int_from_compressed(ctx, it, end);
if (bool(ctx.error)) [[unlikely]] {
return;
}

if constexpr (is_std_tuple<T>) {
if constexpr (use_std_protocol) {
for_each_short_circuit<N>([&]<auto I>() {
if (I < n) {
parse<BEVE>::op<Opts>(std::get<I>(value), ctx, it, end);
parse<BEVE>::op<Opts>(get<I>(value), ctx, it, end);
return false; // continue
}
return true; // short circuit
Expand All @@ -2149,8 +2155,8 @@ namespace glz
return;
}

if constexpr (is_std_tuple<T>) {
for_each<N>([&]<size_t I>() { parse<BEVE>::op<Opts>(std::get<I>(value), ctx, it, end); });
if constexpr (use_std_protocol) {
for_each<N>([&]<size_t I>() { parse<BEVE>::op<Opts>(get<I>(value), ctx, it, end); });
}
else {
for_each<N>([&]<size_t I>() { parse<BEVE>::op<Opts>(glz::get<I>(value), ctx, it, end); });
Expand Down
14 changes: 10 additions & 4 deletions include/glaze/beve/size.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -788,20 +788,26 @@ namespace glz
};

template <class T>
requires(tuple_t<T> || is_std_tuple<T>)
requires(tuple_t<T> || std_tuple_protocol<T>)
struct calculate_size<BEVE, T>
{
template <auto Opts>
[[nodiscard]] static size_t op(auto&& value, size_t offset = 0)
{
static constexpr auto N = glz::tuple_size_v<T>;
static constexpr bool use_std_protocol = std_tuple_protocol<T> && !tuple_t<T>;
static constexpr auto N = []() constexpr {
if constexpr (use_std_protocol)
return std::tuple_size_v<std::remove_cvref_t<T>>;
else
return glz::tuple_size_v<T>;
}();

size_t result = 1; // generic_array tag
result += compressed_int_size<N>(); // element count

if constexpr (is_std_tuple<T>) {
if constexpr (use_std_protocol) {
[&]<size_t... I>(std::index_sequence<I...>) {
((result += calculate_size<BEVE, void>::template op<Opts>(std::get<I>(value), offset + result)), ...);
((result += calculate_size<BEVE, void>::template op<Opts>(get<I>(value), offset + result)), ...);
}(std::make_index_sequence<N>{});
}
else {
Expand Down
14 changes: 10 additions & 4 deletions include/glaze/beve/write.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1582,7 +1582,7 @@ namespace glz
};

template <class T>
requires(tuple_t<T> || is_std_tuple<T>)
requires(tuple_t<T> || std_tuple_protocol<T>)
struct to<BEVE, T> final
{
template <auto Opts, class B>
Expand All @@ -1593,15 +1593,21 @@ namespace glz
}
dump<tag::generic_array>(b, ix);

static constexpr auto N = glz::tuple_size_v<T>;
static constexpr bool use_std_protocol = std_tuple_protocol<T> && !tuple_t<T>;
static constexpr auto N = []() constexpr {
if constexpr (use_std_protocol)
return std::tuple_size_v<std::remove_cvref_t<T>>;
else
return glz::tuple_size_v<T>;
}();
dump_compressed_int<N>(ctx, b, ix);
if (bool(ctx.error)) [[unlikely]] {
return;
}

if constexpr (is_std_tuple<T>) {
if constexpr (use_std_protocol) {
[&]<size_t... I>(std::index_sequence<I...>) {
((serialize<BEVE>::op<Opts>(std::get<I>(value), ctx, b, ix), bool(ctx.error) ? void() : void()), ...);
((serialize<BEVE>::op<Opts>(get<I>(value), ctx, b, ix), bool(ctx.error) ? void() : void()), ...);
}(std::make_index_sequence<N>{});
}
else {
Expand Down
14 changes: 10 additions & 4 deletions include/glaze/cbor/read.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1461,7 +1461,7 @@ namespace glz

// Tuples
template <class T>
requires(tuple_t<T> || is_std_tuple<T>)
requires(tuple_t<T> || std_tuple_protocol<T>)
struct from<CBOR, T> final
{
template <auto Opts>
Expand All @@ -1487,7 +1487,13 @@ namespace glz
}

using V = std::decay_t<T>;
static constexpr auto N = glz::tuple_size_v<V>;
static constexpr bool use_std_protocol = std_tuple_protocol<V> && !tuple_t<V>;
static constexpr auto N = []() constexpr {
if constexpr (use_std_protocol)
return std::tuple_size_v<V>;
else
return glz::tuple_size_v<V>;
}();

uint64_t count = cbor_detail::decode_arg(ctx, it, end, additional_info);
if (bool(ctx.error)) [[unlikely]]
Expand All @@ -1498,8 +1504,8 @@ namespace glz
return;
}

if constexpr (is_std_tuple<T>) {
for_each<N>([&]<size_t I>() { parse<CBOR>::op<Opts>(std::get<I>(value), ctx, it, end); });
if constexpr (use_std_protocol) {
for_each<N>([&]<size_t I>() { parse<CBOR>::op<Opts>(get<I>(value), ctx, it, end); });
}
else {
for_each<N>([&]<size_t I>() { parse<CBOR>::op<Opts>(glz::get<I>(value), ctx, it, end); });
Expand Down
14 changes: 10 additions & 4 deletions include/glaze/cbor/write.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -875,20 +875,26 @@ namespace glz

// Tuples
template <class T>
requires(tuple_t<T> || is_std_tuple<T>)
requires(tuple_t<T> || std_tuple_protocol<T>)
struct to<CBOR, T> final
{
template <auto Opts>
static void op(auto&& value, is_context auto&& ctx, auto&& b, auto& ix)
{
static constexpr auto N = glz::tuple_size_v<T>;
static constexpr bool use_std_protocol = std_tuple_protocol<T> && !tuple_t<T>;
static constexpr auto N = []() constexpr {
if constexpr (use_std_protocol)
return std::tuple_size_v<std::remove_cvref_t<T>>;
else
return glz::tuple_size_v<T>;
}();
if (!cbor_detail::encode_arg_cx<N>(ctx, cbor::major::array, b, ix)) [[unlikely]] {
return;
}

if constexpr (is_std_tuple<T>) {
if constexpr (use_std_protocol) {
[&]<size_t... I>(std::index_sequence<I...>) {
(serialize<CBOR>::op<Opts>(std::get<I>(value), ctx, b, ix), ...);
(serialize<CBOR>::op<Opts>(get<I>(value), ctx, b, ix), ...);
}(std::make_index_sequence<N>{});
}
else {
Expand Down
14 changes: 10 additions & 4 deletions include/glaze/eetf/read.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ namespace glz
};

template <class T>
requires(tuple_t<T> || is_std_tuple<T>)
requires(tuple_t<T> || std_tuple_protocol<T>)
struct from<EETF, T> final
{
template <auto Opts>
Expand All @@ -257,15 +257,21 @@ namespace glz
it += index;

using V = std::decay_t<T>;
constexpr auto N = glz::tuple_size_v<V>;
static constexpr bool use_std_protocol = std_tuple_protocol<V> && !tuple_t<V>;
constexpr auto N = []() constexpr {
if constexpr (use_std_protocol)
return std::tuple_size_v<V>;
else
return glz::tuple_size_v<V>;
}();

if (fields_count != N) {
ctx.error = error_code::syntax_error;
return;
}

if constexpr (is_std_tuple<T>) {
for_each<N>([&]<size_t I>() { parse<EETF>::op<Opts>(std::get<I>(value), ctx, it, end); });
if constexpr (use_std_protocol) {
for_each<N>([&]<size_t I>() { parse<EETF>::op<Opts>(get<I>(value), ctx, it, end); });
}
else {
for_each<N>([&]<size_t I>() { parse<EETF>::op<Opts>(glz::get<I>(value), ctx, it, end); });
Expand Down
14 changes: 10 additions & 4 deletions include/glaze/eetf/write.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ namespace glz
};

template <class T>
requires(tuple_t<T> || is_std_tuple<T>)
requires(tuple_t<T> || std_tuple_protocol<T>)
struct to<EETF, T> final
{
template <auto Opts, class V, class... Args>
Expand All @@ -142,16 +142,22 @@ namespace glz
requires(check_no_header(Opts))
GLZ_ALWAYS_INLINE static void op(auto&& value, Ctx&& ctx, Args&&... args) noexcept
{
static constexpr auto N = glz::tuple_size_v<T>;
static constexpr bool use_std_protocol = std_tuple_protocol<T> && !tuple_t<T>;
static constexpr auto N = []() constexpr {
if constexpr (use_std_protocol)
return std::tuple_size_v<std::remove_cvref_t<T>>;
else
return glz::tuple_size_v<T>;
}();

encode_tuple_header(N, ctx, std::forward<Args>(args)...);
if (bool(ctx.error)) [[unlikely]] {
return;
}

if constexpr (is_std_tuple<T>) {
if constexpr (use_std_protocol) {
[&]<size_t... I>(std::index_sequence<I...>) {
(serialize<EETF>::op<Opts>(std::get<I>(value), ctx, args...), ...);
(serialize<EETF>::op<Opts>(get<I>(value), ctx, args...), ...);
}(std::make_index_sequence<N>{});
}
else {
Expand Down
12 changes: 6 additions & 6 deletions include/glaze/json/flatten_map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,13 @@ namespace glz
write_flatten_map_elements<Opts>(get_member(value, glz::get<I>(meta_v<V>)), ctx, b, ix, first);
});
}
else if constexpr (is_std_tuple<V>) {
static constexpr auto N = glz::tuple_size_v<V>;
else if constexpr (std_tuple_protocol<V> && !tuple_t<V>) {
static constexpr auto N = std::tuple_size_v<V>;
for_each<N>([&]<size_t I>() {
if (bool(ctx.error)) [[unlikely]] {
return;
}
write_flatten_map_elements<Opts>(std::get<I>(value), ctx, b, ix, first);
write_flatten_map_elements<Opts>(get<I>(value), ctx, b, ix, first);
});
}
else if constexpr (tuple_t<V>) {
Expand Down Expand Up @@ -177,13 +177,13 @@ namespace glz
read_flatten_map_elements<Opts>(get_member(value, glz::get<I>(meta_v<V>)), ctx, it, end, first);
});
}
else if constexpr (is_std_tuple<V>) {
static constexpr auto N = glz::tuple_size_v<V>;
else if constexpr (std_tuple_protocol<V> && !tuple_t<V>) {
static constexpr auto N = std::tuple_size_v<V>;
for_each<N>([&]<size_t I>() {
if (bool(ctx.error)) [[unlikely]] {
return;
}
read_flatten_map_elements<Opts>(std::get<I>(value), ctx, it, end, first);
read_flatten_map_elements<Opts>(get<I>(value), ctx, it, end, first);
});
}
else if constexpr (tuple_t<V>) {
Expand Down
16 changes: 11 additions & 5 deletions include/glaze/json/jmespath.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,14 +425,14 @@ namespace glz
{
template <auto Opts = opts{}, class T>
requires(Opts.format == JSON && not readable_array_t<T> &&
not(tuple_t<std::decay_t<T>> || is_std_tuple<std::decay_t<T>>))
not(tuple_t<std::decay_t<T>> || std_tuple_protocol<std::decay_t<T>>))
inline void handle_slice(const jmespath::ArrayParseResult&, T&&, context& ctx, auto&&, auto&&)
{
ctx.error = error_code::syntax_error;
}

template <auto Opts = opts{}, class T>
requires(Opts.format == JSON && (tuple_t<std::decay_t<T>> || is_std_tuple<std::decay_t<T>>))
requires(Opts.format == JSON && (tuple_t<std::decay_t<T>> || std_tuple_protocol<std::decay_t<T>>))
inline void handle_slice(const jmespath::ArrayParseResult& decomposed_key, T&& value, context& ctx, auto&& it,
auto end)
{
Expand Down Expand Up @@ -462,7 +462,13 @@ namespace glz

// Iterate tuple elements
using TupleType = std::decay_t<T>;
constexpr size_t N = glz::tuple_size_v<TupleType>;
static constexpr bool use_std_protocol = std_tuple_protocol<TupleType> && !tuple_t<TupleType>;
constexpr size_t N = []() constexpr {
if constexpr (use_std_protocol)
return std::tuple_size_v<TupleType>;
else
return glz::tuple_size_v<TupleType>;
}();

for_each<N>([&]<size_t I>() {
if (bool(ctx.error)) return;
Expand Down Expand Up @@ -499,8 +505,8 @@ namespace glz
return;
}

if constexpr (is_std_tuple<TupleType>) {
parse<Opts.format>::template op<Opts>(std::get<I>(value), ctx, it, end);
if constexpr (use_std_protocol) {
parse<Opts.format>::template op<Opts>(get<I>(value), ctx, it, end);
}
else {
parse<Opts.format>::template op<Opts>(glz::get<I>(value), ctx, it, end);
Expand Down
30 changes: 11 additions & 19 deletions include/glaze/json/ndjson.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ namespace glz
};

template <class T>
requires glaze_array_t<T> || tuple_t<T> || is_std_tuple<T>
requires glaze_array_t<T> || tuple_t<T> || std_tuple_protocol<T>
struct from<NDJSON, T>
{
template <auto Opts>
Expand All @@ -116,10 +116,14 @@ namespace glz
return;
}

static constexpr bool use_std_protocol = std_tuple_protocol<T> && !tuple_t<T>;
static constexpr auto N = []() constexpr {
if constexpr (glaze_array_t<T>) {
return reflect<T>::size;
}
else if constexpr (use_std_protocol) {
return std::tuple_size_v<T>;
}
else {
return glz::tuple_size_v<T>;
}
Expand Down Expand Up @@ -148,8 +152,8 @@ namespace glz
if constexpr (I != 0) {
read_new_lines();
}
if constexpr (is_std_tuple<T>) {
parse<JSON>::op<Opts>(std::get<I>(value), ctx, it, end);
if constexpr (use_std_protocol) {
parse<JSON>::op<Opts>(get<I>(value), ctx, it, end);
}
else if constexpr (glaze_array_t<T>) {
parse<JSON>::op<Opts>(get_member(value, glz::get<I>(meta_v<T>)), ctx, it, end);
Expand Down Expand Up @@ -223,29 +227,17 @@ namespace glz
};

template <class T>
requires is_std_tuple<std::decay_t<T>>
requires(std_tuple_protocol<std::decay_t<T>> && !tuple_t<std::decay_t<T>> && !glaze_array_t<std::decay_t<T>>)
struct to<NDJSON, T>
{
template <auto Opts, class... Args>
static void op(auto&& value, is_context auto&& ctx, Args&&... args)
{
static constexpr auto N = []() constexpr {
if constexpr (glaze_array_t<std::decay_t<T>>) {
return glz::tuple_size_v<meta_t<std::decay_t<T>>>;
}
else {
return glz::tuple_size_v<std::decay_t<T>>;
}
}();

using V = std::decay_t<T>;
static constexpr auto N = std::tuple_size_v<V>;

for_each<N>([&]<auto I>() {
if constexpr (glaze_array_t<V>) {
serialize<JSON>::op<Opts>(value.*std::get<I>(meta_v<V>), ctx, std::forward<Args>(args)...);
}
else {
serialize<JSON>::op<Opts>(std::get<I>(value), ctx, std::forward<Args>(args)...);
}
serialize<JSON>::op<Opts>(get<I>(value), ctx, std::forward<Args>(args)...);
constexpr bool needs_new_line = I < N - 1;
if constexpr (needs_new_line) {
dump('\n', std::forward<Args>(args)...);
Expand Down
Loading
Loading