mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-01 19:58:15 +00:00
Fix operator==() generated for field of fixed sized array (#7749)
* Fix operator==() generated for field of fixed sized array * Compare address * noexcept * Grammer Co-authored-by: Derek Bailey <derekbailey@google.com>
This commit is contained in:
@@ -17,6 +17,8 @@
|
||||
#ifndef FLATBUFFERS_ARRAY_H_
|
||||
#define FLATBUFFERS_ARRAY_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "flatbuffers/base.h"
|
||||
#include "flatbuffers/stl_emulation.h"
|
||||
#include "flatbuffers/vector.h"
|
||||
@@ -238,6 +240,14 @@ const Array<E, length> &CastToArrayOfEnum(const T (&arr)[length]) {
|
||||
return *reinterpret_cast<const Array<E, length> *>(arr);
|
||||
}
|
||||
|
||||
template<typename T, uint16_t length>
|
||||
bool operator==(const Array<T, length> &lhs,
|
||||
const Array<T, length> &rhs) noexcept {
|
||||
return std::addressof(lhs) == std::addressof(rhs) ||
|
||||
(lhs.size() == rhs.size() &&
|
||||
std::memcmp(lhs.Data(), rhs.Data(), rhs.size() * sizeof(T)) == 0);
|
||||
}
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATBUFFERS_ARRAY_H_
|
||||
|
||||
@@ -2044,7 +2044,6 @@ class CppGenerator : public BaseGenerator {
|
||||
const auto accessor = Name(field) + accessSuffix;
|
||||
const auto lhs_accessor = "lhs." + accessor;
|
||||
const auto rhs_accessor = "rhs." + accessor;
|
||||
|
||||
if (!field.deprecated && // Deprecated fields won't be accessible.
|
||||
field.value.type.base_type != BASE_TYPE_UTYPE &&
|
||||
(field.value.type.base_type != BASE_TYPE_VECTOR ||
|
||||
@@ -2067,6 +2066,8 @@ class CppGenerator : public BaseGenerator {
|
||||
" const &b) { return (a == b) || (a && b && *a == *b); })";
|
||||
|
||||
compare_op += "(" + equal_length + " && " + elements_equal + ")";
|
||||
} else if (field.value.type.base_type == BASE_TYPE_ARRAY) {
|
||||
compare_op += "(*" + lhs_accessor + " == *" + rhs_accessor + ")";
|
||||
} else {
|
||||
compare_op += "(" + lhs_accessor + " == " + rhs_accessor + ")";
|
||||
}
|
||||
|
||||
@@ -141,10 +141,10 @@ FLATBUFFERS_STRUCT_END(NestedStruct, 32);
|
||||
|
||||
inline bool operator==(const NestedStruct &lhs, const NestedStruct &rhs) {
|
||||
return
|
||||
(lhs.a() == rhs.a()) &&
|
||||
(*lhs.a() == *rhs.a()) &&
|
||||
(lhs.b() == rhs.b()) &&
|
||||
(lhs.c() == rhs.c()) &&
|
||||
(lhs.d() == rhs.d());
|
||||
(*lhs.c() == *rhs.c()) &&
|
||||
(*lhs.d() == *rhs.d());
|
||||
}
|
||||
|
||||
inline bool operator!=(const NestedStruct &lhs, const NestedStruct &rhs) {
|
||||
@@ -257,11 +257,11 @@ FLATBUFFERS_STRUCT_END(ArrayStruct, 160);
|
||||
inline bool operator==(const ArrayStruct &lhs, const ArrayStruct &rhs) {
|
||||
return
|
||||
(lhs.a() == rhs.a()) &&
|
||||
(lhs.b() == rhs.b()) &&
|
||||
(*lhs.b() == *rhs.b()) &&
|
||||
(lhs.c() == rhs.c()) &&
|
||||
(lhs.d() == rhs.d()) &&
|
||||
(*lhs.d() == *rhs.d()) &&
|
||||
(lhs.e() == rhs.e()) &&
|
||||
(lhs.f() == rhs.f());
|
||||
(*lhs.f() == *rhs.f());
|
||||
}
|
||||
|
||||
inline bool operator!=(const ArrayStruct &lhs, const ArrayStruct &rhs) {
|
||||
|
||||
@@ -88,7 +88,7 @@ FLATBUFFERS_STRUCT_END(Baz, 5);
|
||||
|
||||
inline bool operator==(const Baz &lhs, const Baz &rhs) {
|
||||
return
|
||||
(lhs.a() == rhs.a()) &&
|
||||
(*lhs.a() == *rhs.a()) &&
|
||||
(lhs.b() == rhs.b());
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ FLATBUFFERS_STRUCT_END(Bar, 16);
|
||||
|
||||
inline bool operator==(const Bar &lhs, const Bar &rhs) {
|
||||
return
|
||||
(lhs.a() == rhs.a()) &&
|
||||
(*lhs.a() == *rhs.a()) &&
|
||||
(lhs.b() == rhs.b());
|
||||
}
|
||||
|
||||
|
||||
@@ -829,6 +829,54 @@ void FixedLengthArrayConstructorTest() {
|
||||
void FixedLengthArrayConstructorTest() {}
|
||||
#endif
|
||||
|
||||
void FixedLengthArrayOperatorEqualTest() {
|
||||
const int32_t nested_a[2] = { 1, 2 };
|
||||
MyGame::Example::TestEnum nested_c[2] = { MyGame::Example::TestEnum::A,
|
||||
MyGame::Example::TestEnum::B };
|
||||
|
||||
MyGame::Example::TestEnum nested_cc[2] = { MyGame::Example::TestEnum::A,
|
||||
MyGame::Example::TestEnum::C };
|
||||
const int64_t int64_2[2] = { -2, -1 };
|
||||
|
||||
std::array<MyGame::Example::NestedStruct, 2> init_d = {
|
||||
{ MyGame::Example::NestedStruct(nested_a, MyGame::Example::TestEnum::B,
|
||||
nested_c, int64_2),
|
||||
MyGame::Example::NestedStruct(nested_a, MyGame::Example::TestEnum::B,
|
||||
nested_c,
|
||||
std::array<int64_t, 2>{ { -2, -1 } }) }
|
||||
};
|
||||
|
||||
auto different = MyGame::Example::NestedStruct(
|
||||
nested_a, MyGame::Example::TestEnum::B, nested_cc,
|
||||
std::array<int64_t, 2>{ { -2, -1 } });
|
||||
|
||||
TEST_ASSERT(init_d[0] == init_d[1]);
|
||||
TEST_ASSERT(init_d[0] != different);
|
||||
|
||||
std::array<MyGame::Example::ArrayStruct, 3> arr_struct = {
|
||||
MyGame::Example::ArrayStruct(
|
||||
8.125,
|
||||
std::array<int32_t, 0xF>{
|
||||
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } },
|
||||
-17, init_d, 10, int64_2),
|
||||
|
||||
MyGame::Example::ArrayStruct(
|
||||
8.125,
|
||||
std::array<int32_t, 0xF>{
|
||||
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } },
|
||||
-17, init_d, 10, int64_2),
|
||||
|
||||
MyGame::Example::ArrayStruct(
|
||||
8.125,
|
||||
std::array<int32_t, 0xF>{
|
||||
{ 1000, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } },
|
||||
-17, init_d, 10, int64_2)
|
||||
};
|
||||
|
||||
TEST_ASSERT(arr_struct[0] == arr_struct[1]);
|
||||
TEST_ASSERT(arr_struct[1] != arr_struct[2]);
|
||||
}
|
||||
|
||||
void NativeTypeTest() {
|
||||
const int N = 3;
|
||||
|
||||
@@ -1560,6 +1608,7 @@ int FlatBufferTests(const std::string &tests_data_path) {
|
||||
ParseFlexbuffersFromJsonWithNullTest();
|
||||
FlatbuffersSpanTest();
|
||||
FixedLengthArrayConstructorTest();
|
||||
FixedLengthArrayOperatorEqualTest();
|
||||
FieldIdentifierTest();
|
||||
StringVectorDefaultsTest();
|
||||
FlexBuffersFloatingPointTest();
|
||||
|
||||
Reference in New Issue
Block a user