156 lines
4.5 KiB
C++
156 lines
4.5 KiB
C++
#include "Test/Test.h"
|
|
#include "Support/Struct.h"
|
|
|
|
namespace clice::testing {
|
|
|
|
namespace {
|
|
|
|
struct X {
|
|
int x;
|
|
int y;
|
|
|
|
friend constexpr bool operator== (const X& lhs, const X& rhs) noexcept = default;
|
|
};
|
|
|
|
static_assert(std::is_same_v<refl::member_types<X>, type_list<int, int>>);
|
|
|
|
suite<"Struct"> struct_tests = [] {
|
|
test("FieldName") = [&] {
|
|
static struct X {
|
|
int a;
|
|
int b;
|
|
} x;
|
|
|
|
static_assert(refl::impl::member_name<&x.a>() == "a", "Member name mismatch");
|
|
static_assert(refl::impl::member_name<&x.b>() == "b", "Member name mismatch");
|
|
static_assert(refl::member_names<X>() == std::array<std::string_view, 2>{"a", "b"});
|
|
|
|
static struct Y {
|
|
X x;
|
|
} y;
|
|
|
|
static_assert(refl::impl::member_name<&y.x>() == "x", "Member name mismatch");
|
|
static_assert(refl::impl::member_name<&y.x.a>() == "a", "Member name mismatch");
|
|
static_assert(refl::impl::member_name<&y.x.b>() == "b", "Member name mismatch");
|
|
static_assert(refl::member_names<Y>() == std::array<std::string_view, 1>{"x"});
|
|
|
|
struct H {
|
|
X x;
|
|
Y y;
|
|
H() = delete;
|
|
};
|
|
|
|
static union Z {
|
|
char dummy;
|
|
H h;
|
|
|
|
Z() {};
|
|
~Z() {};
|
|
} z;
|
|
|
|
static_assert(refl::impl::member_name<&z.h.x>() == "x", "Member name mismatch");
|
|
static_assert(refl::impl::member_name<&z.h.y>() == "y", "Member name mismatch");
|
|
static_assert(refl::impl::member_name<&z.h.y.x>() == "x", "Member name mismatch");
|
|
|
|
struct M {
|
|
X x;
|
|
Y y;
|
|
H h;
|
|
};
|
|
|
|
static_assert(refl::member_names<M>() == std::array<std::string_view, 3>{"x", "y", "h"});
|
|
};
|
|
|
|
test("Foreach") = [&] {
|
|
bool x = false, y = false;
|
|
refl::foreach(X{1, 2}, [&](auto name, auto value) {
|
|
if(name == "x") {
|
|
x = true;
|
|
expect(that % value == 1);
|
|
} else if(name == "y") {
|
|
y = true;
|
|
expect(that % value == 2);
|
|
} else {
|
|
expect(false);
|
|
}
|
|
});
|
|
expect(that % x && y);
|
|
|
|
X x1 = {1, 2};
|
|
X x2 = {3, 4};
|
|
expect(that % refl::foreach(x1, x2, [](auto& lhs, auto& rhs) { return lhs = rhs; }));
|
|
expect(that % x1.x == 3);
|
|
expect(that % x1.y == 4);
|
|
};
|
|
|
|
test("Inheritance") = [&] {
|
|
inherited_struct(Y, X) {
|
|
int z;
|
|
};
|
|
|
|
static_assert(std::is_same_v<refl::member_types<Y>, type_list<int, int, int>>);
|
|
|
|
bool x = false, y = false, z = false;
|
|
refl::foreach(Y{1, 2, 3}, [&](auto name, auto value) {
|
|
if(name == "x") {
|
|
x = true;
|
|
expect(that % value == 1);
|
|
} else if(name == "y") {
|
|
y = true;
|
|
expect(that % value == 2);
|
|
} else if(name == "z") {
|
|
z = true;
|
|
expect(that % value == 3);
|
|
} else {
|
|
expect(false);
|
|
}
|
|
});
|
|
expect(that % x && y && z);
|
|
|
|
Y y1 = {1, 2, 3};
|
|
Y y2 = {4, 5, 6};
|
|
expect(that % refl::foreach(y1, y2, [](auto& lhs, auto& rhs) { return lhs = rhs; }));
|
|
expect(that % y1.x == 4);
|
|
expect(that % y1.y == 5);
|
|
expect(that % y1.z == 6);
|
|
};
|
|
|
|
test("TupleLike") = [&] {
|
|
std::pair<int, int> p = {1, 2};
|
|
|
|
static_assert(refl::member_names<decltype(p)>() ==
|
|
std::array<std::string_view, 2>{"0", "1"});
|
|
|
|
std::tuple<int, int> t = {1, 2};
|
|
|
|
static_assert(refl::member_names<decltype(t)>() ==
|
|
std::array<std::string_view, 2>{"0", "1"});
|
|
|
|
bool x = false, y = false;
|
|
refl::foreach(t, [&](auto name, auto value) {
|
|
if(name == "0") {
|
|
x = true;
|
|
expect(that % value == 1);
|
|
} else if(name == "1") {
|
|
y = true;
|
|
expect(that % value == 2);
|
|
} else {
|
|
expect(false);
|
|
}
|
|
});
|
|
expect(that % x && y);
|
|
|
|
std::tuple<int, int> t1 = {1, 2};
|
|
std::tuple<int, int> t2 = {3, 4};
|
|
|
|
expect(that % refl::foreach(t1, t2, [](auto& lhs, auto& rhs) { return lhs = rhs; }));
|
|
expect(that % std::get<0>(t1) == 3);
|
|
expect(that % std::get<1>(t1) == 4);
|
|
expect(that % std::get<0>(t2) == 3);
|
|
};
|
|
};
|
|
|
|
} // namespace
|
|
|
|
} // namespace clice::testing
|