Skip to content

Commit

Permalink
Added experimental compile-time flag REFLECT_CPP_NO_C_ARRAYS_OR_INHER…
Browse files Browse the repository at this point in the history
…ITANCE
  • Loading branch information
Patrick Urbanke committed Apr 26, 2024
1 parent 325d163 commit a67b4ac
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 26 deletions.
39 changes: 21 additions & 18 deletions include/rfl/internal/num_fields.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,23 +53,22 @@ template <class Derived>
struct any_empty_base {
any_empty_base(std::size_t);
template <class Base>
requires(
std::is_empty_v<std::remove_cvref_t<Base>> &&
std::is_base_of_v<std::remove_cvref_t<Base>,
std::remove_cv_t<Derived>> &&
!std::is_same_v<std::remove_cvref_t<Base>, std::remove_cv_t<Derived>>)
constexpr operator Base&() const noexcept;
requires(std::is_empty_v<std::remove_cvref_t<Base>>&& std::is_base_of_v<
std::remove_cvref_t<Base>, std::remove_cv_t<Derived>> &&
!std::is_same_v<std::remove_cvref_t<Base>,
std::remove_cv_t<Derived>>) constexpr
operator Base&() const noexcept;
};

template <class Derived>
struct any_base {
any_base(std::size_t);
template <class Base>
requires(
std::is_base_of_v<std::remove_cvref_t<Base>,
std::remove_cv_t<Derived>> &&
!std::is_same_v<std::remove_cvref_t<Base>, std::remove_cv_t<Derived>>)
constexpr operator Base&() const noexcept;
requires(
std::is_base_of_v<std::remove_cvref_t<Base>, std::remove_cv_t<Derived>> &&
!std::is_same_v<std::remove_cvref_t<Base>,
std::remove_cv_t<Derived>>) constexpr
operator Base&() const noexcept;
};

