mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-25 05:38:39 +00:00
[C++] Vector of Tables equality (#7415)
* Vector of Tables equality * support nullptr and fix for not being able to use auto in lambda * use different std::equal overload * use flatbuffers::unique_ptr * go back to auto and clang-format fix
This commit is contained in:
@@ -2727,7 +2727,7 @@ inline bool operator==(const MonsterT &lhs, const MonsterT &rhs) {
|
||||
(lhs.test == rhs.test) &&
|
||||
(lhs.test4 == rhs.test4) &&
|
||||
(lhs.testarrayofstring == rhs.testarrayofstring) &&
|
||||
(lhs.testarrayoftables == rhs.testarrayoftables) &&
|
||||
(lhs.testarrayoftables.size() == rhs.testarrayoftables.size() && std::equal(lhs.testarrayoftables.cbegin(), lhs.testarrayoftables.cend(), rhs.testarrayoftables.cbegin(), [](flatbuffers::unique_ptr<MyGame::Example::MonsterT> const &a, flatbuffers::unique_ptr<MyGame::Example::MonsterT> const &b) { return (a == b) || (a && b && *a == *b); })) &&
|
||||
((lhs.enemy == rhs.enemy) || (lhs.enemy && rhs.enemy && *lhs.enemy == *rhs.enemy)) &&
|
||||
(lhs.testnestedflatbuffer == rhs.testnestedflatbuffer) &&
|
||||
((lhs.testempty == rhs.testempty) || (lhs.testempty && rhs.testempty && *lhs.testempty == *rhs.testempty)) &&
|
||||
@@ -2751,10 +2751,10 @@ inline bool operator==(const MonsterT &lhs, const MonsterT &rhs) {
|
||||
(lhs.vector_of_longs == rhs.vector_of_longs) &&
|
||||
(lhs.vector_of_doubles == rhs.vector_of_doubles) &&
|
||||
((lhs.parent_namespace_test == rhs.parent_namespace_test) || (lhs.parent_namespace_test && rhs.parent_namespace_test && *lhs.parent_namespace_test == *rhs.parent_namespace_test)) &&
|
||||
(lhs.vector_of_referrables == rhs.vector_of_referrables) &&
|
||||
(lhs.vector_of_referrables.size() == rhs.vector_of_referrables.size() && std::equal(lhs.vector_of_referrables.cbegin(), lhs.vector_of_referrables.cend(), rhs.vector_of_referrables.cbegin(), [](flatbuffers::unique_ptr<MyGame::Example::ReferrableT> const &a, flatbuffers::unique_ptr<MyGame::Example::ReferrableT> const &b) { return (a == b) || (a && b && *a == *b); })) &&
|
||||
(lhs.single_weak_reference == rhs.single_weak_reference) &&
|
||||
(lhs.vector_of_weak_references == rhs.vector_of_weak_references) &&
|
||||
(lhs.vector_of_strong_referrables == rhs.vector_of_strong_referrables) &&
|
||||
(lhs.vector_of_strong_referrables.size() == rhs.vector_of_strong_referrables.size() && std::equal(lhs.vector_of_strong_referrables.cbegin(), lhs.vector_of_strong_referrables.cend(), rhs.vector_of_strong_referrables.cbegin(), [](flatbuffers::unique_ptr<MyGame::Example::ReferrableT> const &a, flatbuffers::unique_ptr<MyGame::Example::ReferrableT> const &b) { return (a == b) || (a && b && *a == *b); })) &&
|
||||
(lhs.co_owning_reference == rhs.co_owning_reference) &&
|
||||
(lhs.vector_of_co_owning_references == rhs.vector_of_co_owning_references) &&
|
||||
(lhs.non_owning_reference == rhs.non_owning_reference) &&
|
||||
@@ -2764,7 +2764,7 @@ inline bool operator==(const MonsterT &lhs, const MonsterT &rhs) {
|
||||
(lhs.vector_of_enums == rhs.vector_of_enums) &&
|
||||
(lhs.signed_enum == rhs.signed_enum) &&
|
||||
(lhs.testrequirednestedflatbuffer == rhs.testrequirednestedflatbuffer) &&
|
||||
(lhs.scalar_key_sorted_tables == rhs.scalar_key_sorted_tables) &&
|
||||
(lhs.scalar_key_sorted_tables.size() == rhs.scalar_key_sorted_tables.size() && std::equal(lhs.scalar_key_sorted_tables.cbegin(), lhs.scalar_key_sorted_tables.cend(), rhs.scalar_key_sorted_tables.cbegin(), [](flatbuffers::unique_ptr<MyGame::Example::StatT> const &a, flatbuffers::unique_ptr<MyGame::Example::StatT> const &b) { return (a == b) || (a && b && *a == *b); })) &&
|
||||
(lhs.native_inline == rhs.native_inline) &&
|
||||
(lhs.long_enum_non_enum_default == rhs.long_enum_non_enum_default) &&
|
||||
(lhs.long_enum_normal_default == rhs.long_enum_normal_default);
|
||||
|
||||
@@ -2727,7 +2727,7 @@ inline bool operator==(const MonsterT &lhs, const MonsterT &rhs) {
|
||||
(lhs.test == rhs.test) &&
|
||||
(lhs.test4 == rhs.test4) &&
|
||||
(lhs.testarrayofstring == rhs.testarrayofstring) &&
|
||||
(lhs.testarrayoftables == rhs.testarrayoftables) &&
|
||||
(lhs.testarrayoftables.size() == rhs.testarrayoftables.size() && std::equal(lhs.testarrayoftables.cbegin(), lhs.testarrayoftables.cend(), rhs.testarrayoftables.cbegin(), [](flatbuffers::unique_ptr<MyGame::Example::MonsterT> const &a, flatbuffers::unique_ptr<MyGame::Example::MonsterT> const &b) { return (a == b) || (a && b && *a == *b); })) &&
|
||||
((lhs.enemy == rhs.enemy) || (lhs.enemy && rhs.enemy && *lhs.enemy == *rhs.enemy)) &&
|
||||
(lhs.testnestedflatbuffer == rhs.testnestedflatbuffer) &&
|
||||
((lhs.testempty == rhs.testempty) || (lhs.testempty && rhs.testempty && *lhs.testempty == *rhs.testempty)) &&
|
||||
@@ -2751,10 +2751,10 @@ inline bool operator==(const MonsterT &lhs, const MonsterT &rhs) {
|
||||
(lhs.vector_of_longs == rhs.vector_of_longs) &&
|
||||
(lhs.vector_of_doubles == rhs.vector_of_doubles) &&
|
||||
((lhs.parent_namespace_test == rhs.parent_namespace_test) || (lhs.parent_namespace_test && rhs.parent_namespace_test && *lhs.parent_namespace_test == *rhs.parent_namespace_test)) &&
|
||||
(lhs.vector_of_referrables == rhs.vector_of_referrables) &&
|
||||
(lhs.vector_of_referrables.size() == rhs.vector_of_referrables.size() && std::equal(lhs.vector_of_referrables.cbegin(), lhs.vector_of_referrables.cend(), rhs.vector_of_referrables.cbegin(), [](flatbuffers::unique_ptr<MyGame::Example::ReferrableT> const &a, flatbuffers::unique_ptr<MyGame::Example::ReferrableT> const &b) { return (a == b) || (a && b && *a == *b); })) &&
|
||||
(lhs.single_weak_reference == rhs.single_weak_reference) &&
|
||||
(lhs.vector_of_weak_references == rhs.vector_of_weak_references) &&
|
||||
(lhs.vector_of_strong_referrables == rhs.vector_of_strong_referrables) &&
|
||||
(lhs.vector_of_strong_referrables.size() == rhs.vector_of_strong_referrables.size() && std::equal(lhs.vector_of_strong_referrables.cbegin(), lhs.vector_of_strong_referrables.cend(), rhs.vector_of_strong_referrables.cbegin(), [](flatbuffers::unique_ptr<MyGame::Example::ReferrableT> const &a, flatbuffers::unique_ptr<MyGame::Example::ReferrableT> const &b) { return (a == b) || (a && b && *a == *b); })) &&
|
||||
(lhs.co_owning_reference == rhs.co_owning_reference) &&
|
||||
(lhs.vector_of_co_owning_references == rhs.vector_of_co_owning_references) &&
|
||||
(lhs.non_owning_reference == rhs.non_owning_reference) &&
|
||||
@@ -2764,7 +2764,7 @@ inline bool operator==(const MonsterT &lhs, const MonsterT &rhs) {
|
||||
(lhs.vector_of_enums == rhs.vector_of_enums) &&
|
||||
(lhs.signed_enum == rhs.signed_enum) &&
|
||||
(lhs.testrequirednestedflatbuffer == rhs.testrequirednestedflatbuffer) &&
|
||||
(lhs.scalar_key_sorted_tables == rhs.scalar_key_sorted_tables) &&
|
||||
(lhs.scalar_key_sorted_tables.size() == rhs.scalar_key_sorted_tables.size() && std::equal(lhs.scalar_key_sorted_tables.cbegin(), lhs.scalar_key_sorted_tables.cend(), rhs.scalar_key_sorted_tables.cbegin(), [](flatbuffers::unique_ptr<MyGame::Example::StatT> const &a, flatbuffers::unique_ptr<MyGame::Example::StatT> const &b) { return (a == b) || (a && b && *a == *b); })) &&
|
||||
(lhs.native_inline == rhs.native_inline) &&
|
||||
(lhs.long_enum_non_enum_default == rhs.long_enum_non_enum_default) &&
|
||||
(lhs.long_enum_normal_default == rhs.long_enum_normal_default);
|
||||
|
||||
@@ -2727,7 +2727,7 @@ inline bool operator==(const MonsterT &lhs, const MonsterT &rhs) {
|
||||
(lhs.test == rhs.test) &&
|
||||
(lhs.test4 == rhs.test4) &&
|
||||
(lhs.testarrayofstring == rhs.testarrayofstring) &&
|
||||
(lhs.testarrayoftables == rhs.testarrayoftables) &&
|
||||
(lhs.testarrayoftables.size() == rhs.testarrayoftables.size() && std::equal(lhs.testarrayoftables.cbegin(), lhs.testarrayoftables.cend(), rhs.testarrayoftables.cbegin(), [](flatbuffers::unique_ptr<MyGame::Example::MonsterT> const &a, flatbuffers::unique_ptr<MyGame::Example::MonsterT> const &b) { return (a == b) || (a && b && *a == *b); })) &&
|
||||
((lhs.enemy == rhs.enemy) || (lhs.enemy && rhs.enemy && *lhs.enemy == *rhs.enemy)) &&
|
||||
(lhs.testnestedflatbuffer == rhs.testnestedflatbuffer) &&
|
||||
((lhs.testempty == rhs.testempty) || (lhs.testempty && rhs.testempty && *lhs.testempty == *rhs.testempty)) &&
|
||||
@@ -2751,10 +2751,10 @@ inline bool operator==(const MonsterT &lhs, const MonsterT &rhs) {
|
||||
(lhs.vector_of_longs == rhs.vector_of_longs) &&
|
||||
(lhs.vector_of_doubles == rhs.vector_of_doubles) &&
|
||||
((lhs.parent_namespace_test == rhs.parent_namespace_test) || (lhs.parent_namespace_test && rhs.parent_namespace_test && *lhs.parent_namespace_test == *rhs.parent_namespace_test)) &&
|
||||
(lhs.vector_of_referrables == rhs.vector_of_referrables) &&
|
||||
(lhs.vector_of_referrables.size() == rhs.vector_of_referrables.size() && std::equal(lhs.vector_of_referrables.cbegin(), lhs.vector_of_referrables.cend(), rhs.vector_of_referrables.cbegin(), [](flatbuffers::unique_ptr<MyGame::Example::ReferrableT> const &a, flatbuffers::unique_ptr<MyGame::Example::ReferrableT> const &b) { return (a == b) || (a && b && *a == *b); })) &&
|
||||
(lhs.single_weak_reference == rhs.single_weak_reference) &&
|
||||
(lhs.vector_of_weak_references == rhs.vector_of_weak_references) &&
|
||||
(lhs.vector_of_strong_referrables == rhs.vector_of_strong_referrables) &&
|
||||
(lhs.vector_of_strong_referrables.size() == rhs.vector_of_strong_referrables.size() && std::equal(lhs.vector_of_strong_referrables.cbegin(), lhs.vector_of_strong_referrables.cend(), rhs.vector_of_strong_referrables.cbegin(), [](flatbuffers::unique_ptr<MyGame::Example::ReferrableT> const &a, flatbuffers::unique_ptr<MyGame::Example::ReferrableT> const &b) { return (a == b) || (a && b && *a == *b); })) &&
|
||||
(lhs.co_owning_reference == rhs.co_owning_reference) &&
|
||||
(lhs.vector_of_co_owning_references == rhs.vector_of_co_owning_references) &&
|
||||
(lhs.non_owning_reference == rhs.non_owning_reference) &&
|
||||
@@ -2764,7 +2764,7 @@ inline bool operator==(const MonsterT &lhs, const MonsterT &rhs) {
|
||||
(lhs.vector_of_enums == rhs.vector_of_enums) &&
|
||||
(lhs.signed_enum == rhs.signed_enum) &&
|
||||
(lhs.testrequirednestedflatbuffer == rhs.testrequirednestedflatbuffer) &&
|
||||
(lhs.scalar_key_sorted_tables == rhs.scalar_key_sorted_tables) &&
|
||||
(lhs.scalar_key_sorted_tables.size() == rhs.scalar_key_sorted_tables.size() && std::equal(lhs.scalar_key_sorted_tables.cbegin(), lhs.scalar_key_sorted_tables.cend(), rhs.scalar_key_sorted_tables.cbegin(), [](flatbuffers::unique_ptr<MyGame::Example::StatT> const &a, flatbuffers::unique_ptr<MyGame::Example::StatT> const &b) { return (a == b) || (a && b && *a == *b); })) &&
|
||||
(lhs.native_inline == rhs.native_inline) &&
|
||||
(lhs.long_enum_non_enum_default == rhs.long_enum_non_enum_default) &&
|
||||
(lhs.long_enum_normal_default == rhs.long_enum_normal_default);
|
||||
|
||||
@@ -2727,7 +2727,7 @@ inline bool operator==(const MonsterT &lhs, const MonsterT &rhs) {
|
||||
(lhs.test == rhs.test) &&
|
||||
(lhs.test4 == rhs.test4) &&
|
||||
(lhs.testarrayofstring == rhs.testarrayofstring) &&
|
||||
(lhs.testarrayoftables == rhs.testarrayoftables) &&
|
||||
(lhs.testarrayoftables.size() == rhs.testarrayoftables.size() && std::equal(lhs.testarrayoftables.cbegin(), lhs.testarrayoftables.cend(), rhs.testarrayoftables.cbegin(), [](flatbuffers::unique_ptr<MyGame::Example::MonsterT> const &a, flatbuffers::unique_ptr<MyGame::Example::MonsterT> const &b) { return (a == b) || (a && b && *a == *b); })) &&
|
||||
((lhs.enemy == rhs.enemy) || (lhs.enemy && rhs.enemy && *lhs.enemy == *rhs.enemy)) &&
|
||||
(lhs.testnestedflatbuffer == rhs.testnestedflatbuffer) &&
|
||||
((lhs.testempty == rhs.testempty) || (lhs.testempty && rhs.testempty && *lhs.testempty == *rhs.testempty)) &&
|
||||
@@ -2751,10 +2751,10 @@ inline bool operator==(const MonsterT &lhs, const MonsterT &rhs) {
|
||||
(lhs.vector_of_longs == rhs.vector_of_longs) &&
|
||||
(lhs.vector_of_doubles == rhs.vector_of_doubles) &&
|
||||
((lhs.parent_namespace_test == rhs.parent_namespace_test) || (lhs.parent_namespace_test && rhs.parent_namespace_test && *lhs.parent_namespace_test == *rhs.parent_namespace_test)) &&
|
||||
(lhs.vector_of_referrables == rhs.vector_of_referrables) &&
|
||||
(lhs.vector_of_referrables.size() == rhs.vector_of_referrables.size() && std::equal(lhs.vector_of_referrables.cbegin(), lhs.vector_of_referrables.cend(), rhs.vector_of_referrables.cbegin(), [](flatbuffers::unique_ptr<MyGame::Example::ReferrableT> const &a, flatbuffers::unique_ptr<MyGame::Example::ReferrableT> const &b) { return (a == b) || (a && b && *a == *b); })) &&
|
||||
(lhs.single_weak_reference == rhs.single_weak_reference) &&
|
||||
(lhs.vector_of_weak_references == rhs.vector_of_weak_references) &&
|
||||
(lhs.vector_of_strong_referrables == rhs.vector_of_strong_referrables) &&
|
||||
(lhs.vector_of_strong_referrables.size() == rhs.vector_of_strong_referrables.size() && std::equal(lhs.vector_of_strong_referrables.cbegin(), lhs.vector_of_strong_referrables.cend(), rhs.vector_of_strong_referrables.cbegin(), [](flatbuffers::unique_ptr<MyGame::Example::ReferrableT> const &a, flatbuffers::unique_ptr<MyGame::Example::ReferrableT> const &b) { return (a == b) || (a && b && *a == *b); })) &&
|
||||
(lhs.co_owning_reference == rhs.co_owning_reference) &&
|
||||
(lhs.vector_of_co_owning_references == rhs.vector_of_co_owning_references) &&
|
||||
(lhs.non_owning_reference == rhs.non_owning_reference) &&
|
||||
@@ -2764,7 +2764,7 @@ inline bool operator==(const MonsterT &lhs, const MonsterT &rhs) {
|
||||
(lhs.vector_of_enums == rhs.vector_of_enums) &&
|
||||
(lhs.signed_enum == rhs.signed_enum) &&
|
||||
(lhs.testrequirednestedflatbuffer == rhs.testrequirednestedflatbuffer) &&
|
||||
(lhs.scalar_key_sorted_tables == rhs.scalar_key_sorted_tables) &&
|
||||
(lhs.scalar_key_sorted_tables.size() == rhs.scalar_key_sorted_tables.size() && std::equal(lhs.scalar_key_sorted_tables.cbegin(), lhs.scalar_key_sorted_tables.cend(), rhs.scalar_key_sorted_tables.cbegin(), [](flatbuffers::unique_ptr<MyGame::Example::StatT> const &a, flatbuffers::unique_ptr<MyGame::Example::StatT> const &b) { return (a == b) || (a && b && *a == *b); })) &&
|
||||
(lhs.native_inline == rhs.native_inline) &&
|
||||
(lhs.long_enum_non_enum_default == rhs.long_enum_non_enum_default) &&
|
||||
(lhs.long_enum_normal_default == rhs.long_enum_normal_default);
|
||||
|
||||
@@ -16,12 +16,14 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
#include "flatbuffers/idl.h"
|
||||
#include "flatbuffers/minireflect.h"
|
||||
#include "flatbuffers/registry.h"
|
||||
#include "flatbuffers/stl_emulation.h"
|
||||
#include "flatbuffers/util.h"
|
||||
#include "monster_test_generated.h"
|
||||
#include "namespace_test/namespace_test1_generated.h"
|
||||
@@ -3542,6 +3544,48 @@ void EqualOperatorTest() {
|
||||
b.test.type = Any_Monster;
|
||||
TEST_EQ(b == a, false);
|
||||
TEST_EQ(b != a, true);
|
||||
|
||||
// Test that vector of tables are compared by value and not by reference.
|
||||
{
|
||||
// Two tables are equal by default.
|
||||
MonsterT a, b;
|
||||
TEST_EQ(a == b, true);
|
||||
|
||||
// Adding only a table to one of the monster vectors should make it not
|
||||
// equal (due to size mistmatch).
|
||||
a.testarrayoftables.push_back(
|
||||
flatbuffers::unique_ptr<MonsterT>(new MonsterT));
|
||||
TEST_EQ(a == b, false);
|
||||
|
||||
// Adding an equalivant table to the other monster vector should make it
|
||||
// equal again.
|
||||
b.testarrayoftables.push_back(
|
||||
flatbuffers::unique_ptr<MonsterT>(new MonsterT));
|
||||
TEST_EQ(a == b, true);
|
||||
|
||||
// Create two new monsters that are different.
|
||||
auto c = flatbuffers::unique_ptr<MonsterT>(new MonsterT);
|
||||
auto d = flatbuffers::unique_ptr<MonsterT>(new MonsterT);
|
||||
c->hp = 1;
|
||||
d->hp = 2;
|
||||
TEST_EQ(c == d, false);
|
||||
|
||||
// Adding them to the original monsters should also make them different.
|
||||
a.testarrayoftables.push_back(std::move(c));
|
||||
b.testarrayoftables.push_back(std::move(d));
|
||||
TEST_EQ(a == b, false);
|
||||
|
||||
// Remove the mismatching monsters to get back to equality
|
||||
a.testarrayoftables.pop_back();
|
||||
b.testarrayoftables.pop_back();
|
||||
TEST_EQ(a == b, true);
|
||||
|
||||
// Check that nullptr are OK.
|
||||
a.testarrayoftables.push_back(nullptr);
|
||||
b.testarrayoftables.push_back(
|
||||
flatbuffers::unique_ptr<MonsterT>(new MonsterT));
|
||||
TEST_EQ(a == b, false);
|
||||
}
|
||||
}
|
||||
|
||||
// For testing any binaries, e.g. from fuzzing.
|
||||
@@ -4443,9 +4487,9 @@ void PrivateAnnotationsLeaks() {
|
||||
|
||||
// (private) (table), (public) (struct/enum)
|
||||
schemas.push_back(
|
||||
"table Monster (private) { mana: int; }"
|
||||
"struct ABC { mana: int; }"
|
||||
"enum Race:byte { None = -1, Human = 0, }");
|
||||
"table Monster (private) { mana: int; }"
|
||||
"struct ABC { mana: int; }"
|
||||
"enum Race:byte { None = -1, Human = 0, }");
|
||||
|
||||
// (public) (struct) containing (public) (enum)
|
||||
schemas.push_back(
|
||||
|
||||
Reference in New Issue
Block a user