From 5bb365fe0af37e3cb398a1fb06fc0711dd98e29b Mon Sep 17 00:00:00 2001 From: "Dr. Patrick Urbanke" Date: Mon, 20 Oct 2025 22:22:59 +0200 Subject: [PATCH 01/10] Added checks to make sure headers are self-contained; addresses #528 --- CMakeLists.txt | 84 ++++++++++++------- include/rfl/Processors.hpp | 7 +- include/rfl/Timestamp.hpp | 1 + include/rfl/Tuple.hpp | 8 +- include/rfl/avro/Parser.hpp | 4 +- include/rfl/avro/SchemaImpl.hpp | 3 +- include/rfl/avro/Writer.hpp | 72 ++++++++++------ include/rfl/bson/Parser.hpp | 5 +- include/rfl/bson/Reader.hpp | 13 ++- include/rfl/capnproto/Parser.hpp | 5 +- include/rfl/capnproto/Reader.hpp | 6 +- include/rfl/capnproto/SchemaImpl.hpp | 3 +- include/rfl/capnproto/is_named_type.hpp | 2 + .../rfl/capnproto/schema/CapnProtoTypes.hpp | 1 + include/rfl/capnproto/to_schema.hpp | 20 ++--- include/rfl/cbor/Parser.hpp | 3 +- include/rfl/flexbuf/Reader.hpp | 10 +-- include/rfl/flexbuf/Writer.hpp | 23 +++-- include/rfl/internal/Array.hpp | 3 +- include/rfl/internal/Skip.hpp | 3 + include/rfl/internal/find_index.hpp | 1 + include/rfl/internal/has_custom_parser.hpp | 2 +- .../internal/is_add_tags_to_variants_v.hpp | 11 +-- .../rfl/internal/is_default_if_missing_v.hpp | 8 +- include/rfl/internal/is_empty.hpp | 1 + include/rfl/internal/is_no_field_names_v.hpp | 8 +- include/rfl/internal/remove_ptrs_nt.hpp | 1 + include/rfl/internal/to_std_array.hpp | 1 + include/rfl/internal/wrap_in_fields.hpp | 1 + include/rfl/json/Reader.hpp | 1 + include/rfl/json/schema/Type.hpp | 1 + include/rfl/msgpack/Reader.hpp | 7 +- include/rfl/msgpack/Writer.hpp | 28 +++---- include/rfl/parsing/FieldVariantReader.hpp | 1 + include/rfl/parsing/is_required.hpp | 1 + .../parsing/schemaful/IsSchemafulReader.hpp | 1 + 36 files changed, 205 insertions(+), 145 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2012b679..fb3366f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,7 @@ option(REFLECTCPP_YAML "Enable YAML support" ${REFLECTCPP_ALL_FORMATS}) option(REFLECTCPP_BUILD_BENCHMARKS "Build benchmarks" OFF) option(REFLECTCPP_BUILD_TESTS "Build tests" OFF) +option(REFLECTCPP_CHECK_HEADERS "Make sure that all headers are self-contained" OFF) option(REFLECTCPP_USE_BUNDLED_DEPENDENCIES "Use the bundled dependencies" ON) @@ -55,7 +56,7 @@ if(REFLECTCPP_BUILD_BENCHMARKS) set(REFLECTCPP_YAML ON CACHE BOOL "" FORCE) endif() -if (REFLECTCPP_BUILD_TESTS OR REFLECTCPP_BUILD_BENCHMARKS OR +if (REFLECTCPP_BUILD_TESTS OR REFLECTCPP_BUILD_BENCHMARKS OR REFLECTCPP_CHECK_HEADERS OR (REFLECTCPP_JSON AND NOT REFLECTCPP_USE_BUNDLED_DEPENDENCIES) OR REFLECTCPP_AVRO OR REFLECTCPP_BSON OR REFLECTCPP_CAPNPROTO OR REFLECTCPP_CBOR OR REFLECTCPP_CSV OR REFLECTCPP_FLEXBUFFERS OR REFLECTCPP_MSGPACK OR REFLECTCPP_PARQUET OR REFLECTCPP_XML OR @@ -73,31 +74,31 @@ endif() option(REFLECTCPP_USE_VCPKG "Use VCPKG to download and build dependencies" ${REFLECTCPP_USE_VCPKG_DEFAULT}) if (REFLECTCPP_USE_VCPKG) - if (REFLECTCPP_AVRO) + if (REFLECTCPP_AVRO OR REFLECTCPP_CHECK_HEADERS) list(APPEND VCPKG_MANIFEST_FEATURES "avro") endif() - if (REFLECTCPP_BSON) + if (REFLECTCPP_BSON OR REFLECTCPP_CHECK_HEADERS) list(APPEND VCPKG_MANIFEST_FEATURES "bson") endif() - if (REFLECTCPP_BUILD_BENCHMARKS) + if (REFLECTCPP_BUILD_BENCHMARKS OR REFLECTCPP_CHECK_HEADERS) list(APPEND VCPKG_MANIFEST_FEATURES "benchmarks") endif() - if (REFLECTCPP_BUILD_TESTS) + if (REFLECTCPP_BUILD_TESTS OR REFLECTCPP_CHECK_HEADERS) list(APPEND VCPKG_MANIFEST_FEATURES "tests") endif() - if (REFLECTCPP_CAPNPROTO) + if (REFLECTCPP_CAPNPROTO OR REFLECTCPP_CHECK_HEADERS) list(APPEND VCPKG_MANIFEST_FEATURES "capnproto") endif() - if (REFLECTCPP_CBOR) + if (REFLECTCPP_CBOR OR REFLECTCPP_CHECK_HEADERS) list(APPEND VCPKG_MANIFEST_FEATURES "cbor") endif() - if (REFLECTCPP_CSV) + if (REFLECTCPP_CSV OR REFLECTCPP_CHECK_HEADERS) list(APPEND VCPKG_MANIFEST_FEATURES "csv") endif() @@ -105,7 +106,7 @@ if (REFLECTCPP_USE_VCPKG) list(APPEND VCPKG_MANIFEST_FEATURES "ctre") endif() - if (REFLECTCPP_FLEXBUFFERS) + if (REFLECTCPP_FLEXBUFFERS OR REFLECTCPP_CHECK_HEADERS) list(APPEND VCPKG_MANIFEST_FEATURES "flexbuffers") endif() @@ -113,27 +114,27 @@ if (REFLECTCPP_USE_VCPKG) list(APPEND VCPKG_MANIFEST_FEATURES "json") endif() - if (REFLECTCPP_MSGPACK) + if (REFLECTCPP_MSGPACK OR REFLECTCPP_CHECK_HEADERS) list(APPEND VCPKG_MANIFEST_FEATURES "msgpack") endif() - if (REFLECTCPP_PARQUET) + if (REFLECTCPP_PARQUET OR REFLECTCPP_CHECK_HEADERS) list(APPEND VCPKG_MANIFEST_FEATURES "parquet") endif() - if (REFLECTCPP_TOML) + if (REFLECTCPP_TOML OR REFLECTCPP_CHECK_HEADERS) list(APPEND VCPKG_MANIFEST_FEATURES "toml") endif() - if (REFLECTCPP_UBJSON) + if (REFLECTCPP_UBJSON OR REFLECTCPP_CHECK_HEADERS) list(APPEND VCPKG_MANIFEST_FEATURES "ubjson") endif() - if (REFLECTCPP_XML) + if (REFLECTCPP_XML OR REFLECTCPP_CHECK_HEADERS) list(APPEND VCPKG_MANIFEST_FEATURES "xml") endif() - if (REFLECTCPP_YAML) + if (REFLECTCPP_YAML OR REFLECTCPP_CHECK_HEADERS) list(APPEND VCPKG_MANIFEST_FEATURES "yaml") endif() @@ -237,7 +238,7 @@ if (_REFLECTCPP_NEEDS_JSON_IMPL) endif () endif () -if (REFLECTCPP_AVRO) +if (REFLECTCPP_AVRO OR REFLECTCPP_CHECK_HEADERS) list(APPEND REFLECT_CPP_SOURCES src/reflectcpp_avro.cpp ) @@ -270,7 +271,7 @@ if (REFLECTCPP_AVRO) target_link_libraries(reflectcpp PRIVATE jansson::jansson) endif () -if (REFLECTCPP_BSON) +if (REFLECTCPP_BSON OR REFLECTCPP_CHECK_HEADERS) list(APPEND REFLECT_CPP_SOURCES src/reflectcpp_bson.cpp ) @@ -280,7 +281,7 @@ if (REFLECTCPP_BSON) target_link_libraries(reflectcpp PUBLIC $,mongo::bson_static,mongo::bson_shared>) endif () -if (REFLECTCPP_CAPNPROTO) +if (REFLECTCPP_CAPNPROTO OR REFLECTCPP_CHECK_HEADERS) list(APPEND REFLECT_CPP_SOURCES src/reflectcpp_capnproto.cpp ) @@ -295,7 +296,7 @@ if (REFLECTCPP_CAPNPROTO) target_link_libraries(reflectcpp PUBLIC CapnProto::kj CapnProto::capnp ${CAPNPC_LIB} CapnProto::kj-gzip) endif () -if (REFLECTCPP_CBOR) +if (REFLECTCPP_CBOR OR REFLECTCPP_CHECK_HEADERS) list(APPEND REFLECT_CPP_SOURCES src/reflectcpp_cbor.cpp ) @@ -305,7 +306,7 @@ if (REFLECTCPP_CBOR) include_directories(PUBLIC ${jsoncons_INCLUDE_DIRS}) endif () -if (REFLECTCPP_CSV) +if (REFLECTCPP_CSV OR REFLECTCPP_CHECK_HEADERS) if (NOT TARGET Arrow) find_package(Arrow CONFIG REQUIRED) endif() @@ -316,7 +317,7 @@ if (REFLECTCPP_CSV) endif() endif () -if (REFLECTCPP_FLEXBUFFERS) +if (REFLECTCPP_FLEXBUFFERS OR REFLECTCPP_CHECK_HEADERS) list(APPEND REFLECT_CPP_SOURCES src/reflectcpp_flexbuf.cpp ) @@ -326,7 +327,7 @@ if (REFLECTCPP_FLEXBUFFERS) target_link_libraries(reflectcpp PUBLIC flatbuffers::flatbuffers) endif () -if (REFLECTCPP_MSGPACK) +if (REFLECTCPP_MSGPACK OR REFLECTCPP_CHECK_HEADERS) list(APPEND REFLECT_CPP_SOURCES src/reflectcpp_msgpack.cpp ) @@ -336,7 +337,7 @@ if (REFLECTCPP_MSGPACK) target_link_libraries(reflectcpp PUBLIC msgpack-c) endif () -if (REFLECTCPP_PARQUET) +if (REFLECTCPP_PARQUET OR REFLECTCPP_CHECK_HEADERS) if (NOT TARGET Arrow) find_package(Arrow CONFIG REQUIRED) endif() @@ -351,7 +352,7 @@ if (REFLECTCPP_PARQUET) endif() endif () -if (REFLECTCPP_TOML) +if (REFLECTCPP_TOML OR REFLECTCPP_CHECK_HEADERS) list(APPEND REFLECT_CPP_SOURCES src/reflectcpp_toml.cpp ) @@ -361,7 +362,7 @@ if (REFLECTCPP_TOML) target_link_libraries(reflectcpp PUBLIC tomlplusplus::tomlplusplus) endif() -if (REFLECTCPP_UBJSON) +if (REFLECTCPP_UBJSON OR REFLECTCPP_CHECK_HEADERS) list(APPEND REFLECT_CPP_SOURCES src/reflectcpp_ubjson.cpp ) @@ -371,7 +372,7 @@ if (REFLECTCPP_UBJSON) include_directories(PUBLIC ${jsoncons_INCLUDE_DIRS}) endif () -if (REFLECTCPP_XML) +if (REFLECTCPP_XML OR REFLECTCPP_CHECK_HEADERS) list(APPEND REFLECT_CPP_SOURCES src/reflectcpp_xml.cpp ) @@ -381,7 +382,7 @@ if (REFLECTCPP_XML) target_link_libraries(reflectcpp PUBLIC pugixml::pugixml) endif () -if (REFLECTCPP_YAML) +if (REFLECTCPP_YAML OR REFLECTCPP_CHECK_HEADERS) list(APPEND REFLECT_CPP_SOURCES src/reflectcpp_yaml.cpp ) @@ -415,6 +416,32 @@ if (REFLECTCPP_BUILD_BENCHMARKS) add_subdirectory(benchmarks) endif () +if(REFLECTCPP_CHECK_HEADERS) + file(GLOB_RECURSE PROJECT_HEADERS "include/*.hpp") + + set(TEST_DIR "${CMAKE_CURRENT_BINARY_DIR}/self_contained_tests") + file(MAKE_DIRECTORY "${TEST_DIR}") + + foreach(HEADER_FILE ${PROJECT_HEADERS}) + string(MAKE_C_IDENTIFIER ${HEADER_FILE} HEADER_NAME) + set(TEST_SOURCE_FILE "${TEST_DIR}/test_${HEADER_NAME}.cpp") + + file(GENERATE + OUTPUT ${TEST_SOURCE_FILE} + CONTENT "#include \"${HEADER_FILE}\"\n" + ) + + add_library(check_header_${HEADER_NAME} "${TEST_SOURCE_FILE}") + + target_include_directories(check_header_${HEADER_NAME} PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${ADDITIONAL_INCLUDE_DIRS} + ) + + add_custom_target(check_${HEADER_NAME} ALL DEPENDS check_header_${HEADER_NAME}) + endforeach() +endif() + if (REFLECTCPP_INSTALL) include(GNUInstallDirs) include(CMakePackageConfigHelpers) @@ -451,9 +478,6 @@ if (REFLECTCPP_INSTALL) ) endif () - -# CPack configuration - # Set general package information set(CPACK_PACKAGE_NAME "reflectcpp") set(CPACK_PACKAGE_VENDOR "Reflect C++ Team") diff --git a/include/rfl/Processors.hpp b/include/rfl/Processors.hpp index 696e9f8e..14707b1f 100644 --- a/include/rfl/Processors.hpp +++ b/include/rfl/Processors.hpp @@ -2,6 +2,7 @@ #define RFL_INTERNAL_PROCESSORS_HPP_ #include +#include #include "internal/is_add_tags_to_variants_v.hpp" #include "internal/is_allow_raw_ptrs_v.hpp" @@ -69,9 +70,9 @@ struct Processors { template static auto process(NamedTupleType&& _named_tuple) { - static_assert(!add_tags_to_variants_ || !add_namespaced_tags_to_variants_, - "You cannot add both rfl::AddTagsToVariants and " - "rfl::AddNamespacedTagsToVariants."); + static_assert(!add_tags_to_variants_ || !add_namespaced_tags_to_variants_, + "You cannot add both rfl::AddTagsToVariants and " + "rfl::AddNamespacedTagsToVariants."); return Processors::template process( Head::template process(std::move(_named_tuple))); } diff --git a/include/rfl/Timestamp.hpp b/include/rfl/Timestamp.hpp index 31eaa657..64468229 100644 --- a/include/rfl/Timestamp.hpp +++ b/include/rfl/Timestamp.hpp @@ -7,6 +7,7 @@ #include #include +#include "Literal.hpp" #include "Result.hpp" #include "internal/StringLiteral.hpp" diff --git a/include/rfl/Tuple.hpp b/include/rfl/Tuple.hpp index d88af559..f654be47 100644 --- a/include/rfl/Tuple.hpp +++ b/include/rfl/Tuple.hpp @@ -2,6 +2,7 @@ #define RFL_TUPLE_HPP_ #include +#include #include #include #include @@ -43,9 +44,7 @@ class Tuple { Tuple(const Tuple& _other) { copy_from_other(_other, seq_); } - Tuple(Tuple&& _other) noexcept { - move_from_other(std::move(_other), seq_); - } + Tuple(Tuple&& _other) noexcept { move_from_other(std::move(_other), seq_); } ~Tuple() { destroy_if_necessary(seq_); } @@ -154,8 +153,7 @@ class Tuple { } template - void move_from_other(Tuple&& _other, - std::integer_sequence) { + void move_from_other(Tuple&& _other, std::integer_sequence) { const auto move_one = [this](auto&& _other, std::integral_constant) { using Type = internal::nth_element_t<_i, Types...>; diff --git a/include/rfl/avro/Parser.hpp b/include/rfl/avro/Parser.hpp index 706f4caf..369bb797 100644 --- a/include/rfl/avro/Parser.hpp +++ b/include/rfl/avro/Parser.hpp @@ -2,9 +2,11 @@ #define RFL_AVRO_PARSER_HPP_ #include "../Generic.hpp" +#include "../NamedTuple.hpp" #include "../Tuple.hpp" #include "../always_false.hpp" -//#include "../parsing/Parser.hpp" +#include "../parsing/AreReaderAndWriter.hpp" +#include "../parsing/Parser.hpp" #include "Reader.hpp" #include "Writer.hpp" diff --git a/include/rfl/avro/SchemaImpl.hpp b/include/rfl/avro/SchemaImpl.hpp index 85e1492f..0264c016 100644 --- a/include/rfl/avro/SchemaImpl.hpp +++ b/include/rfl/avro/SchemaImpl.hpp @@ -5,8 +5,7 @@ #include -//#include "../Box.hpp" -//#include "../Result.hpp" +#include "../Box.hpp" #include "../common.hpp" namespace rfl::avro { diff --git a/include/rfl/avro/Writer.hpp b/include/rfl/avro/Writer.hpp index 2ce8b7bf..5f780256 100644 --- a/include/rfl/avro/Writer.hpp +++ b/include/rfl/avro/Writer.hpp @@ -1,21 +1,22 @@ #ifndef RFL_AVRO_WRITER_HPP_ #define RFL_AVRO_WRITER_HPP_ +#include + +#include #include #include #include #include -#include - -//#include "../Box.hpp" #include "../Bytestring.hpp" -//#include "../Ref.hpp" -//#include "../Result.hpp" +#include "../Timestamp.hpp" #include "../Vectorstring.hpp" #include "../always_false.hpp" -#include "../internal/is_literal.hpp" #include "../common.hpp" +#include "../internal/is_literal.hpp" +#include "../internal/is_validator.hpp" +#include "../patterns.hpp" namespace rfl::avro { @@ -102,9 +103,9 @@ class RFL_API Writer { const size_t _size, OutputMapType* _parent) const; - OutputObjectType add_object_to_object( - const std::string_view& _name, const size_t _size, - OutputObjectType* _parent) const; + OutputObjectType add_object_to_object(const std::string_view& _name, + const size_t _size, + OutputObjectType* _parent) const; OutputObjectType add_object_to_union(const size_t _index, const size_t _size, OutputUnionType* _parent) const; @@ -137,7 +138,9 @@ class RFL_API Writer { avro_value_t new_value; int result = avro_value_append(&_parent->val_, &new_value, nullptr); if (result != 0) { - throw std::runtime_error(std::string(__FUNCTION__) + " error("+ std::to_string(result)+"): " + avro_strerror()); + throw std::runtime_error(std::string(__FUNCTION__) + " error(" + + std::to_string(result) + + "): " + avro_strerror()); } set_value(_var, &new_value); return OutputVarType{new_value}; @@ -147,9 +150,12 @@ class RFL_API Writer { OutputVarType add_value_to_map(const std::string_view& _name, const T& _var, OutputMapType* _parent) const { avro_value_t new_value; - int result = avro_value_add(&_parent->val_, _name.data(), &new_value, nullptr, nullptr); + int result = avro_value_add(&_parent->val_, _name.data(), &new_value, + nullptr, nullptr); if (result != 0) { - throw std::runtime_error(std::string(__FUNCTION__) + " error("+ std::to_string(result)+"): " + avro_strerror()); + throw std::runtime_error(std::string(__FUNCTION__) + " error(" + + std::to_string(result) + + "): " + avro_strerror()); } set_value(_var, &new_value); return OutputVarType{new_value}; @@ -160,9 +166,12 @@ class RFL_API Writer { const T& _var, OutputObjectType* _parent) const { avro_value_t new_value; - int result = avro_value_get_by_name(&_parent->val_, _name.data(), &new_value, nullptr); + int result = avro_value_get_by_name(&_parent->val_, _name.data(), + &new_value, nullptr); if (result != 0) { - throw std::runtime_error(std::string(__FUNCTION__) + " error("+ std::to_string(result)+"): " + avro_strerror()); + throw std::runtime_error(std::string(__FUNCTION__) + " error(" + + std::to_string(result) + + "): " + avro_strerror()); } set_value(_var, &new_value); return OutputVarType{new_value}; @@ -175,9 +184,12 @@ class RFL_API Writer { throw std::runtime_error(std::string(__FUNCTION__) + " index error"); } avro_value_t new_value; - int result = avro_value_set_branch(&_parent->val_, static_cast(_index), &new_value); + int result = avro_value_set_branch(&_parent->val_, static_cast(_index), + &new_value); if (result != 0) { - throw std::runtime_error(std::string(__FUNCTION__) + " error("+ std::to_string(result)+"): " + avro_strerror()); + throw std::runtime_error(std::string(__FUNCTION__) + " error(" + + std::to_string(result) + + "): " + avro_strerror()); } set_value(_var, &new_value); return OutputVarType{new_value}; @@ -193,9 +205,12 @@ class RFL_API Writer { template void set_value(const T& _var, avro_value_t* _val) const { if constexpr (std::is_same, std::string>()) { - int result = avro_value_set_string_len(_val, _var.c_str(), _var.size() + 1); + int result = + avro_value_set_string_len(_val, _var.c_str(), _var.size() + 1); if (result != 0) { - throw std::runtime_error(std::string(__FUNCTION__) + " error("+ std::to_string(result)+"): " + avro_strerror()); + throw std::runtime_error(std::string(__FUNCTION__) + " error(" + + std::to_string(result) + + "): " + avro_strerror()); } } else if constexpr (std::is_same, rfl::Bytestring>() || @@ -207,35 +222,44 @@ class RFL_API Writer { } int result = avro_value_set_bytes(_val, var.data(), var.size()); if (result != 0) { - throw std::runtime_error(std::string(__FUNCTION__) + " error("+ std::to_string(result)+"): " + avro_strerror()); + throw std::runtime_error(std::string(__FUNCTION__) + " error(" + + std::to_string(result) + + "): " + avro_strerror()); } } else if constexpr (std::is_same, bool>()) { int result = avro_value_set_boolean(_val, _var); if (result != 0) { - throw std::runtime_error(std::string(__FUNCTION__) + " error("+ std::to_string(result)+"): " + avro_strerror()); + throw std::runtime_error(std::string(__FUNCTION__) + " error(" + + std::to_string(result) + + "): " + avro_strerror()); } } else if constexpr (std::is_floating_point>()) { /*int result = avro_value_set_double(_val, static_cast(_var)); if (result != 0) { - throw std::runtime_error(std::string(__FUNCTION__) + " error("+ std::to_string(result)+"): " + avro_strerror()); + throw std::runtime_error(std::string(__FUNCTION__) + " error("+ + std::to_string(result)+"): " + avro_strerror()); }*/ avro_value_set_double(_val, static_cast(_var)); } else if constexpr (std::is_integral>()) { /*int result = avro_value_set_long(_val, static_cast(_var)); if (result != 0) { - throw std::runtime_error(std::string(__FUNCTION__) + " error("+ std::to_string(result)+"): " + avro_strerror()); + throw std::runtime_error(std::string(__FUNCTION__) + " error("+ + std::to_string(result)+"): " + avro_strerror()); }*/ avro_value_set_long(_val, static_cast(_var)); } else if constexpr (internal::is_literal_v) { int result = avro_value_set_enum(_val, static_cast(_var.value())); if (result != 0) { - throw std::runtime_error(std::string(__FUNCTION__) + " error("+ std::to_string(result)+"): " + avro_strerror()); + throw std::runtime_error(std::string(__FUNCTION__) + " error(" + + std::to_string(result) + + "): " + avro_strerror()); } } else if constexpr (internal::is_validator_v) { using ValueType = std::remove_cvref_t; const auto val = _var.value(); set_value(val, _val); - } else if constexpr (std::is_same, rfl::Timestamp<"%Y-%m-%d">>()) { + } else if constexpr (std::is_same, + rfl::Timestamp<"%Y-%m-%d">>()) { const auto str = _var.to_string(); set_value(str, _val); } else if constexpr (std::is_same, rfl::Email>()) { diff --git a/include/rfl/bson/Parser.hpp b/include/rfl/bson/Parser.hpp index 8f132943..e3973a46 100644 --- a/include/rfl/bson/Parser.hpp +++ b/include/rfl/bson/Parser.hpp @@ -3,7 +3,8 @@ #include -//#include "../parsing/Parser.hpp" +#include "../parsing/AreReaderAndWriter.hpp" +#include "../parsing/Parser.hpp" #include "Reader.hpp" #include "Writer.hpp" @@ -12,7 +13,7 @@ namespace rfl::parsing { /// bson_oid_t needs to be treated as a special case, otherwise it will be read /// as a struct. template -requires AreReaderAndWriter + requires AreReaderAndWriter struct Parser { using InputVarType = typename R::InputVarType; diff --git a/include/rfl/bson/Reader.hpp b/include/rfl/bson/Reader.hpp index e8abc5af..9cb714d6 100644 --- a/include/rfl/bson/Reader.hpp +++ b/include/rfl/bson/Reader.hpp @@ -9,12 +9,11 @@ #include #include -//#include "../Box.hpp" -//#include "../Bytestring.hpp" +#include "../Bytestring.hpp" #include "../Result.hpp" -//#include "../Vectorstring.hpp" +#include "../Vectorstring.hpp" #include "../always_false.hpp" -//#include "../internal/ptr_cast.hpp" +#include "../internal/ptr_cast.hpp" namespace rfl { namespace bson { @@ -110,16 +109,14 @@ struct Reader { using VectorType = std::remove_cvref_t; using ValueType = typename VectorType::value_type; if (btype != BSON_TYPE_BINARY) { - if constexpr (std::is_same, - rfl::Bytestring>()) { + if constexpr (std::is_same, rfl::Bytestring>()) { return error("Could not cast to bytestring."); } else { return error("Could not cast to vectorstring."); } } if (value.v_binary.subtype != BSON_SUBTYPE_BINARY) { - if constexpr (std::is_same, - rfl::Bytestring>()) { + if constexpr (std::is_same, rfl::Bytestring>()) { return error( "The BSON subtype must be a binary in order to read into a " "bytestring."); diff --git a/include/rfl/capnproto/Parser.hpp b/include/rfl/capnproto/Parser.hpp index 43e9ed73..60e205c1 100644 --- a/include/rfl/capnproto/Parser.hpp +++ b/include/rfl/capnproto/Parser.hpp @@ -1,10 +1,11 @@ #ifndef RFL_CAPNPROTO_PARSER_HPP_ #define RFL_CAPNPROTO_PARSER_HPP_ -//#include "../Generic.hpp" +#include "../Generic.hpp" +#include "../NamedTuple.hpp" #include "../Tuple.hpp" #include "../always_false.hpp" -//#include "../parsing/Parser.hpp" +#include "../parsing/Parser.hpp" #include "Reader.hpp" #include "Writer.hpp" diff --git a/include/rfl/capnproto/Reader.hpp b/include/rfl/capnproto/Reader.hpp index d041b5c5..819a5f3e 100644 --- a/include/rfl/capnproto/Reader.hpp +++ b/include/rfl/capnproto/Reader.hpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -11,9 +12,9 @@ #include "../Result.hpp" #include "../Vectorstring.hpp" #include "../always_false.hpp" +#include "../common.hpp" #include "../internal/is_literal.hpp" #include "../internal/ptr_cast.hpp" -#include "../common.hpp" namespace rfl::capnproto { @@ -69,8 +70,7 @@ class RFL_API Reader { using VectorType = std::remove_cvref_t; using ValueType = typename VectorType::value_type; if (type != capnp::DynamicValue::DATA) { - if constexpr (std::is_same, - rfl::Bytestring>()) { + if constexpr (std::is_same, rfl::Bytestring>()) { return error("Could not cast to bytestring."); } else { return error("Could not cast to vectorstring."); diff --git a/include/rfl/capnproto/SchemaImpl.hpp b/include/rfl/capnproto/SchemaImpl.hpp index ff783bc9..b45fe4d8 100644 --- a/include/rfl/capnproto/SchemaImpl.hpp +++ b/include/rfl/capnproto/SchemaImpl.hpp @@ -5,8 +5,7 @@ #include -//#include "../Box.hpp" -//#include "../Result.hpp" +#include "../Box.hpp" #include "../common.hpp" namespace rfl::capnproto { diff --git a/include/rfl/capnproto/is_named_type.hpp b/include/rfl/capnproto/is_named_type.hpp index c95377c3..cad64d63 100644 --- a/include/rfl/capnproto/is_named_type.hpp +++ b/include/rfl/capnproto/is_named_type.hpp @@ -1,6 +1,8 @@ #ifndef RFL_CAPNPROTO_IS_NAMED_TYPE_HPP_ #define RFL_CAPNPROTO_IS_NAMED_TYPE_HPP_ +#include "../parsing/schema/Type.hpp" + namespace rfl::capnproto { inline bool is_named_type(const parsing::schema::Type& _type) { diff --git a/include/rfl/capnproto/schema/CapnProtoTypes.hpp b/include/rfl/capnproto/schema/CapnProtoTypes.hpp index 5a5515f4..6f50f4e6 100644 --- a/include/rfl/capnproto/schema/CapnProtoTypes.hpp +++ b/include/rfl/capnproto/schema/CapnProtoTypes.hpp @@ -3,6 +3,7 @@ #include +#include "../../internal/strings/strings.hpp" #include "Type.hpp" namespace rfl::capnproto::schema { diff --git a/include/rfl/capnproto/to_schema.hpp b/include/rfl/capnproto/to_schema.hpp index 8fc31f80..2a6e96a2 100644 --- a/include/rfl/capnproto/to_schema.hpp +++ b/include/rfl/capnproto/to_schema.hpp @@ -3,20 +3,20 @@ #include -//#include "../Literal.hpp" -//#include "../Processors.hpp" +#include "../Literal.hpp" +#include "../Processors.hpp" #include "../Result.hpp" -//#include "../SnakeCaseToCamelCase.hpp" -//#include "../Variant.hpp" -//#include "../json.hpp" -//#include "../parsing/schema/Type.hpp" -//#include "../parsing/schema/ValidationType.hpp" +#include "../SnakeCaseToCamelCase.hpp" +#include "../Variant.hpp" +#include "../common.hpp" +#include "../json.hpp" +#include "../parsing/schema/Type.hpp" +#include "../parsing/schema/ValidationType.hpp" #include "../parsing/schema/make.hpp" +#include "Reader.hpp" #include "Schema.hpp" #include "Writer.hpp" -#include "Reader.hpp" -//#include "schema/Type.hpp" -#include "../common.hpp" +#include "schema/Type.hpp" namespace rfl::capnproto { diff --git a/include/rfl/cbor/Parser.hpp b/include/rfl/cbor/Parser.hpp index 658190bf..8bcd9150 100644 --- a/include/rfl/cbor/Parser.hpp +++ b/include/rfl/cbor/Parser.hpp @@ -1,8 +1,7 @@ #ifndef RFL_CBOR_PARSER_HPP_ #define RFL_CBOR_PARSER_HPP_ -//#include "../Tuple.hpp" -//#include "../parsing/Parser.hpp" +#include "../parsing/Parser.hpp" #include "Reader.hpp" #include "Writer.hpp" diff --git a/include/rfl/flexbuf/Reader.hpp b/include/rfl/flexbuf/Reader.hpp index d8d8460f..539c338c 100644 --- a/include/rfl/flexbuf/Reader.hpp +++ b/include/rfl/flexbuf/Reader.hpp @@ -9,11 +9,12 @@ #include #include -//#include "../Bytestring.hpp" +#include "../Bytestring.hpp" +#include "../Ref.hpp" #include "../Result.hpp" -//#include "../Vectorstring.hpp" +#include "../Vectorstring.hpp" #include "../always_false.hpp" -//#include "../internal/ptr_cast.hpp" +#include "../internal/ptr_cast.hpp" namespace rfl { namespace flexbuf { @@ -79,8 +80,7 @@ struct Reader { using VectorType = std::remove_cvref_t; using ValueType = typename VectorType::value_type; if (!_var.IsBlob()) { - if constexpr (std::is_same, - rfl::Bytestring>()) { + if constexpr (std::is_same, rfl::Bytestring>()) { return error("Could not cast to bytestring."); } else { return error("Could not cast to vectorstring."); diff --git a/include/rfl/flexbuf/Writer.hpp b/include/rfl/flexbuf/Writer.hpp index df5c82ae..bf4c85b3 100644 --- a/include/rfl/flexbuf/Writer.hpp +++ b/include/rfl/flexbuf/Writer.hpp @@ -9,8 +9,7 @@ #include #include "../Bytestring.hpp" -//#include "../Ref.hpp" -//#include "../Result.hpp" +#include "../Ref.hpp" #include "../Vectorstring.hpp" #include "../always_false.hpp" #include "../common.hpp" @@ -51,27 +50,27 @@ struct RFL_API Writer { OutputArrayType add_array_to_array(const size_t _size, OutputArrayType* _parent) const noexcept; - OutputArrayType add_array_to_object( - const std::string_view& _name, const size_t _size, - OutputObjectType* _parent) const noexcept; + OutputArrayType add_array_to_object(const std::string_view& _name, + const size_t _size, + OutputObjectType* _parent) const noexcept; - OutputObjectType add_object_to_array( - const size_t _size, OutputArrayType* _parent) const noexcept; + OutputObjectType add_object_to_array(const size_t _size, + OutputArrayType* _parent) const noexcept; OutputObjectType add_object_to_object( const std::string_view& _name, const size_t _size, OutputObjectType* _parent) const noexcept; template - OutputVarType add_value_to_array(const T& _var, - OutputArrayType* /*_parent*/) const noexcept { + OutputVarType add_value_to_array( + const T& _var, OutputArrayType* /*_parent*/) const noexcept { return insert_value(_var); } template - OutputVarType add_value_to_object(const std::string_view& _name, - const T& _var, - OutputObjectType* /*_parent*/) const noexcept { + OutputVarType add_value_to_object( + const std::string_view& _name, const T& _var, + OutputObjectType* /*_parent*/) const noexcept { return insert_value(_name, _var); } diff --git a/include/rfl/internal/Array.hpp b/include/rfl/internal/Array.hpp index e61ef76d..8e16b633 100644 --- a/include/rfl/internal/Array.hpp +++ b/include/rfl/internal/Array.hpp @@ -1,6 +1,7 @@ #ifndef RFL_INTERNAL_ARRAY_HPP_ #define RFL_INTERNAL_ARRAY_HPP_ +#include #include #include "to_std_array.hpp" @@ -9,7 +10,7 @@ namespace rfl { namespace internal { template -requires std::is_array_v + requires std::is_array_v struct Array { using Type = T; using StdArrayType = to_std_array_t; diff --git a/include/rfl/internal/Skip.hpp b/include/rfl/internal/Skip.hpp index 763229ae..a97603d4 100644 --- a/include/rfl/internal/Skip.hpp +++ b/include/rfl/internal/Skip.hpp @@ -2,6 +2,9 @@ #define RFL_INTERNAL_SKIP_HPP_ #include +#include + +#include "../default.hpp" namespace rfl::internal { diff --git a/include/rfl/internal/find_index.hpp b/include/rfl/internal/find_index.hpp index 347d27b7..f32bc968 100644 --- a/include/rfl/internal/find_index.hpp +++ b/include/rfl/internal/find_index.hpp @@ -1,6 +1,7 @@ #ifndef RFL_FIND_INDEX_HPP_ #define RFL_FIND_INDEX_HPP_ +#include "../Tuple.hpp" #include "StringLiteral.hpp" namespace rfl { diff --git a/include/rfl/internal/has_custom_parser.hpp b/include/rfl/internal/has_custom_parser.hpp index a8743288..40b5720d 100644 --- a/include/rfl/internal/has_custom_parser.hpp +++ b/include/rfl/internal/has_custom_parser.hpp @@ -3,7 +3,7 @@ #include -//#include "../parsing/Parser.hpp" +#include "../parsing/Parser.hpp" namespace rfl::internal { diff --git a/include/rfl/internal/is_add_tags_to_variants_v.hpp b/include/rfl/internal/is_add_tags_to_variants_v.hpp index 9086a6f0..4385b1d2 100644 --- a/include/rfl/internal/is_add_tags_to_variants_v.hpp +++ b/include/rfl/internal/is_add_tags_to_variants_v.hpp @@ -3,7 +3,7 @@ #include -//#include "../AddTagsToVariants.hpp" +#include "../AddTagsToVariants.hpp" namespace rfl ::internal { @@ -27,12 +27,13 @@ template class is_add_namespaced_tags_to_variants : public std::false_type {}; template <> -class is_add_namespaced_tags_to_variants : public std::true_type {}; +class is_add_namespaced_tags_to_variants + : public std::true_type {}; template -constexpr bool is_add_namespaced_tags_to_variants_v = is_add_namespaced_tags_to_variants< - std::remove_cvref_t>>::value; - +constexpr bool is_add_namespaced_tags_to_variants_v = + is_add_namespaced_tags_to_variants< + std::remove_cvref_t>>::value; } // namespace rfl::internal diff --git a/include/rfl/internal/is_default_if_missing_v.hpp b/include/rfl/internal/is_default_if_missing_v.hpp index 72e5c208..836ca7e0 100644 --- a/include/rfl/internal/is_default_if_missing_v.hpp +++ b/include/rfl/internal/is_default_if_missing_v.hpp @@ -3,10 +3,9 @@ #include -//#include "../DefaultIfMissing.hpp" +#include "../DefaultIfMissing.hpp" -namespace rfl { -namespace internal { +namespace rfl::internal { template class is_default_if_missing; @@ -21,7 +20,6 @@ template constexpr bool is_default_if_missing_v = is_default_if_missing>>::value; -} // namespace internal -} // namespace rfl +} // namespace rfl::internal #endif diff --git a/include/rfl/internal/is_empty.hpp b/include/rfl/internal/is_empty.hpp index 49e018b5..7434710b 100644 --- a/include/rfl/internal/is_empty.hpp +++ b/include/rfl/internal/is_empty.hpp @@ -5,6 +5,7 @@ #include "../Tuple.hpp" #include "is_named_tuple.hpp" +#include "ptr_tuple_t.hpp" namespace rfl::internal { diff --git a/include/rfl/internal/is_no_field_names_v.hpp b/include/rfl/internal/is_no_field_names_v.hpp index 2b00b704..9c0cbee5 100644 --- a/include/rfl/internal/is_no_field_names_v.hpp +++ b/include/rfl/internal/is_no_field_names_v.hpp @@ -3,10 +3,9 @@ #include -//#include "../NoFieldNames.hpp" +#include "../NoFieldNames.hpp" -namespace rfl { -namespace internal { +namespace rfl::internal { template class is_no_field_names; @@ -21,7 +20,6 @@ template constexpr bool is_no_field_names_v = is_no_field_names>>::value; -} // namespace internal -} // namespace rfl +} // namespace rfl::internal #endif diff --git a/include/rfl/internal/remove_ptrs_nt.hpp b/include/rfl/internal/remove_ptrs_nt.hpp index 97a3d16a..cc503aae 100644 --- a/include/rfl/internal/remove_ptrs_nt.hpp +++ b/include/rfl/internal/remove_ptrs_nt.hpp @@ -4,6 +4,7 @@ #include #include "../Field.hpp" +#include "../NamedTuple.hpp" #include "StringLiteral.hpp" #include "wrap_in_rfl_array_t.hpp" diff --git a/include/rfl/internal/to_std_array.hpp b/include/rfl/internal/to_std_array.hpp index 4d9a936e..509416c1 100644 --- a/include/rfl/internal/to_std_array.hpp +++ b/include/rfl/internal/to_std_array.hpp @@ -2,6 +2,7 @@ #define RFL_INTERNAL_TO_STD_ARRAY_HPP_ #include +#include #include namespace rfl::internal { diff --git a/include/rfl/internal/wrap_in_fields.hpp b/include/rfl/internal/wrap_in_fields.hpp index 93838f2c..f536779d 100644 --- a/include/rfl/internal/wrap_in_fields.hpp +++ b/include/rfl/internal/wrap_in_fields.hpp @@ -3,6 +3,7 @@ #include +#include "../Field.hpp" #include "../Tuple.hpp" #include "flattened_ptr_tuple_t.hpp" #include "is_flatten_field.hpp" diff --git a/include/rfl/json/Reader.hpp b/include/rfl/json/Reader.hpp index ac75f738..b358e71f 100644 --- a/include/rfl/json/Reader.hpp +++ b/include/rfl/json/Reader.hpp @@ -8,6 +8,7 @@ #endif #include +#include #include #include #include diff --git a/include/rfl/json/schema/Type.hpp b/include/rfl/json/schema/Type.hpp index 4630a296..32e0dcfb 100644 --- a/include/rfl/json/schema/Type.hpp +++ b/include/rfl/json/schema/Type.hpp @@ -7,6 +7,7 @@ #include "../../Literal.hpp" #include "../../Object.hpp" +#include "../../Ref.hpp" #include "../../Rename.hpp" #include "../../Variant.hpp" diff --git a/include/rfl/msgpack/Reader.hpp b/include/rfl/msgpack/Reader.hpp index 2a0bd625..c42c09f4 100644 --- a/include/rfl/msgpack/Reader.hpp +++ b/include/rfl/msgpack/Reader.hpp @@ -5,14 +5,15 @@ #include #include +#include #include #include -//#include "../Bytestring.hpp" +#include "../Bytestring.hpp" #include "../Result.hpp" -//#include "../Vectorstring.hpp" +#include "../Vectorstring.hpp" #include "../always_false.hpp" -//#include "../internal/ptr_cast.hpp" +#include "../internal/ptr_cast.hpp" namespace rfl { namespace msgpack { diff --git a/include/rfl/msgpack/Writer.hpp b/include/rfl/msgpack/Writer.hpp index 2e58828f..dbf980ec 100644 --- a/include/rfl/msgpack/Writer.hpp +++ b/include/rfl/msgpack/Writer.hpp @@ -3,14 +3,13 @@ #include +#include +#include #include #include #include -//#include "../Box.hpp" #include "../Bytestring.hpp" -//#include "../Ref.hpp" -//#include "../Result.hpp" #include "../Vectorstring.hpp" #include "../always_false.hpp" #include "../common.hpp" @@ -47,27 +46,27 @@ class RFL_API Writer { OutputArrayType add_array_to_array(const size_t _size, OutputArrayType* _parent) const noexcept; - OutputArrayType add_array_to_object( - const std::string_view& _name, const size_t _size, - OutputObjectType* _parent) const noexcept; + OutputArrayType add_array_to_object(const std::string_view& _name, + const size_t _size, + OutputObjectType* _parent) const noexcept; - OutputObjectType add_object_to_array( - const size_t _size, OutputArrayType* _parent) const noexcept; + OutputObjectType add_object_to_array(const size_t _size, + OutputArrayType* _parent) const noexcept; OutputObjectType add_object_to_object( const std::string_view& _name, const size_t _size, OutputObjectType* _parent) const noexcept; template - OutputVarType add_value_to_array(const T& _var, - OutputArrayType* /*_parent*/) const noexcept { + OutputVarType add_value_to_array( + const T& _var, OutputArrayType* /*_parent*/) const noexcept { return new_value(_var); } template - OutputVarType add_value_to_object(const std::string_view& _name, - const T& _var, - OutputObjectType* /*_parent*/) const noexcept { + OutputVarType add_value_to_object( + const std::string_view& _name, const T& _var, + OutputObjectType* /*_parent*/) const noexcept { msgpack_pack_str(pk_, _name.size()); msgpack_pack_str_body(pk_, _name.data(), _name.size()); return new_value(_var); @@ -93,7 +92,8 @@ class RFL_API Writer { if constexpr (std::is_same()) { msgpack_pack_str(pk_, _var.size()); msgpack_pack_str_body(pk_, _var.c_str(), _var.size()); - } else if constexpr (std::is_same() || std::is_same()) { + } else if constexpr (std::is_same() || + std::is_same()) { msgpack_pack_bin(pk_, _var.size()); msgpack_pack_bin_body(pk_, _var.data(), _var.size()); } else if constexpr (std::is_same()) { diff --git a/include/rfl/parsing/FieldVariantReader.hpp b/include/rfl/parsing/FieldVariantReader.hpp index e16ea35f..8014fb5b 100644 --- a/include/rfl/parsing/FieldVariantReader.hpp +++ b/include/rfl/parsing/FieldVariantReader.hpp @@ -11,6 +11,7 @@ #include "../Variant.hpp" #include "../internal/is_array.hpp" #include "../internal/nth_element_t.hpp" +#include "Parser_base.hpp" namespace rfl::parsing { diff --git a/include/rfl/parsing/is_required.hpp b/include/rfl/parsing/is_required.hpp index befa2545..bc4cb543 100644 --- a/include/rfl/parsing/is_required.hpp +++ b/include/rfl/parsing/is_required.hpp @@ -8,6 +8,7 @@ #include "../Generic.hpp" #include "../Rename.hpp" #include "../internal/StringLiteral.hpp" +#include "../internal/has_reflection_type_v.hpp" #include "../internal/is_rename.hpp" #include "is_map_like.hpp" #include "is_vector_like.hpp" diff --git a/include/rfl/parsing/schemaful/IsSchemafulReader.hpp b/include/rfl/parsing/schemaful/IsSchemafulReader.hpp index c78ae7bd..d89c834e 100644 --- a/include/rfl/parsing/schemaful/IsSchemafulReader.hpp +++ b/include/rfl/parsing/schemaful/IsSchemafulReader.hpp @@ -2,6 +2,7 @@ #define RFL_PARSING_SCHEMAFUL_ISSCHEMAFULREADER_HPP_ #include +#include #include #include From 2c302d1a8b481f7022bc12527986eb9444b45be6 Mon Sep 17 00:00:00 2001 From: "Dr. Patrick Urbanke" Date: Tue, 21 Oct 2025 23:58:36 +0200 Subject: [PATCH 02/10] Fixed more headers --- include/rfl/parsing/MapReader.hpp | 5 +- include/rfl/parsing/Parser_bytestring.hpp | 1 + include/rfl/parsing/Parser_filepath.hpp | 1 + include/rfl/parsing/Parser_result.hpp | 16 +- include/rfl/parsing/Parser_rfl_variant.hpp | 21 +- include/rfl/parsing/Parser_tagged_union.hpp | 11 +- include/rfl/parsing/Parser_vectorstring.hpp | 5 +- include/rfl/parsing/TaggedUnionWrapper.hpp | 1 + include/rfl/parsing/TupleReader.hpp | 3 + include/rfl/parsing/VectorReader.hpp | 2 + include/rfl/parsing/ViewReaderWithDefault.hpp | 2 + ...ReaderWithDefaultAndStrippedFieldNames.hpp | 2 + .../ViewReaderWithStrippedFieldNames.hpp | 2 + .../rfl/parsing/schema/to_numeric_type.hpp | 43 --- .../parsing/schemaful/IsSchemafulReader.hpp | 2 + .../rfl/parsing/schemaful/OptionalReader.hpp | 1 + .../rfl/parsing/schemaful/SharedPtrReader.hpp | 1 + .../rfl/parsing/schemaful/UniquePtrReader.hpp | 1 + .../rfl/parsing/schemaful/VariantReader.hpp | 1 + .../rfl/parsing/to_single_error_message.hpp | 1 + .../enchantum/details/enchantum_msvc.hpp | 249 +++++++++--------- .../enchantum/details/format_util.hpp | 34 +-- .../rfl/thirdparty/enchantum/fmt_format.hpp | 14 - include/rfl/thirdparty/enchantum/istream.hpp | 19 +- include/rfl/yaml/Reader.hpp | 1 + 25 files changed, 206 insertions(+), 233 deletions(-) delete mode 100644 include/rfl/parsing/schema/to_numeric_type.hpp delete mode 100644 include/rfl/thirdparty/enchantum/fmt_format.hpp diff --git a/include/rfl/parsing/MapReader.hpp b/include/rfl/parsing/MapReader.hpp index 5fe07902..6e932a61 100644 --- a/include/rfl/parsing/MapReader.hpp +++ b/include/rfl/parsing/MapReader.hpp @@ -9,6 +9,8 @@ #include "../Result.hpp" #include "../always_false.hpp" +#include "../internal/has_reflection_type_v.hpp" +#include "Parser_base.hpp" namespace rfl::parsing { @@ -56,7 +58,8 @@ class MapReader { } Result> make_key(auto&& _pair) const noexcept { - static_assert(std::is_rvalue_reference_v, "Expected an rvalue"); + static_assert(std::is_rvalue_reference_v, + "Expected an rvalue"); const auto to_pair = [&](auto&& _key) -> Result> { try { diff --git a/include/rfl/parsing/Parser_bytestring.hpp b/include/rfl/parsing/Parser_bytestring.hpp index 93a7499b..18980d09 100644 --- a/include/rfl/parsing/Parser_bytestring.hpp +++ b/include/rfl/parsing/Parser_bytestring.hpp @@ -5,6 +5,7 @@ #include "../Bytestring.hpp" #include "../Result.hpp" +#include "Parent.hpp" #include "Parser_base.hpp" #include "schema/Type.hpp" diff --git a/include/rfl/parsing/Parser_filepath.hpp b/include/rfl/parsing/Parser_filepath.hpp index eecf5763..0c067cd8 100644 --- a/include/rfl/parsing/Parser_filepath.hpp +++ b/include/rfl/parsing/Parser_filepath.hpp @@ -2,6 +2,7 @@ #define RFL_PARSING_PARSER_FILEPATH_HPP_ #include +#include #include "../Result.hpp" #include "Parser_base.hpp" diff --git a/include/rfl/parsing/Parser_result.hpp b/include/rfl/parsing/Parser_result.hpp index c6e46104..1aa96d0a 100644 --- a/include/rfl/parsing/Parser_result.hpp +++ b/include/rfl/parsing/Parser_result.hpp @@ -4,9 +4,12 @@ #include #include +#include "../Field.hpp" +#include "../NamedTuple.hpp" #include "../Result.hpp" #include "../always_false.hpp" #include "../internal/StringLiteral.hpp" +#include "Parent.hpp" #include "Parser_base.hpp" #include "schema/Type.hpp" @@ -44,17 +47,6 @@ struct Parser, ProcessorsType> { template static void write(const W& _w, const Result& _r, const P& _parent) noexcept { - // const auto write_t = [&](const auto& _t) -> Nothing { - // Parser, ProcessorsType>::write(_w, _t, - // _parent); - // return Nothing{}; - // }; - - // const auto write_err = [&](const auto& _err) -> Nothing { - // Parser::write( - // _w, ErrorType(make_field<"error">(_err.what())), _parent); - // return Nothing{}; - // }; if (_r) { Parser, ProcessorsType>::write( _w, _r.value(), _parent); @@ -62,8 +54,6 @@ struct Parser, ProcessorsType> { Parser::write( _w, ErrorType(make_field<"error">(_r.error().what())), _parent); } - - // _r.transform(write_t).transform_error(write_err); } static schema::Type to_schema( diff --git a/include/rfl/parsing/Parser_rfl_variant.hpp b/include/rfl/parsing/Parser_rfl_variant.hpp index d0f698bd..5de448fc 100644 --- a/include/rfl/parsing/Parser_rfl_variant.hpp +++ b/include/rfl/parsing/Parser_rfl_variant.hpp @@ -7,15 +7,17 @@ #include "../Result.hpp" #include "../Variant.hpp" #include "../always_false.hpp" -#include "../internal/nth_element_t.hpp" #include "../internal/all_fields.hpp" +#include "../internal/nth_element_t.hpp" #include "FieldVariantParser.hpp" +#include "Parent.hpp" #include "Parser_base.hpp" #include "VariantAlternativeWrapper.hpp" #include "schema/Type.hpp" #include "schemaful/IsSchemafulReader.hpp" #include "schemaful/IsSchemafulWriter.hpp" #include "schemaful/VariantReader.hpp" +#include "to_single_error_message.hpp" namespace rfl::parsing { @@ -53,11 +55,11 @@ class Parser, ProcessorsType> { return _r.template read_union, V>(_u); }); - } else if constexpr (ProcessorsType::add_tags_to_variants_ || + } else if constexpr (ProcessorsType::add_tags_to_variants_ || ProcessorsType::add_namespaced_tags_to_variants_) { constexpr bool remove_namespaces = ProcessorsType::add_tags_to_variants_; - using FieldVariantType = - rfl::Variant...>; + using FieldVariantType = rfl::Variant< + VariantAlternativeWrapper...>; const auto from_field_variant = [](auto&& _field) -> rfl::Variant { return std::move(_field.value()); @@ -121,11 +123,12 @@ class Parser, ProcessorsType> { }, _variant); - } else if constexpr (ProcessorsType::add_tags_to_variants_ || + } else if constexpr (ProcessorsType::add_tags_to_variants_ || ProcessorsType::add_namespaced_tags_to_variants_) { constexpr bool remove_namespaces = ProcessorsType::add_tags_to_variants_; using FieldVariantType = - rfl::Variant...>; + rfl::Variant...>; const auto to_field_variant = [](const T& _t) -> FieldVariantType { return VariantAlternativeWrapper(&_t); @@ -148,11 +151,11 @@ class Parser, ProcessorsType> { return FieldVariantParser::to_schema(_definitions); - } else if constexpr (ProcessorsType::add_tags_to_variants_ || + } else if constexpr (ProcessorsType::add_tags_to_variants_ || ProcessorsType::add_namespaced_tags_to_variants_) { constexpr bool remove_namespaces = ProcessorsType::add_tags_to_variants_; - using FieldVariantType = - rfl::Variant...>; + using FieldVariantType = rfl::Variant< + VariantAlternativeWrapper...>; return Parser::to_schema( _definitions); diff --git a/include/rfl/parsing/Parser_tagged_union.hpp b/include/rfl/parsing/Parser_tagged_union.hpp index 35adc902..ce4622d3 100644 --- a/include/rfl/parsing/Parser_tagged_union.hpp +++ b/include/rfl/parsing/Parser_tagged_union.hpp @@ -10,6 +10,7 @@ #include "../always_false.hpp" #include "../internal/strings/strings.hpp" #include "../named_tuple_t.hpp" +#include "../visit.hpp" #include "Parser_base.hpp" #include "TaggedUnionWrapper.hpp" #include "is_tagged_union_wrapper.hpp" @@ -157,13 +158,13 @@ struct Parser, using T = tagged_union_wrapper_no_ptr_t), AlternativeType>>; *_result = Parser::read(_r, _var) - .transform(get_fields) - .transform(to_tagged_union) - .transform_error(embellish_error); + .transform(get_fields) + .transform(to_tagged_union) + .transform_error(embellish_error); } else { *_result = Parser::read(_r, _var) - .transform(to_tagged_union) - .transform_error(embellish_error); + .transform(to_tagged_union) + .transform_error(embellish_error); } *_match_found = true; diff --git a/include/rfl/parsing/Parser_vectorstring.hpp b/include/rfl/parsing/Parser_vectorstring.hpp index 480e77bc..474473da 100644 --- a/include/rfl/parsing/Parser_vectorstring.hpp +++ b/include/rfl/parsing/Parser_vectorstring.hpp @@ -3,8 +3,9 @@ #include -#include "../Vectorstring.hpp" #include "../Result.hpp" +#include "../Vectorstring.hpp" +#include "Parent.hpp" #include "Parser_base.hpp" #include "schema/Type.hpp" @@ -17,7 +18,7 @@ struct Parser { using ParentType = Parent; static Result read(const R& _r, - const InputVarType& _var) noexcept { + const InputVarType& _var) noexcept { return _r.template to_basic_type(_var); } diff --git a/include/rfl/parsing/TaggedUnionWrapper.hpp b/include/rfl/parsing/TaggedUnionWrapper.hpp index feffceea..2335f8e0 100644 --- a/include/rfl/parsing/TaggedUnionWrapper.hpp +++ b/include/rfl/parsing/TaggedUnionWrapper.hpp @@ -3,6 +3,7 @@ #include +#include "../Field.hpp" #include "../Flatten.hpp" #include "../Rename.hpp" #include "../internal/StringLiteral.hpp" diff --git a/include/rfl/parsing/TupleReader.hpp b/include/rfl/parsing/TupleReader.hpp index 0a5f5dc1..c4304450 100644 --- a/include/rfl/parsing/TupleReader.hpp +++ b/include/rfl/parsing/TupleReader.hpp @@ -7,6 +7,9 @@ #include "../Result.hpp" #include "../Tuple.hpp" #include "../internal/is_array.hpp" +#include "AreReaderAndWriter.hpp" +#include "Parser_base.hpp" +#include "is_required.hpp" namespace rfl::parsing { diff --git a/include/rfl/parsing/VectorReader.hpp b/include/rfl/parsing/VectorReader.hpp index 87dfe32c..90824346 100644 --- a/include/rfl/parsing/VectorReader.hpp +++ b/include/rfl/parsing/VectorReader.hpp @@ -1,9 +1,11 @@ #ifndef RFL_PARSING_VECTORREADER_HPP_ #define RFL_PARSING_VECTORREADER_HPP_ +#include #include #include "../Result.hpp" +#include "Parser_base.hpp" #include "is_map_like.hpp" #include "is_set_like.hpp" diff --git a/include/rfl/parsing/ViewReaderWithDefault.hpp b/include/rfl/parsing/ViewReaderWithDefault.hpp index c498c620..a5a56563 100644 --- a/include/rfl/parsing/ViewReaderWithDefault.hpp +++ b/include/rfl/parsing/ViewReaderWithDefault.hpp @@ -8,9 +8,11 @@ #include #include +#include "../Ref.hpp" #include "../Result.hpp" #include "../Tuple.hpp" #include "../internal/is_array.hpp" +#include "Parser_base.hpp" namespace rfl::parsing { diff --git a/include/rfl/parsing/ViewReaderWithDefaultAndStrippedFieldNames.hpp b/include/rfl/parsing/ViewReaderWithDefaultAndStrippedFieldNames.hpp index e93018ee..697060ab 100644 --- a/include/rfl/parsing/ViewReaderWithDefaultAndStrippedFieldNames.hpp +++ b/include/rfl/parsing/ViewReaderWithDefaultAndStrippedFieldNames.hpp @@ -1,6 +1,7 @@ #ifndef RFL_PARSING_VIEWREADERWITHDEFAULTANDSTRIPPEDFIELDNAMES_HPP_ #define RFL_PARSING_VIEWREADERWITHDEFAULTANDSTRIPPEDFIELDNAMES_HPP_ +#include #include #include #include @@ -9,6 +10,7 @@ #include "../Result.hpp" #include "../Tuple.hpp" #include "../internal/is_array.hpp" +#include "Parser_base.hpp" namespace rfl::parsing { diff --git a/include/rfl/parsing/ViewReaderWithStrippedFieldNames.hpp b/include/rfl/parsing/ViewReaderWithStrippedFieldNames.hpp index c4ab784d..5787a1e0 100644 --- a/include/rfl/parsing/ViewReaderWithStrippedFieldNames.hpp +++ b/include/rfl/parsing/ViewReaderWithStrippedFieldNames.hpp @@ -2,6 +2,7 @@ #define RFL_PARSING_VIEWREADERWITHSTRIPPEDFIELDNAMES_HPP_ #include +#include #include #include #include @@ -10,6 +11,7 @@ #include "../Result.hpp" #include "../Tuple.hpp" #include "../internal/is_array.hpp" +#include "Parser_base.hpp" namespace rfl::parsing { diff --git a/include/rfl/parsing/schema/to_numeric_type.hpp b/include/rfl/parsing/schema/to_numeric_type.hpp deleted file mode 100644 index cb9e4d47..00000000 --- a/include/rfl/parsing/schema/to_numeric_type.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef RFL_PARSING_SCHEMA_TONUMERICTYPE_HPP_ -#define RFL_PARSING_SCHEMA_TONUMERICTYPE_HPP_ - -#include - -#include "../../always_false.hpp" -#include "Type.hpp" - -namespace rfl::parsing::schema { - -template -inline schema::Type::NumericType to_numeric_type() { - using U = std::remove_cvref_t; - - if constexpr (std::is_same()) { - return Type::NumericType(Type::Int32{}); - - } else if constexpr (std::is_same()) { - return Type::NumericType(Type::Int64{}); - - } else if constexpr (std::is_same()) { - return Type::NumericType(Type::UInt32{}); - - } else if constexpr (std::is_same()) { - return Type::NumericType(Type::UInt64{}); - - } else if constexpr (std::is_integral()) { - return Type::NumericType(Type::Integer{}); - - } else if constexpr (std::is_same()) { - return Type::NumericType(Type::Float{}); - - } else if constexpr (std::is_floating_point_v) { - return Type::NumericType(Type::Double{}); - - } else { - static_assert(always_false_v, "Not a numeric value."); - } -} - -} // namespace rfl::parsing::schema - -#endif diff --git a/include/rfl/parsing/schemaful/IsSchemafulReader.hpp b/include/rfl/parsing/schemaful/IsSchemafulReader.hpp index d89c834e..19ecdc8c 100644 --- a/include/rfl/parsing/schemaful/IsSchemafulReader.hpp +++ b/include/rfl/parsing/schemaful/IsSchemafulReader.hpp @@ -6,6 +6,8 @@ #include #include +#include "../../Result.hpp" + namespace rfl::parsing::schemaful { using MockVariantType = std::variant; diff --git a/include/rfl/parsing/schemaful/OptionalReader.hpp b/include/rfl/parsing/schemaful/OptionalReader.hpp index 2753f614..6f423c54 100644 --- a/include/rfl/parsing/schemaful/OptionalReader.hpp +++ b/include/rfl/parsing/schemaful/OptionalReader.hpp @@ -5,6 +5,7 @@ #include #include "../../Result.hpp" +#include "../Parser_base.hpp" namespace rfl::parsing::schemaful { diff --git a/include/rfl/parsing/schemaful/SharedPtrReader.hpp b/include/rfl/parsing/schemaful/SharedPtrReader.hpp index baad5e53..154e5b52 100644 --- a/include/rfl/parsing/schemaful/SharedPtrReader.hpp +++ b/include/rfl/parsing/schemaful/SharedPtrReader.hpp @@ -5,6 +5,7 @@ #include #include "../../Result.hpp" +#include "../Parser_base.hpp" namespace rfl::parsing::schemaful { diff --git a/include/rfl/parsing/schemaful/UniquePtrReader.hpp b/include/rfl/parsing/schemaful/UniquePtrReader.hpp index 888cf634..b27fa23e 100644 --- a/include/rfl/parsing/schemaful/UniquePtrReader.hpp +++ b/include/rfl/parsing/schemaful/UniquePtrReader.hpp @@ -5,6 +5,7 @@ #include #include "../../Result.hpp" +#include "../Parser_base.hpp" namespace rfl::parsing::schemaful { diff --git a/include/rfl/parsing/schemaful/VariantReader.hpp b/include/rfl/parsing/schemaful/VariantReader.hpp index 00857f8e..5b6656e4 100644 --- a/include/rfl/parsing/schemaful/VariantReader.hpp +++ b/include/rfl/parsing/schemaful/VariantReader.hpp @@ -6,6 +6,7 @@ #include "../../Result.hpp" #include "../../internal/nth_element_t.hpp" +#include "../Parser_base.hpp" namespace rfl::parsing::schemaful { diff --git a/include/rfl/parsing/to_single_error_message.hpp b/include/rfl/parsing/to_single_error_message.hpp index e4669ac4..b56837b6 100644 --- a/include/rfl/parsing/to_single_error_message.hpp +++ b/include/rfl/parsing/to_single_error_message.hpp @@ -6,6 +6,7 @@ #include #include +#include "../Result.hpp" #include "../internal/strings/strings.hpp" namespace rfl::parsing { diff --git a/include/rfl/thirdparty/enchantum/details/enchantum_msvc.hpp b/include/rfl/thirdparty/enchantum/details/enchantum_msvc.hpp index a72e3193..d98ca7fc 100644 --- a/include/rfl/thirdparty/enchantum/details/enchantum_msvc.hpp +++ b/include/rfl/thirdparty/enchantum/details/enchantum_msvc.hpp @@ -1,60 +1,65 @@ #pragma once + +#if defined(_MSC_VER) + +#include +#include + +#include "../bitflags.hpp" #include "../common.hpp" #include "generate_arrays.hpp" #include "string_view.hpp" -#include -#include namespace enchantum { namespace details { #define SZC(x) (sizeof(x) - 1) - template - constexpr auto type_name_func_size() noexcept - { - // (sizeof("auto __cdecl enchantum::details::type_name_func<") - 1) - return SZC(__FUNCSIG__) - SZC("auto __cdecl enchantum::details::type_name_func_size(void) noexcept"); - } - - template - constexpr auto enum_in_array_name() noexcept - { - string_view s = __FUNCSIG__ + sizeof("auto __cdecl enchantum::details::enum_in_array_name<") - 1; - s.remove_suffix(sizeof(">(void) noexcept") - 1); - - if constexpr (ScopedEnum) { - if (s.front() == '(') { - s.remove_prefix(sizeof("(enum ") - 1); - s.remove_suffix(sizeof(")0x0") - 1); - return s; - } - return s.substr(0, s.rfind("::")); +template +constexpr auto type_name_func_size() noexcept { + // (sizeof("auto __cdecl enchantum::details::type_name_func<") - 1) + return SZC(__FUNCSIG__) - + SZC("auto __cdecl enchantum::details::type_name_func_size(void) noexcept"); +} + +template +constexpr auto enum_in_array_name() noexcept { + string_view s = + __FUNCSIG__ + + sizeof("auto __cdecl enchantum::details::enum_in_array_name<") - 1; + s.remove_suffix(sizeof(">(void) noexcept") - 1); + + if constexpr (ScopedEnum) { + if (s.front() == '(') { + s.remove_prefix(sizeof("(enum ") - 1); + s.remove_suffix(sizeof(")0x0") - 1); + return s; } - else { - if (s.front() == '(') { - s.remove_prefix(sizeof("(enum ") - 1); - s.remove_suffix(sizeof(")0x0") - 1); - } - if (const auto pos = s.rfind("::"); pos != s.npos) - return s.substr(0, pos); - return string_view(); + return s.substr(0, s.rfind("::")); + } else { + if (s.front() == '(') { + s.remove_prefix(sizeof("(enum ") - 1); + s.remove_suffix(sizeof(")0x0") - 1); } + if (const auto pos = s.rfind("::"); pos != s.npos) return s.substr(0, pos); + return string_view(); } +} - template - constexpr auto var_name() noexcept - { - //auto __cdecl f{enum `anonymous-namespace'::UnscopedAnon +template +constexpr auto var_name() noexcept { + // auto __cdecl f{enum `anonymous-namespace'::UnscopedAnon - using T = typename decltype(Array)::value_type; + using T = typename decltype(Array)::value_type; #define SZC(x) (sizeof(x) - 1) - std::size_t funcsig_off = SZC("auto __cdecl enchantum::details::var_name(); - funcsig_off += type_name_len + SZC(","); - constexpr auto Size = Array.size(); - // clang-format off + std::size_t funcsig_off = + SZC("auto __cdecl enchantum::details::var_name(); + funcsig_off += type_name_len + SZC(","); + constexpr auto Size = Array.size(); + // clang-format off funcsig_off += Size < 10 ? 1 : Size < 100 ? 2 : Size < 1000 ? 3 @@ -65,94 +70,94 @@ namespace details { : Size < 100000000 ? 8 : Size < 1000000000 ? 9 : 10; - // clang-format on - funcsig_off += SZC(">{enum ") + type_name_len; - return string_view(__FUNCSIG__ + funcsig_off, SZC(__FUNCSIG__) - funcsig_off - (sizeof("}>(void) noexcept") - 1)); - } + // clang-format on + funcsig_off += SZC(">{enum ") + type_name_len; + return string_view( + __FUNCSIG__ + funcsig_off, + SZC(__FUNCSIG__) - funcsig_off - (sizeof("}>(void) noexcept") - 1)); +} #undef SZC +template +inline constexpr auto static_storage_for = Copy; + +template +constexpr auto get_elements() { + constexpr auto type_name_len = details::type_name_func_size(); + + auto str = var_name(); + struct RetVal { + std::array pairs{}; + std::size_t total_string_length = 0; + std::size_t valid_count = 0; + } ret; + std::size_t index = 0; + constexpr auto enum_in_array_len = details::enum_in_array_name().size(); + while (index < Array.size()) { + if (str.front() == '(') { + str.remove_prefix(sizeof("(enum ") - 1 + type_name_len + sizeof(")0x0") - + 1); // there is atleast 1 base 16 hex digit - template - inline constexpr auto static_storage_for = Copy; - - template - constexpr auto get_elements() - { - constexpr auto type_name_len = details::type_name_func_size(); - - auto str = var_name(); - struct RetVal { - std::array pairs{}; - std::size_t total_string_length = 0; - std::size_t valid_count = 0; - } ret; - std::size_t index = 0; - constexpr auto enum_in_array_len = details::enum_in_array_name().size(); - while (index < Array.size()) { - if (str.front() == '(') { - str.remove_prefix(sizeof("(enum ") - 1 + type_name_len + sizeof(")0x0") - 1); // there is atleast 1 base 16 hex digit - - if (const auto commapos = str.find(','); commapos != str.npos) - str.remove_prefix(commapos + 1); - } - else { - if constexpr (enum_in_array_len != 0) - str.remove_prefix(enum_in_array_len + sizeof("::") - 1); - - if constexpr (details::prefix_length_or_zero != 0) - str.remove_prefix(details::prefix_length_or_zero); - - const auto commapos = str.find(','); - - const auto name = str.substr(0, commapos); - - ret.pairs[ret.valid_count] = Pair{Array[index], name}; - ret.total_string_length += name.size() + ShouldNullTerminate; - - if (commapos != str.npos) - str.remove_prefix(commapos + 1); - ++ret.valid_count; - } - ++index; + if (const auto commapos = str.find(','); commapos != str.npos) + str.remove_prefix(commapos + 1); + } else { + if constexpr (enum_in_array_len != 0) + str.remove_prefix(enum_in_array_len + sizeof("::") - 1); + + if constexpr (details::prefix_length_or_zero != 0) + str.remove_prefix(details::prefix_length_or_zero); + + const auto commapos = str.find(','); + + const auto name = str.substr(0, commapos); + + ret.pairs[ret.valid_count] = Pair{Array[index], name}; + ret.total_string_length += name.size() + ShouldNullTerminate; + + if (commapos != str.npos) str.remove_prefix(commapos + 1); + ++ret.valid_count; } - return ret; + ++index; } + return ret; +} - template - constexpr auto reflect() noexcept - { - constexpr auto Min = enum_traits::min; - constexpr auto Max = enum_traits::max; - - constexpr auto elements = details::get_elements(), ShouldNullTerminate>(); - - constexpr auto strings = [elements]() { - std::array strings; - for (std::size_t _i = 0, index = 0; _i < elements.valid_count; ++_i) { - const auto& [_, s] = elements.pairs[_i]; - for (std::size_t i = 0; i < s.size(); ++i) - strings[index++] = s[i]; - - if constexpr (ShouldNullTerminate) - strings[index++] = '\0'; - } - return strings; - }(); - - std::array ret; - constexpr const auto* str = static_storage_for.data(); - for (std::size_t i = 0, string_index = 0; i < elements.valid_count; ++i) { - const auto& [e, s] = elements.pairs[i]; - auto& [re, rs] = ret[i]; - re = e; - - rs = {str + string_index, str + string_index + s.size()}; - string_index += s.size() + ShouldNullTerminate; - } +template +constexpr auto reflect() noexcept { + constexpr auto Min = enum_traits::min; + constexpr auto Max = enum_traits::max; - return ret; + constexpr auto elements = + details::get_elements(), + ShouldNullTerminate>(); + + constexpr auto strings = [elements]() { + std::array strings; + for (std::size_t _i = 0, index = 0; _i < elements.valid_count; ++_i) { + const auto& [_, s] = elements.pairs[_i]; + for (std::size_t i = 0; i < s.size(); ++i) strings[index++] = s[i]; + + if constexpr (ShouldNullTerminate) strings[index++] = '\0'; + } + return strings; + }(); + + std::array ret; + constexpr const auto* str = static_storage_for.data(); + for (std::size_t i = 0, string_index = 0; i < elements.valid_count; ++i) { + const auto& [e, s] = elements.pairs[i]; + auto& [re, rs] = ret[i]; + re = e; + + rs = {str + string_index, str + string_index + s.size()}; + string_index += s.size() + ShouldNullTerminate; } -} // namespace details + return ret; +} +} // namespace details + +} // namespace enchantum + +#endif -} // namespace enchantum diff --git a/include/rfl/thirdparty/enchantum/details/format_util.hpp b/include/rfl/thirdparty/enchantum/details/format_util.hpp index ac1c9798..a3b9aea3 100644 --- a/include/rfl/thirdparty/enchantum/details/format_util.hpp +++ b/include/rfl/thirdparty/enchantum/details/format_util.hpp @@ -1,20 +1,24 @@ -#include "../enchantum.hpp" +#pragma once + #include +#include "../bitflags.hpp" +#include "../enchantum.hpp" + namespace enchantum { namespace details { - template - std::string format(E e) noexcept - { - if constexpr (is_bitflag) { - if (const auto name = enchantum::to_string_bitflag(e); !name.empty()) - return std::string(name.data(), name.size()); - } - else { - if (const auto name = enchantum::to_string(e); !name.empty()) - return std::string(name.data(), name.size()); - } - return std::to_string(+enchantum::to_underlying(e)); // promote using + to select int overload if to underlying returns char +template +std::string format(E e) noexcept { + if constexpr (is_bitflag) { + if (const auto name = enchantum::to_string_bitflag(e); !name.empty()) + return std::string(name.data(), name.size()); + } else { + if (const auto name = enchantum::to_string(e); !name.empty()) + return std::string(name.data(), name.size()); } -} // namespace details -} // namespace enchantum \ No newline at end of file + return std::to_string( + +enchantum::to_underlying(e)); // promote using + to select int overload + // if to underlying returns char +} +} // namespace details +} // namespace enchantum diff --git a/include/rfl/thirdparty/enchantum/fmt_format.hpp b/include/rfl/thirdparty/enchantum/fmt_format.hpp deleted file mode 100644 index 6c2c4efa..00000000 --- a/include/rfl/thirdparty/enchantum/fmt_format.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "details/format_util.hpp" -#include "enchantum.hpp" -#include - -template -struct fmt::formatter : fmt::formatter { - template - constexpr auto format(const E e, FmtContext& ctx) const - { - return fmt::formatter::format(enchantum::details::format(e), ctx); - } -}; \ No newline at end of file diff --git a/include/rfl/thirdparty/enchantum/istream.hpp b/include/rfl/thirdparty/enchantum/istream.hpp index b003279f..197a5216 100644 --- a/include/rfl/thirdparty/enchantum/istream.hpp +++ b/include/rfl/thirdparty/enchantum/istream.hpp @@ -1,26 +1,27 @@ #pragma once -#include "enchantum.hpp" #include +#include #include #include +#include "bitflags.hpp" +#include "enchantum.hpp" + namespace enchantum::istream_operators { -template +template requires std::assignable_from -std::basic_istream& operator>>(std::basic_istream& is, E& value) -{ +std::basic_istream& operator>>( + std::basic_istream& is, E& value) { std::basic_string s; is >> s; - if (!is) - return is; + if (!is) return is; if constexpr (is_bitflag) { if (const auto v = enchantum::cast_bitflag(s)) value = *v; else is.setstate(std::ios_base::failbit); - } - else { + } else { if (const auto v = enchantum::cast(s)) value = *v; else @@ -29,4 +30,4 @@ std::basic_istream& operator>>(std::basic_istream& i return is; } -} // namespace enchantum::istream_operators +} // namespace enchantum::istream_operators diff --git a/include/rfl/yaml/Reader.hpp b/include/rfl/yaml/Reader.hpp index e6c2cfd2..505339e2 100644 --- a/include/rfl/yaml/Reader.hpp +++ b/include/rfl/yaml/Reader.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include From 679a65a7768bce3ec46465e4b52305c9f01711e2 Mon Sep 17 00:00:00 2001 From: "Dr. Patrick Urbanke" Date: Fri, 24 Oct 2025 23:13:03 +0200 Subject: [PATCH 03/10] Added the format specifier to linux --- .github/workflows/linux.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/linux.yaml b/.github/workflows/linux.yaml index 0125cca6..f824b7a7 100644 --- a/.github/workflows/linux.yaml +++ b/.github/workflows/linux.yaml @@ -10,7 +10,7 @@ jobs: strategy: fail-fast: false matrix: - format: ["JSON", "AVRO", "CAPNPROTO", "CBOR", "FLEXBUFFERS", "MSGPACK", "PARQUET", "TOML", "UBJSON", "XML", "YAML", "benchmarks"] + format: ["JSON", "AVRO", "CAPNPROTO", "CBOR", "FLEXBUFFERS", "MSGPACK", "PARQUET", "TOML", "UBJSON", "XML", "YAML", "benchmarks", "headers"] compiler: [llvm, gcc] compiler-version: [11, 12, 13, 14, 16, 17, 18] cxx: [20, 23] @@ -82,12 +82,14 @@ jobs: cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=${{ matrix.cxx }} -DCMAKE_CXX_STANDARD=20 -DREFLECTCPP_BUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Release elif [[ "${{ matrix.format }}" == "benchmarks" ]]; then cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=${{ matrix.cxx }} -DCMAKE_CXX_STANDARD=20 -DREFLECTCPP_BUILD_BENCHMARKS=ON -DREFLECTCPP_ALL_FORMATS=ON -DCMAKE_BUILD_TYPE=Release + elif [[ "${{ matrix.format }}" == "headers" ]]; then + cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=${{ matrix.cxx }} -DCMAKE_CXX_STANDARD=20 -DREFLECTCPP_CHECK_HEADERS=ON -DCMAKE_BUILD_TYPE=Release else cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=${{ matrix.cxx }} -DCMAKE_CXX_STANDARD=20 -DREFLECTCPP_BUILD_TESTS=ON -DREFLECTCPP_JSON=OFF -DREFLECTCPP_${{ matrix.format }}=ON -DCMAKE_BUILD_TYPE=Release fi cmake --build build -j4 - name: Run tests - if: matrix.format != 'benchmarks' + if: (matrix.format != 'benchmarks') && (matrix.format != 'headers') run: | ctest --test-dir build --output-on-failure - name: Run benchmarks From 1be1dddc3ab557c87035b2a9cd3ba33e9f9816f7 Mon Sep 17 00:00:00 2001 From: "Dr. Patrick Urbanke" Date: Fri, 24 Oct 2025 23:13:12 +0200 Subject: [PATCH 04/10] Reduce the matrix for MacOS --- .github/workflows/macos.yaml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/macos.yaml b/.github/workflows/macos.yaml index 109b232c..28b398dd 100644 --- a/.github/workflows/macos.yaml +++ b/.github/workflows/macos.yaml @@ -11,7 +11,7 @@ jobs: fail-fast: false matrix: os: ["macos-latest", "macos-13"] - format: ["JSON", "AVRO", "CAPNPROTO", "CBOR", "FLEXBUFFERS", "MSGPACK", "PARQUET", "TOML", "UBJSON", "XML", "YAML", "benchmarks"] + format: ["tests", "benchmarks"] name: "${{ matrix.os }} (${{ matrix.format }})" runs-on: ${{ matrix.os }} steps: @@ -43,12 +43,10 @@ jobs: export CMAKE_GENERATOR=Ninja fi $CXX --version - if [[ "${{ matrix.format }}" == "JSON" ]]; then - cmake -S . -B build -DCMAKE_CXX_STANDARD=20 -DREFLECTCPP_BUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ - elif [[ "${{ matrix.format }}" == "benchmarks" ]]; then + if [[ "${{ matrix.format }}" == "benchmarks" ]]; then cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=${{ matrix.cxx }} -DCMAKE_CXX_STANDARD=20 -DREFLECTCPP_BUILD_BENCHMARKS=ON -DREFLECTCPP_ALL_FORMATS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ else - cmake -S . -B build -DCMAKE_CXX_STANDARD=20 -DREFLECTCPP_BUILD_TESTS=ON -DREFLECTCPP_JSON=OFF -DREFLECTCPP_${{ matrix.format }}=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ + cmake -S . -B build -DCMAKE_CXX_STANDARD=20 -DREFLECTCPP_BUILD_TESTS=ON -DREFLECTCPP_ALL_FORMATS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ fi cmake --build build -j 4 - name: Run tests From c528e26dec0af8e2da267c2e6aeb0d9a6865d7cf Mon Sep 17 00:00:00 2001 From: "Dr. Patrick Urbanke" Date: Fri, 24 Oct 2025 23:20:09 +0200 Subject: [PATCH 05/10] Fixed include --- include/rfl/thirdparty/enchantum/all.hpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/include/rfl/thirdparty/enchantum/all.hpp b/include/rfl/thirdparty/enchantum/all.hpp index c6038a82..a70a21a1 100644 --- a/include/rfl/thirdparty/enchantum/all.hpp +++ b/include/rfl/thirdparty/enchantum/all.hpp @@ -1,20 +1,14 @@ #pragma once -#include "details/optional.hpp" -#include "details/string_view.hpp" -#include "details/generate_arrays.hpp" - #include "algorithms.hpp" #include "array.hpp" #include "bitflags.hpp" +#include "bitset.hpp" #include "bitwise_operators.hpp" +#include "details/generate_arrays.hpp" +#include "details/optional.hpp" +#include "details/string_view.hpp" #include "enchantum.hpp" #include "entries.hpp" #include "iostream.hpp" #include "next_value.hpp" -#include "bitset.hpp" - -#if __has_include() - #include "fmt_format.hpp" -#elif __has_include() - #include "std_format.hpp" -#endif \ No newline at end of file +#include "std_format.hpp" From 87b2b18d049c1ccb10bc412036bab6a3595e011e Mon Sep 17 00:00:00 2001 From: "Dr. Patrick Urbanke" Date: Fri, 24 Oct 2025 23:51:19 +0200 Subject: [PATCH 06/10] Recreated the original state of the enchantum thirdparty library --- include/rfl/thirdparty/enchantum/all.hpp | 16 +- .../enchantum/details/enchantum_msvc.hpp | 249 +++++++++--------- .../enchantum/details/format_util.hpp | 34 ++- .../rfl/thirdparty/enchantum/fmt_format.hpp | 14 + include/rfl/thirdparty/enchantum/istream.hpp | 19 +- 5 files changed, 171 insertions(+), 161 deletions(-) create mode 100644 include/rfl/thirdparty/enchantum/fmt_format.hpp diff --git a/include/rfl/thirdparty/enchantum/all.hpp b/include/rfl/thirdparty/enchantum/all.hpp index a70a21a1..c6038a82 100644 --- a/include/rfl/thirdparty/enchantum/all.hpp +++ b/include/rfl/thirdparty/enchantum/all.hpp @@ -1,14 +1,20 @@ #pragma once +#include "details/optional.hpp" +#include "details/string_view.hpp" +#include "details/generate_arrays.hpp" + #include "algorithms.hpp" #include "array.hpp" #include "bitflags.hpp" -#include "bitset.hpp" #include "bitwise_operators.hpp" -#include "details/generate_arrays.hpp" -#include "details/optional.hpp" -#include "details/string_view.hpp" #include "enchantum.hpp" #include "entries.hpp" #include "iostream.hpp" #include "next_value.hpp" -#include "std_format.hpp" +#include "bitset.hpp" + +#if __has_include() + #include "fmt_format.hpp" +#elif __has_include() + #include "std_format.hpp" +#endif \ No newline at end of file diff --git a/include/rfl/thirdparty/enchantum/details/enchantum_msvc.hpp b/include/rfl/thirdparty/enchantum/details/enchantum_msvc.hpp index d98ca7fc..a72e3193 100644 --- a/include/rfl/thirdparty/enchantum/details/enchantum_msvc.hpp +++ b/include/rfl/thirdparty/enchantum/details/enchantum_msvc.hpp @@ -1,65 +1,60 @@ #pragma once - -#if defined(_MSC_VER) - -#include -#include - -#include "../bitflags.hpp" #include "../common.hpp" #include "generate_arrays.hpp" #include "string_view.hpp" +#include +#include namespace enchantum { namespace details { #define SZC(x) (sizeof(x) - 1) -template -constexpr auto type_name_func_size() noexcept { - // (sizeof("auto __cdecl enchantum::details::type_name_func<") - 1) - return SZC(__FUNCSIG__) - - SZC("auto __cdecl enchantum::details::type_name_func_size(void) noexcept"); -} - -template -constexpr auto enum_in_array_name() noexcept { - string_view s = - __FUNCSIG__ + - sizeof("auto __cdecl enchantum::details::enum_in_array_name<") - 1; - s.remove_suffix(sizeof(">(void) noexcept") - 1); - - if constexpr (ScopedEnum) { - if (s.front() == '(') { - s.remove_prefix(sizeof("(enum ") - 1); - s.remove_suffix(sizeof(")0x0") - 1); - return s; + template + constexpr auto type_name_func_size() noexcept + { + // (sizeof("auto __cdecl enchantum::details::type_name_func<") - 1) + return SZC(__FUNCSIG__) - SZC("auto __cdecl enchantum::details::type_name_func_size(void) noexcept"); + } + + template + constexpr auto enum_in_array_name() noexcept + { + string_view s = __FUNCSIG__ + sizeof("auto __cdecl enchantum::details::enum_in_array_name<") - 1; + s.remove_suffix(sizeof(">(void) noexcept") - 1); + + if constexpr (ScopedEnum) { + if (s.front() == '(') { + s.remove_prefix(sizeof("(enum ") - 1); + s.remove_suffix(sizeof(")0x0") - 1); + return s; + } + return s.substr(0, s.rfind("::")); } - return s.substr(0, s.rfind("::")); - } else { - if (s.front() == '(') { - s.remove_prefix(sizeof("(enum ") - 1); - s.remove_suffix(sizeof(")0x0") - 1); + else { + if (s.front() == '(') { + s.remove_prefix(sizeof("(enum ") - 1); + s.remove_suffix(sizeof(")0x0") - 1); + } + if (const auto pos = s.rfind("::"); pos != s.npos) + return s.substr(0, pos); + return string_view(); } - if (const auto pos = s.rfind("::"); pos != s.npos) return s.substr(0, pos); - return string_view(); } -} -template -constexpr auto var_name() noexcept { - // auto __cdecl f{enum `anonymous-namespace'::UnscopedAnon + template + constexpr auto var_name() noexcept + { + //auto __cdecl f{enum `anonymous-namespace'::UnscopedAnon - using T = typename decltype(Array)::value_type; + using T = typename decltype(Array)::value_type; #define SZC(x) (sizeof(x) - 1) - std::size_t funcsig_off = - SZC("auto __cdecl enchantum::details::var_name(); - funcsig_off += type_name_len + SZC(","); - constexpr auto Size = Array.size(); - // clang-format off + std::size_t funcsig_off = SZC("auto __cdecl enchantum::details::var_name(); + funcsig_off += type_name_len + SZC(","); + constexpr auto Size = Array.size(); + // clang-format off funcsig_off += Size < 10 ? 1 : Size < 100 ? 2 : Size < 1000 ? 3 @@ -70,94 +65,94 @@ constexpr auto var_name() noexcept { : Size < 100000000 ? 8 : Size < 1000000000 ? 9 : 10; - // clang-format on - funcsig_off += SZC(">{enum ") + type_name_len; - return string_view( - __FUNCSIG__ + funcsig_off, - SZC(__FUNCSIG__) - funcsig_off - (sizeof("}>(void) noexcept") - 1)); -} + // clang-format on + funcsig_off += SZC(">{enum ") + type_name_len; + return string_view(__FUNCSIG__ + funcsig_off, SZC(__FUNCSIG__) - funcsig_off - (sizeof("}>(void) noexcept") - 1)); + } #undef SZC -template -inline constexpr auto static_storage_for = Copy; - -template -constexpr auto get_elements() { - constexpr auto type_name_len = details::type_name_func_size(); - - auto str = var_name(); - struct RetVal { - std::array pairs{}; - std::size_t total_string_length = 0; - std::size_t valid_count = 0; - } ret; - std::size_t index = 0; - constexpr auto enum_in_array_len = details::enum_in_array_name().size(); - while (index < Array.size()) { - if (str.front() == '(') { - str.remove_prefix(sizeof("(enum ") - 1 + type_name_len + sizeof(")0x0") - - 1); // there is atleast 1 base 16 hex digit - if (const auto commapos = str.find(','); commapos != str.npos) - str.remove_prefix(commapos + 1); - } else { - if constexpr (enum_in_array_len != 0) - str.remove_prefix(enum_in_array_len + sizeof("::") - 1); - - if constexpr (details::prefix_length_or_zero != 0) - str.remove_prefix(details::prefix_length_or_zero); - - const auto commapos = str.find(','); - - const auto name = str.substr(0, commapos); - - ret.pairs[ret.valid_count] = Pair{Array[index], name}; - ret.total_string_length += name.size() + ShouldNullTerminate; - - if (commapos != str.npos) str.remove_prefix(commapos + 1); - ++ret.valid_count; + template + inline constexpr auto static_storage_for = Copy; + + template + constexpr auto get_elements() + { + constexpr auto type_name_len = details::type_name_func_size(); + + auto str = var_name(); + struct RetVal { + std::array pairs{}; + std::size_t total_string_length = 0; + std::size_t valid_count = 0; + } ret; + std::size_t index = 0; + constexpr auto enum_in_array_len = details::enum_in_array_name().size(); + while (index < Array.size()) { + if (str.front() == '(') { + str.remove_prefix(sizeof("(enum ") - 1 + type_name_len + sizeof(")0x0") - 1); // there is atleast 1 base 16 hex digit + + if (const auto commapos = str.find(','); commapos != str.npos) + str.remove_prefix(commapos + 1); + } + else { + if constexpr (enum_in_array_len != 0) + str.remove_prefix(enum_in_array_len + sizeof("::") - 1); + + if constexpr (details::prefix_length_or_zero != 0) + str.remove_prefix(details::prefix_length_or_zero); + + const auto commapos = str.find(','); + + const auto name = str.substr(0, commapos); + + ret.pairs[ret.valid_count] = Pair{Array[index], name}; + ret.total_string_length += name.size() + ShouldNullTerminate; + + if (commapos != str.npos) + str.remove_prefix(commapos + 1); + ++ret.valid_count; + } + ++index; } - ++index; + return ret; } - return ret; -} - -template -constexpr auto reflect() noexcept { - constexpr auto Min = enum_traits::min; - constexpr auto Max = enum_traits::max; - constexpr auto elements = - details::get_elements(), - ShouldNullTerminate>(); - - constexpr auto strings = [elements]() { - std::array strings; - for (std::size_t _i = 0, index = 0; _i < elements.valid_count; ++_i) { - const auto& [_, s] = elements.pairs[_i]; - for (std::size_t i = 0; i < s.size(); ++i) strings[index++] = s[i]; - - if constexpr (ShouldNullTerminate) strings[index++] = '\0'; + template + constexpr auto reflect() noexcept + { + constexpr auto Min = enum_traits::min; + constexpr auto Max = enum_traits::max; + + constexpr auto elements = details::get_elements(), ShouldNullTerminate>(); + + constexpr auto strings = [elements]() { + std::array strings; + for (std::size_t _i = 0, index = 0; _i < elements.valid_count; ++_i) { + const auto& [_, s] = elements.pairs[_i]; + for (std::size_t i = 0; i < s.size(); ++i) + strings[index++] = s[i]; + + if constexpr (ShouldNullTerminate) + strings[index++] = '\0'; + } + return strings; + }(); + + std::array ret; + constexpr const auto* str = static_storage_for.data(); + for (std::size_t i = 0, string_index = 0; i < elements.valid_count; ++i) { + const auto& [e, s] = elements.pairs[i]; + auto& [re, rs] = ret[i]; + re = e; + + rs = {str + string_index, str + string_index + s.size()}; + string_index += s.size() + ShouldNullTerminate; } - return strings; - }(); - - std::array ret; - constexpr const auto* str = static_storage_for.data(); - for (std::size_t i = 0, string_index = 0; i < elements.valid_count; ++i) { - const auto& [e, s] = elements.pairs[i]; - auto& [re, rs] = ret[i]; - re = e; - - rs = {str + string_index, str + string_index + s.size()}; - string_index += s.size() + ShouldNullTerminate; - } - return ret; -} -} // namespace details - -} // namespace enchantum + return ret; + } +} // namespace details -#endif +} // namespace enchantum diff --git a/include/rfl/thirdparty/enchantum/details/format_util.hpp b/include/rfl/thirdparty/enchantum/details/format_util.hpp index a3b9aea3..ac1c9798 100644 --- a/include/rfl/thirdparty/enchantum/details/format_util.hpp +++ b/include/rfl/thirdparty/enchantum/details/format_util.hpp @@ -1,24 +1,20 @@ -#pragma once - -#include - -#include "../bitflags.hpp" #include "../enchantum.hpp" +#include namespace enchantum { namespace details { -template -std::string format(E e) noexcept { - if constexpr (is_bitflag) { - if (const auto name = enchantum::to_string_bitflag(e); !name.empty()) - return std::string(name.data(), name.size()); - } else { - if (const auto name = enchantum::to_string(e); !name.empty()) - return std::string(name.data(), name.size()); + template + std::string format(E e) noexcept + { + if constexpr (is_bitflag) { + if (const auto name = enchantum::to_string_bitflag(e); !name.empty()) + return std::string(name.data(), name.size()); + } + else { + if (const auto name = enchantum::to_string(e); !name.empty()) + return std::string(name.data(), name.size()); + } + return std::to_string(+enchantum::to_underlying(e)); // promote using + to select int overload if to underlying returns char } - return std::to_string( - +enchantum::to_underlying(e)); // promote using + to select int overload - // if to underlying returns char -} -} // namespace details -} // namespace enchantum +} // namespace details +} // namespace enchantum \ No newline at end of file diff --git a/include/rfl/thirdparty/enchantum/fmt_format.hpp b/include/rfl/thirdparty/enchantum/fmt_format.hpp new file mode 100644 index 00000000..6c2c4efa --- /dev/null +++ b/include/rfl/thirdparty/enchantum/fmt_format.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include "details/format_util.hpp" +#include "enchantum.hpp" +#include + +template +struct fmt::formatter : fmt::formatter { + template + constexpr auto format(const E e, FmtContext& ctx) const + { + return fmt::formatter::format(enchantum::details::format(e), ctx); + } +}; \ No newline at end of file diff --git a/include/rfl/thirdparty/enchantum/istream.hpp b/include/rfl/thirdparty/enchantum/istream.hpp index 197a5216..b003279f 100644 --- a/include/rfl/thirdparty/enchantum/istream.hpp +++ b/include/rfl/thirdparty/enchantum/istream.hpp @@ -1,27 +1,26 @@ #pragma once +#include "enchantum.hpp" #include -#include #include #include -#include "bitflags.hpp" -#include "enchantum.hpp" - namespace enchantum::istream_operators { -template +template requires std::assignable_from -std::basic_istream& operator>>( - std::basic_istream& is, E& value) { +std::basic_istream& operator>>(std::basic_istream& is, E& value) +{ std::basic_string s; is >> s; - if (!is) return is; + if (!is) + return is; if constexpr (is_bitflag) { if (const auto v = enchantum::cast_bitflag(s)) value = *v; else is.setstate(std::ios_base::failbit); - } else { + } + else { if (const auto v = enchantum::cast(s)) value = *v; else @@ -30,4 +29,4 @@ std::basic_istream& operator>>( return is; } -} // namespace enchantum::istream_operators +} // namespace enchantum::istream_operators From a7f94d757fa0b93e484bb34b74d34ae92ee1fa62 Mon Sep 17 00:00:00 2001 From: "Dr. Patrick Urbanke" Date: Fri, 24 Oct 2025 23:51:30 +0200 Subject: [PATCH 07/10] Do not check thirdparty headers --- CMakeLists.txt | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fb3366f6..7aea8a0e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -423,22 +423,24 @@ if(REFLECTCPP_CHECK_HEADERS) file(MAKE_DIRECTORY "${TEST_DIR}") foreach(HEADER_FILE ${PROJECT_HEADERS}) - string(MAKE_C_IDENTIFIER ${HEADER_FILE} HEADER_NAME) - set(TEST_SOURCE_FILE "${TEST_DIR}/test_${HEADER_NAME}.cpp") - - file(GENERATE - OUTPUT ${TEST_SOURCE_FILE} - CONTENT "#include \"${HEADER_FILE}\"\n" - ) - - add_library(check_header_${HEADER_NAME} "${TEST_SOURCE_FILE}") - - target_include_directories(check_header_${HEADER_NAME} PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${ADDITIONAL_INCLUDE_DIRS} - ) - - add_custom_target(check_${HEADER_NAME} ALL DEPENDS check_header_${HEADER_NAME}) + if(NOT HEADER_FILE MATCHES "thirdparty") + string(MAKE_C_IDENTIFIER ${HEADER_FILE} HEADER_NAME) + set(TEST_SOURCE_FILE "${TEST_DIR}/test_${HEADER_NAME}.cpp") + + file(GENERATE + OUTPUT ${TEST_SOURCE_FILE} + CONTENT "#include \"${HEADER_FILE}\"\n" + ) + + add_library(check_header_${HEADER_NAME} "${TEST_SOURCE_FILE}") + + target_include_directories(check_header_${HEADER_NAME} PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${ADDITIONAL_INCLUDE_DIRS} + ) + + add_custom_target(check_${HEADER_NAME} ALL DEPENDS check_header_${HEADER_NAME}) + endif() endforeach() endif() From a94435fb32bb7209ca48879974ca02069c88c5eb Mon Sep 17 00:00:00 2001 From: "Dr. Patrick Urbanke" Date: Sat, 25 Oct 2025 01:01:19 +0200 Subject: [PATCH 08/10] Check headers on macOS and Windows --- .github/workflows/macos.yaml | 2 +- .github/workflows/windows.yaml | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/macos.yaml b/.github/workflows/macos.yaml index 28b398dd..14d17156 100644 --- a/.github/workflows/macos.yaml +++ b/.github/workflows/macos.yaml @@ -46,7 +46,7 @@ jobs: if [[ "${{ matrix.format }}" == "benchmarks" ]]; then cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=${{ matrix.cxx }} -DCMAKE_CXX_STANDARD=20 -DREFLECTCPP_BUILD_BENCHMARKS=ON -DREFLECTCPP_ALL_FORMATS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ else - cmake -S . -B build -DCMAKE_CXX_STANDARD=20 -DREFLECTCPP_BUILD_TESTS=ON -DREFLECTCPP_ALL_FORMATS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ + cmake -S . -B build -DCMAKE_CXX_STANDARD=20 -DREFLECTCPP_BUILD_TESTS=ON -DREFLECTCPP_ALL_FORMATS=ON -DREFLECTCPP_CHECK_HEADERS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ fi cmake --build build -j 4 - name: Run tests diff --git a/.github/workflows/windows.yaml b/.github/workflows/windows.yaml index b5056c26..859cbb2d 100644 --- a/.github/workflows/windows.yaml +++ b/.github/workflows/windows.yaml @@ -10,7 +10,7 @@ jobs: strategy: fail-fast: false matrix: - format: ["JSON", "AVRO", "CAPNPROTO", "CBOR", "FLEXBUFFERS", "MSGPACK", "PARQUET", "TOML", "UBJSON", "XML", "YAML", "benchmarks"] + format: ["JSON", "AVRO", "CAPNPROTO", "CBOR", "FLEXBUFFERS", "MSGPACK", "PARQUET", "TOML", "UBJSON", "XML", "YAML", "benchmarks", "headers"] name: "windows-msvc (${{ matrix.format }})" runs-on: windows-latest steps: @@ -32,17 +32,23 @@ jobs: run: | cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=${{ matrix.cxx }} -DCMAKE_CXX_STANDARD=20 -DREFLECTCPP_BUILD_BENCHMARKS=ON -DREFLECTCPP_ALL_FORMATS=ON -DCMAKE_BUILD_TYPE=Release cmake --build build --config Release -j4 + - name: Check headers + if: matrix.format == "headers" + run: | + cmake -S . -B build -DCMAKE_CXX_STANDARD=20 -DREFLECTCPP_CHECK_HEADERS=ON -DCMAKE_BUILD_TYPE=Release + cmake --build build --config Release -j4 - name: Compile tests (JSON) if: matrix.format == 'JSON' run: | cmake -S . -B build -DCMAKE_CXX_STANDARD=20 -DREFLECTCPP_BUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Release cmake --build build --config Release -j4 - name: Compile tests (Other formats) - if: matrix.format != 'JSON' && matrix.format != 'benchmarks' + if: matrix.format != 'JSON' && matrix.format != 'benchmarks' && matrix.format != "headers" run: | cmake -S . -B build -DCMAKE_CXX_STANDARD=20 -DREFLECTCPP_BUILD_TESTS=ON -DREFLECTCPP_JSON=OFF -DREFLECTCPP_${{ matrix.format }}=ON -DCMAKE_BUILD_TYPE=Release cmake --build build --config Release -j4 - name: Run tests + if: matrix.format != 'benchmarks' run: | ctest --test-dir build --output-on-failure - name: Run benchmarks @@ -99,4 +105,4 @@ jobs: run: | ctest --test-dir build --output-on-failure - \ No newline at end of file + From 2b7bcfc7680e3e126289e69a31de901fc287ab55 Mon Sep 17 00:00:00 2001 From: "Dr. Patrick Urbanke" Date: Sat, 25 Oct 2025 10:25:39 +0200 Subject: [PATCH 09/10] Fixed typo --- .github/workflows/windows.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/windows.yaml b/.github/workflows/windows.yaml index 859cbb2d..261fa2ad 100644 --- a/.github/workflows/windows.yaml +++ b/.github/workflows/windows.yaml @@ -33,7 +33,7 @@ jobs: cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=${{ matrix.cxx }} -DCMAKE_CXX_STANDARD=20 -DREFLECTCPP_BUILD_BENCHMARKS=ON -DREFLECTCPP_ALL_FORMATS=ON -DCMAKE_BUILD_TYPE=Release cmake --build build --config Release -j4 - name: Check headers - if: matrix.format == "headers" + if: matrix.format == 'headers' run: | cmake -S . -B build -DCMAKE_CXX_STANDARD=20 -DREFLECTCPP_CHECK_HEADERS=ON -DCMAKE_BUILD_TYPE=Release cmake --build build --config Release -j4 @@ -43,7 +43,7 @@ jobs: cmake -S . -B build -DCMAKE_CXX_STANDARD=20 -DREFLECTCPP_BUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Release cmake --build build --config Release -j4 - name: Compile tests (Other formats) - if: matrix.format != 'JSON' && matrix.format != 'benchmarks' && matrix.format != "headers" + if: matrix.format != 'JSON' && matrix.format != 'benchmarks' && matrix.format != 'headers' run: | cmake -S . -B build -DCMAKE_CXX_STANDARD=20 -DREFLECTCPP_BUILD_TESTS=ON -DREFLECTCPP_JSON=OFF -DREFLECTCPP_${{ matrix.format }}=ON -DCMAKE_BUILD_TYPE=Release cmake --build build --config Release -j4 From c6d2ba6345063518bd5d00659c31490fd3e4c372 Mon Sep 17 00:00:00 2001 From: "Dr. Patrick Urbanke" Date: Sat, 25 Oct 2025 11:35:46 +0200 Subject: [PATCH 10/10] Don't check headers on Windows --- .github/workflows/windows.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/windows.yaml b/.github/workflows/windows.yaml index 261fa2ad..be942f87 100644 --- a/.github/workflows/windows.yaml +++ b/.github/workflows/windows.yaml @@ -10,7 +10,7 @@ jobs: strategy: fail-fast: false matrix: - format: ["JSON", "AVRO", "CAPNPROTO", "CBOR", "FLEXBUFFERS", "MSGPACK", "PARQUET", "TOML", "UBJSON", "XML", "YAML", "benchmarks", "headers"] + format: ["JSON", "AVRO", "CAPNPROTO", "CBOR", "FLEXBUFFERS", "MSGPACK", "PARQUET", "TOML", "UBJSON", "XML", "YAML", "benchmarks"] name: "windows-msvc (${{ matrix.format }})" runs-on: windows-latest steps: