125 lines
3.9 KiB
C++
125 lines
3.9 KiB
C++
#include <gtest/gtest.h>
|
|
|
|
#include <larra/utils.hpp>
|
|
|
|
namespace larra::xmpp {
|
|
|
|
struct SomeStruct {
|
|
std::string field1;
|
|
float field2 = 1.f;
|
|
template <typename Self>
|
|
auto Field1(this Self&& self, std::string field1) -> decltype(auto) {
|
|
return utils::FieldSetHelper::With<0>(std::forward<Self>(self), std::move(field1));
|
|
}
|
|
template <typename Self>
|
|
auto Field2(this Self&& self, float field2) -> decltype(auto) {
|
|
return utils::FieldSetHelper::With<"field2">(std::forward<Self>(self), std::move(field2));
|
|
}
|
|
};
|
|
|
|
TEST(Set, Basic) {
|
|
auto obj = SomeStruct{}.Field1("Hello").Field2(.0f);
|
|
EXPECT_EQ(obj.field1, "Hello");
|
|
EXPECT_EQ(obj.field2, .0f);
|
|
}
|
|
|
|
struct SomeStruct2 {
|
|
SomeStruct2(const SomeStruct2&) = delete;
|
|
SomeStruct2() = default;
|
|
SomeStruct2(SomeStruct2&&) = default;
|
|
};
|
|
|
|
struct SomeStruct3 {
|
|
SomeStruct2 field1;
|
|
SomeStruct2 field2;
|
|
template <typename Self>
|
|
auto Field1(this Self&& self, SomeStruct2 field1) -> decltype(auto) {
|
|
return utils::FieldSetHelper::With<0>(std::forward<Self>(self), std::move(field1));
|
|
}
|
|
template <typename Self>
|
|
auto Field2(this Self&& self, SomeStruct2 field2) -> decltype(auto) {
|
|
return utils::FieldSetHelper::With<"field2">(std::forward<Self>(self), std::move(field2));
|
|
}
|
|
};
|
|
|
|
TEST(Set, NonCopyable) {
|
|
auto obj = SomeStruct3{}.Field1({}).Field2({});
|
|
}
|
|
|
|
struct SomeStruct4 {
|
|
std::string field1;
|
|
float field2 = 1.f;
|
|
static constexpr auto kUtils = utils::CreateFieldsDescription(&SomeStruct4::field1, &SomeStruct4::field2);
|
|
template <typename Self>
|
|
auto Field1(this Self&& self, std::string field1) -> decltype(auto) {
|
|
return kUtils.With<0>(std::forward<Self>(self), std::move(field1));
|
|
}
|
|
template <typename Self>
|
|
auto Field2(this Self&& self, float field2) -> decltype(auto) {
|
|
return kUtils.With(&SomeStruct4::field2, std::forward<Self>(self), std::move(field2));
|
|
}
|
|
};
|
|
|
|
struct SomeStruct5 {
|
|
SomeStruct2 field1;
|
|
SomeStruct2 field2;
|
|
static constexpr auto kUtils = utils::CreateFieldsDescription(&SomeStruct5::field1, &SomeStruct5::field2);
|
|
template <typename Self>
|
|
auto Field1(this Self&& self, SomeStruct2 field1) -> decltype(auto) {
|
|
return kUtils.With<0>(std::forward<Self>(self), std::move(field1));
|
|
}
|
|
template <typename Self>
|
|
auto Field2(this Self&& self, SomeStruct2 field2) -> decltype(auto) {
|
|
return kUtils.With(&SomeStruct5::field2, std::forward<Self>(self), std::move(field2));
|
|
}
|
|
};
|
|
|
|
TEST(NonPfrSet, Basic) {
|
|
auto obj = SomeStruct4{}.Field1("Hello").Field2(.0f);
|
|
EXPECT_EQ(obj.field1, "Hello");
|
|
EXPECT_EQ(obj.field2, .0f);
|
|
}
|
|
|
|
TEST(NonPfrSet, NonCopyable) {
|
|
auto obj = SomeStruct5{}.Field1({}).Field2({});
|
|
}
|
|
|
|
struct SomeStruct6 {
|
|
std::string field1;
|
|
std::string field2;
|
|
template <typename Self>
|
|
auto Field1(this Self&& self, std::string field1) -> std::decay_t<Self> {
|
|
return utils::FieldSetHelper::With<"field1", SomeStruct6>(std::forward<Self>(self), std::move(field1));
|
|
}
|
|
template <typename Self>
|
|
auto Field2(this Self&& self, std::string field2) -> std::decay_t<Self> {
|
|
return utils::FieldSetHelper::With<"field2", SomeStruct6>(std::forward<Self>(self), std::move(field2));
|
|
}
|
|
};
|
|
|
|
struct SomeStruct7 : SomeStruct6 {
|
|
explicit SomeStruct7(SomeStruct6&& obj) : SomeStruct6(std::move(obj)) {};
|
|
using SomeStruct6::SomeStruct6;
|
|
};
|
|
|
|
TEST(Set, Inheritance) {
|
|
const SomeStruct7 obj = SomeStruct7{}.Field1("Hello").Field2("World");
|
|
ASSERT_EQ(obj.field1, "Hello");
|
|
ASSERT_EQ(obj.field2, "World");
|
|
}
|
|
|
|
template <typename T>
|
|
struct SomeStruct8 {
|
|
T value;
|
|
template <typename TT, typename Self>
|
|
constexpr auto Value(this Self&& self, TT value) {
|
|
return utils::FieldSetHelper::With<0, SomeStruct8<TT>, false>(std::forward<Self>(self), std::move(value));
|
|
}
|
|
};
|
|
|
|
TEST(Set, OtherType) {
|
|
constexpr auto value = SomeStruct8{.value = 42}.Value<std::string_view>("Hello World");
|
|
EXPECT_EQ(value.value, std::string_view{"Hello World"});
|
|
}
|
|
|
|
} // namespace larra::xmpp
|