Skip to content

Commit c7226db

Browse files
authored
Merge pull request #14 from contour-terminal/features/CollectDifferences
Implement CollectDifferences
2 parents 74a6181 + 081ab6b commit c7226db

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

include/reflection-cpp/reflection.hpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,25 @@ std::string Inspect(std::vector<Object> const& objects)
813813
}
814814
return str;
815815
}
816+
817+
template <typename Object, typename Callback>
818+
void CollectDifferences(const Object& lhs, const Object& rhs, Callback&& callback)
819+
{
820+
template_for<0, CountMembers<Object>>([&]<auto I>() {
821+
if constexpr (std::equality_comparable<MemberTypeOf<I, Object>>)
822+
{
823+
if (GetMemberAt<I>(lhs) != GetMemberAt<I>(rhs))
824+
{
825+
callback(MemberNameOf<I, Object>, GetMemberAt<I>(lhs), GetMemberAt<I>(rhs));
826+
}
827+
}
828+
else
829+
{
830+
CollectDifferences(GetMemberAt<I>(lhs), GetMemberAt<I>(rhs), callback);
831+
}
832+
});
833+
}
834+
816835
} // namespace Reflection
817836

818837
template <std::size_t N>

test-reflection-cpp.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,3 +152,53 @@ TEST_CASE("MemberTypeOf", "[reflection]")
152152
static_assert(std::same_as<Reflection::MemberTypeOf<3, TestStruct>, std::string>);
153153
static_assert(std::same_as<Reflection::MemberTypeOf<4, TestStruct>, Person>);
154154
}
155+
156+
struct Record
157+
{
158+
int id;
159+
std::string name;
160+
int age;
161+
};
162+
163+
TEST_CASE("Compare.simple", "[reflection]")
164+
{
165+
auto const r1 = Record { .id = 1, .name = "John Doe", .age = 42 };
166+
auto const r2 = Record { .id = 1, .name = "John Doe", .age = 42 };
167+
auto const r3 = Record { .id = 2, .name = "Jane Doe", .age = 43 };
168+
169+
std::string diff;
170+
auto differenceCallback = [&](std::string_view name, auto const& lhs, auto const& rhs) {
171+
diff += std::format("{}: {} != {}\n", name, lhs, rhs);
172+
};
173+
174+
Reflection::CollectDifferences(r1, r2, differenceCallback);
175+
CHECK(diff.empty());
176+
Reflection::CollectDifferences(r1, r3, differenceCallback);
177+
CHECK(diff == "id: 1 != 2\nname: John Doe != Jane Doe\nage: 42 != 43\n");
178+
}
179+
180+
struct Table
181+
{
182+
Record first;
183+
Record second;
184+
};
185+
186+
TEST_CASE("Compare.nested", "[reflection]")
187+
{
188+
auto const t1 = Table { .first = { .id = 1, .name = "John Doe", .age = 42 },
189+
.second = { .id = 2, .name = "Jane Doe", .age = 43 } };
190+
auto const t2 = Table { .first = { .id = 1, .name = "John Doe", .age = 42 },
191+
.second = { .id = 2, .name = "Jane Doe", .age = 43 } };
192+
auto const t3 = Table { .first = { .id = 1, .name = "John Doe", .age = 42 },
193+
.second = { .id = 3, .name = "Jane Doe", .age = 43 } };
194+
195+
std::string diff;
196+
auto differenceCallback = [&](std::string_view name, auto const& lhs, auto const& rhs) {
197+
diff += std::format("{}: {} != {}\n", name, lhs, rhs);
198+
};
199+
200+
Reflection::CollectDifferences(t1, t2, differenceCallback);
201+
CHECK(diff.empty());
202+
Reflection::CollectDifferences(t1, t3, differenceCallback);
203+
CHECK(diff == "id: 2 != 3\n");
204+
}

0 commit comments

Comments
 (0)