#include #include namespace larra::xmpp { struct SomeStruct { std::string field1; float field2 = 1.f; template auto Field1(this Self&& self, std::string field1) -> decltype(auto) { return utils::FieldSetHelper::With<0>(std::forward(self), std::move(field1)); } template auto Field2(this Self&& self, float field2) -> decltype(auto) { return utils::FieldSetHelper::With<"field2">(std::forward(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 auto Field1(this Self&& self, SomeStruct2 field1) -> decltype(auto) { return utils::FieldSetHelper::With<0>(std::forward(self), std::move(field1)); } template auto Field2(this Self&& self, SomeStruct2 field2) -> decltype(auto) { return utils::FieldSetHelper::With<"field2">(std::forward(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 auto Field1(this Self&& self, std::string field1) -> decltype(auto) { return kUtils.With<0>(std::forward(self), std::move(field1)); } template auto Field2(this Self&& self, float field2) -> decltype(auto) { return kUtils.With(&SomeStruct4::field2, std::forward(self), std::move(field2)); } }; struct SomeStruct5 { SomeStruct2 field1; SomeStruct2 field2; static constexpr auto kUtils = utils::CreateFieldsDescription(&SomeStruct5::field1, &SomeStruct5::field2); template auto Field1(this Self&& self, SomeStruct2 field1) -> decltype(auto) { return kUtils.With<0>(std::forward(self), std::move(field1)); } template auto Field2(this Self&& self, SomeStruct2 field2) -> decltype(auto) { return kUtils.With(&SomeStruct5::field2, std::forward(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({}); } } // namespace larra::xmpp