diff --git a/include/rfl/TaggedUnion.hpp b/include/rfl/TaggedUnion.hpp index 6e1331cd..1fea1be8 100644 --- a/include/rfl/TaggedUnion.hpp +++ b/include/rfl/TaggedUnion.hpp @@ -120,6 +120,27 @@ struct PossibleTags> { template using possible_tags_t = typename PossibleTags::Type; +template +bool operator==( + const TaggedUnion<_discriminator, Ts...>& lhs, + const TaggedUnion<_discriminator, Ts...>& rhs + ) { + + return (lhs.variant().index() == rhs.variant().index()) && + lhs.variant().visit( + [&rhs](const auto& l) { + return rhs.variant().visit( + [&l](const auto& r) -> bool { + if constexpr (std::is_same_v, std::decay_t>) + return l == r; + else + return false; + } + ); + } + ); +} + } // namespace rfl #endif // RFL_TAGGEDUNION_HPP_ diff --git a/tests/json/test_tagged_union5.cpp b/tests/json/test_tagged_union5.cpp new file mode 100644 index 00000000..5de2d0c9 --- /dev/null +++ b/tests/json/test_tagged_union5.cpp @@ -0,0 +1,67 @@ +#include +#include +#include +#include +#include +#include + +#include + +namespace test_tagged_union5 { + + template + concept OneOf = (std::is_same_v || ...); + + template + bool operator==(const T& lhs, const T& rhs) + requires OneOf + { + return rfl::to_named_tuple(lhs) == rfl::to_named_tuple(rhs); + } + + struct Sa { + int a; + std::string b; + }; + + struct Sb { + std::string b; + int i; + }; + + using Tu = rfl::TaggedUnion<"tu",Sa,Sb>; + + Tu v1 = Sa{.a = 1, .b = "b" }; + Tu v2 = Sa{.a = 1, .b = "b" }; + Tu v3 = Sa{.a = 1, .b = "bc" }; + Tu v4 = Sb{.b = "s", .i = -2}; + + TEST(json, test_tagged_union5) { + ASSERT_TRUE(v1 == v1); + ASSERT_TRUE(v1 == v2); + ASSERT_TRUE(v1 != v3); + ASSERT_TRUE(v1 != v4); + + ASSERT_TRUE(v2 == v2); + ASSERT_TRUE(v2 != v3); + ASSERT_TRUE(v2 != v4); + ASSERT_TRUE(v2 == v1); + + ASSERT_TRUE(v3 == v3); + ASSERT_TRUE(v3 != v4); + ASSERT_TRUE(v3 != v1); + ASSERT_TRUE(v3 != v2); + + ASSERT_TRUE(v4 == v4); + ASSERT_TRUE(v4 != v1); + ASSERT_TRUE(v4 != v2); + ASSERT_TRUE(v4 != v3); + + ASSERT_FALSE(v4 == v2); + // This is a compile-time test + EXPECT_TRUE(true); + } + +} // namespace test_tagged_union5