struct any {
Expand Down Expand Up @@ -100,12 +99,12 @@ struct CountFieldsHelper {
}

template <std::size_t n = 0>
static consteval std::size_t count_max_args_in_agg_init() {
static consteval std::size_t count_max_args_in_agg() {
static_assert(n <= static_cast<std::size_t>(sizeof(T)));
if constexpr (constructible<n>() && !constructible<n + 1>()) {
return n;
} else {
return count_max_args_in_agg_init<n + 1>();
return count_max_args_in_agg<n + 1>();
}
}

Expand All @@ -125,8 +124,7 @@ struct CountFieldsHelper {
static consteval std::size_t find_the_sole_non_empty_base_index() {
static_assert(index < max_args);
constexpr auto check = []<std::size_t... l, std::size_t... r>(
std::index_sequence<l...>,
std::index_sequence<r...>) {
std::index_sequence<l...>, std::index_sequence<r...>) {
return requires {
T{any_empty_base<T>(l)..., any_base<T>(0), any_empty_base<T>(r)...};
};
Expand All @@ -153,11 +151,12 @@ struct CountFieldsHelper {

template <std::size_t n, std::size_t max_arg_num>
static consteval bool has_n_base_param() {
constexpr auto right_len = max_arg_num>=n ? max_arg_num-n : 0;
constexpr auto right_len = max_arg_num >= n ? max_arg_num - n : 0;
return []<std::size_t... l, std::size_t... r>(std::index_sequence<l...>,
std::index_sequence<r...>) {
return requires { T{any_base<T>(l)..., any(r)...}; };
}(std::make_index_sequence<n>(), std::make_index_sequence<right_len>());
}
(std::make_index_sequence<n>(), std::make_index_sequence<right_len>());
}

template <std::size_t max_arg_num, std::size_t index = 0>
Expand All @@ -182,7 +181,8 @@ struct CountFieldsHelper {
}

static consteval std::size_t count_fields() {
constexpr std::size_t max_agg_args = count_max_args_in_agg_init();
constexpr std::size_t max_agg_args = count_max_args_in_agg();
#ifndef REFLECT_CPP_NO_C_ARRAYS_OR_INHERITANCE
constexpr std::size_t no_brace_ellison_args =
constructible_no_brace_elision<0, max_agg_args>();
constexpr std::size_t base_args = base_param_num<no_brace_ellison_args>();
Expand All @@ -198,6 +198,9 @@ struct CountFieldsHelper {
} else {
return no_brace_ellison_args - base_args;
}
#else
return max_agg_args;
#endif
}
};

Expand Down
2 changes: 2 additions & 0 deletions tests/json/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ add_executable(
"${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/src/gtest_main.cc"
)

# SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DREFLECT_CPP_NO_C_ARRAYS_OR_INHERITANCE")

target_include_directories(reflect-cpp-json-tests SYSTEM PRIVATE "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include")

target_link_libraries(
Expand Down
5 changes: 4 additions & 1 deletion tests/json/test_c_array_class1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@ struct Test1 {
std::vector<std::string> classes[3];
};

TEST(json, test_c_array_class1) {
TEST(json, test_inheritance2) {
#ifndef REFLECT_CPP_NO_C_ARRAYS_OR_INHERITANCE
Test1 test1 = {.classes = {{"Little A", "Little B", "Little C"},
{"BIG A", "BIG B", "BIG C"},
{"??", "$%", "#@"}}};
write_and_read(
test1,
R"({"classes":[["Little A","Little B","Little C"],["BIG A","BIG B","BIG C"],["??","$%","#@"]]})");

#endif
}

} // namespace test_c_array_class1
2 changes: 2 additions & 0 deletions tests/json/test_c_array_class2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ struct Test2 {
};

TEST(json, test_c_array_class2) {
#ifndef REFLECT_CPP_NO_C_ARRAYS_OR_INHERITANCE
Test2 test2;
for (int i = 0; i < 1 << 4; i++) {
test2.multi_dimension_arr[i >> 3 & 1][i >> 2 & 1][i >> 1 & 1][i >> 0 & 1] =
Expand All @@ -24,6 +25,7 @@ TEST(json, test_c_array_class2) {
write_and_read(
test2,
R"({"multi_dimension_arr":[[[[0,1],[2,3]],[[4,5],[6,7]]],[[[8,9],[10,11]],[[12,13],[14,15]]]],"s":"Hello, world!"})");
#endif
}

} // namespace test_c_array_class2
2 changes: 2 additions & 0 deletions tests/json/test_c_array_class3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ namespace test_c_array_class3 {
using Test3 = std::array<int, 3>[3];

TEST(json, test_c_array_class3) {
#ifndef REFLECT_CPP_NO_C_ARRAYS_OR_INHERITANCE
Test3 test3 = {1, 2, 3, 4, 5, 6, 7, 8, 9};
write_and_read(test3, "[[1,2,3],[4,5,6],[7,8,9]]");
#endif
}

} // namespace test_c_array_class3
3 changes: 2 additions & 1 deletion tests/json/test_c_array_class4.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ struct Test4 {
};

TEST(json, test_c_array_class4) {
#ifndef REFLECT_CPP_NO_C_ARRAYS_OR_INHERITANCE
Test4 test4 = {.a = {1, 2, 3}, .b = {4, 5, 6}, .c = {{7, 8}, {9, 10}}};

write_and_read(test4, R"({"a":[1,2,3],"b":[4,5,6],"c":[[7,8],[9,10]]})");
#endif
}

} // namespace test_c_array_class4
4 changes: 2 additions & 2 deletions tests/json/test_c_array_class5.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ struct Test5 {
};

TEST(json, test_c_array_class5) {
#ifndef REFLECT_CPP_NO_C_ARRAYS_OR_INHERITANCE
Test5 t1 = {.a = {1, 2, 3}, .b = {4, 5, 6}, .c = {{7, 8}, {9, 10}}};

const auto t2 = rfl::replace(t1, rfl::make_field<"b", int[3]>({1, 2, 3}));

write_and_read(t2, R"({"a":[1,2,3],"b":[1,2,3],"c":[[7,8],[9,10]]})");
#endif
}

} // namespace test_c_array_class5
6 changes: 4 additions & 2 deletions tests/json/test_inheritance.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
#include <gtest/gtest.h>

#include <cassert>
#include <iostream>
#include <rfl.hpp>
#include <source_location>
#include <tuple>

#include <gtest/gtest.h>

namespace test_inheritance {

TEST(json, test_inheritance) {
#ifndef REFLECT_CPP_NO_C_ARRAYS_OR_INHERITANCE
struct S {
int x;
};
Expand All @@ -21,6 +22,7 @@ TEST(json, test_inheritance) {
static_assert(name == "x");

EXPECT_TRUE(true);
#endif
}

} // namespace test_inheritance
6 changes: 4 additions & 2 deletions tests/json/test_inheritance2.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#include <gtest/gtest.h>

#include <cassert>
#include <iostream>
#include <rfl.hpp>
#include <source_location>

#include "rfl/internal/num_fields.hpp"

#include <gtest/gtest.h>

namespace test_inheritance2 {

struct EmptyBase1 {};
Expand All @@ -30,6 +30,7 @@ struct EmptyDerived1 : EmptyBase1, BaseX {};
struct EmptyDerived2 : EmptyBase1, EmptyBase2, BaseX {};

TEST(json, test_inheritance2) {
#ifndef REFLECT_CPP_NO_C_ARRAYS_OR_INHERITANCE
Derived1 derived1;
const auto derived1_view = rfl::to_view(derived1);
static_assert(derived1_view.size() == 2);
Expand All @@ -51,6 +52,7 @@ TEST(json, test_inheritance2) {
static_assert(empty_derived0_view.size() == 2);

EXPECT_TRUE(true);
#endif
}

} // namespace test_inheritance2

0 comments on commit a67b4ac

Please sign in to comment.