From 91f5935f15e6f8e52908008ed2803aaabf6cdddb Mon Sep 17 00:00:00 2001 From: "Dr. Patrick Urbanke" Date: Sun, 11 May 2025 10:47:39 +0200 Subject: [PATCH] Use fold expressions inside the literals --- include/rfl/Literal.hpp | 45 ++++++++++------------------- include/rfl/internal/find_index.hpp | 16 ++++++++++ tests/json/test_literal.cpp | 5 ++++ 3 files changed, 36 insertions(+), 30 deletions(-) diff --git a/include/rfl/Literal.hpp b/include/rfl/Literal.hpp index 9aa1b39d..f45817c5 100644 --- a/include/rfl/Literal.hpp +++ b/include/rfl/Literal.hpp @@ -13,6 +13,7 @@ #include "Result.hpp" #include "Tuple.hpp" #include "internal/StringLiteral.hpp" +#include "internal/find_index.hpp" #include "internal/no_duplicate_field_names.hpp" namespace rfl { @@ -95,31 +96,24 @@ class Literal { /// Determines whether the literal contains any of the strings in the other /// literal at compile time. - template + template static constexpr bool contains_any() { - if constexpr (_i == num_fields_) { - return false; - } else { - constexpr auto name = find_name_within_own_fields<_i>(); - return OtherLiteralType::template contains() || - contains_any(); - } + return [](const std::integer_sequence&) { + return (false || ... || + OtherLiteralType::template contains< + find_name_within_own_fields<_is>()>()); + }(std::make_integer_sequence()); } /// Determines whether the literal contains all of the strings in the other /// literal at compile time. - template + template static constexpr bool contains_all() { - if constexpr (_i == num_fields_) { - return _n_found == OtherLiteralType::num_fields_; - } else { - constexpr auto name = find_name_within_own_fields<_i>(); - if constexpr (OtherLiteralType::template contains()) { - return contains_all(); - } else { - return contains_all(); - } - } + return [](const std::integer_sequence&) { + return (true && ... && + OtherLiteralType::template contains< + find_name_within_own_fields<_is>()>()); + }(std::make_integer_sequence()); } /// Determines whether the literal has duplicate strings at compile time. @@ -332,18 +326,9 @@ class Literal { } /// Finds the value of a string literal at compile time. - template + template static constexpr int find_value_of() { - if constexpr (_i == num_fields_) { - return -1; - } else { - using FieldType = tuple_element_t<_i, FieldsType>; - if constexpr (FieldType::name_ == _name) { - return _i; - } else { - return find_value_of<_name, _i + 1>(); - } - } + return internal::find_index_or_minus_one<_name, FieldsType>(); } /// Whether the literal contains this string. diff --git a/include/rfl/internal/find_index.hpp b/include/rfl/internal/find_index.hpp index 1db6d8c6..fdc2e8f9 100644 --- a/include/rfl/internal/find_index.hpp +++ b/include/rfl/internal/find_index.hpp @@ -45,6 +45,22 @@ constexpr static int find_index() { return ix; } +/// Finds the index of the field signified by _field_name or -1. +template +constexpr static int find_index_or_minus_one() { + if constexpr (rfl::tuple_size_v == 0) { + return -1; + } else { + constexpr int ix = wrap_fields<_field_name, Fields>( + std::make_integer_sequence>()); + if constexpr (rfl::tuple_element_t::name_ == _field_name) { + return ix; + } else { + return -1; + } + } +} + } // namespace internal } // namespace rfl diff --git a/tests/json/test_literal.cpp b/tests/json/test_literal.cpp index cba6d6e0..58d51da1 100644 --- a/tests/json/test_literal.cpp +++ b/tests/json/test_literal.cpp @@ -19,6 +19,11 @@ struct Person { }; TEST(json, test_literal) { + static_assert(!FirstName::template contains_any(), + "Must be false."); + static_assert(FirstName::template contains_any(), "Must be true."); + static_assert(FirstName::template contains_all(), "Must be true."); + const auto bart = Person{.first_name = FirstName::make<"Bart">()}; write_and_read(bart,