mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-12 07:50:59 +00:00
Add support for using array of scalar as key field in Cpp (#7623)
* add support for using array of scalar as key field * update cmakelist and test.cpp to include the tests * update bazel rule * address comments * clang format * delete comment * delete comment * address the rest of the commnets * address comments * update naming in test file * format build file * buildifier * make keycomparelessthan call keycomparewithvalue * update to use flatbuffer array instead of raw pointer * clang * format * revert format * revert format * update * run generate_code.py * run code generator * revert changes by generate_code.py * fist run make flatc and then run generate_code.py Co-authored-by: Wen Sun <sunwen@google.com>
This commit is contained in:
@@ -2278,12 +2278,19 @@ class CppGenerator : public BaseGenerator {
|
||||
// Generate CompareWithValue method for a key field.
|
||||
void GenKeyFieldMethods(const FieldDef &field) {
|
||||
FLATBUFFERS_ASSERT(field.key);
|
||||
const bool is_string = (IsString(field.value.type));
|
||||
const bool is_string = IsString(field.value.type);
|
||||
const bool is_array = IsArray(field.value.type);
|
||||
|
||||
code_ += " bool KeyCompareLessThan(const {{STRUCT_NAME}} *o) const {";
|
||||
code_ +=
|
||||
" bool KeyCompareLessThan(const {{STRUCT_NAME}} * const o) const {";
|
||||
if (is_string) {
|
||||
// use operator< of flatbuffers::String
|
||||
code_ += " return *{{FIELD_NAME}}() < *o->{{FIELD_NAME}}();";
|
||||
} else if (is_array) {
|
||||
const auto &elem_type = field.value.type.VectorType();
|
||||
if (IsScalar(elem_type.base_type)) {
|
||||
code_ += " return KeyCompareWithValue(o->{{FIELD_NAME}}()) < 0;";
|
||||
}
|
||||
} else {
|
||||
code_ += " return {{FIELD_NAME}}() < o->{{FIELD_NAME}}();";
|
||||
}
|
||||
@@ -2292,7 +2299,27 @@ class CppGenerator : public BaseGenerator {
|
||||
if (is_string) {
|
||||
code_ += " int KeyCompareWithValue(const char *_{{FIELD_NAME}}) const {";
|
||||
code_ += " return strcmp({{FIELD_NAME}}()->c_str(), _{{FIELD_NAME}});";
|
||||
code_ += " }";
|
||||
} else if (is_array) {
|
||||
const auto &elem_type = field.value.type.VectorType();
|
||||
if (IsScalar(elem_type.base_type)) {
|
||||
std::string input_type = "flatbuffers::Array<" +
|
||||
GenTypeBasic(elem_type, false) + ", " +
|
||||
NumToString(elem_type.fixed_length) + ">";
|
||||
code_.SetValue("INPUT_TYPE", input_type);
|
||||
code_ +=
|
||||
" int KeyCompareWithValue(const {{INPUT_TYPE}} *_{{FIELD_NAME}}"
|
||||
") const { ";
|
||||
code_ += " for (auto i = 0; i < {{FIELD_NAME}}()->size(); i++) {";
|
||||
code_ += " const auto {{FIELD_NAME}}_l = {{FIELD_NAME}}_[i];";
|
||||
code_ += " const auto {{FIELD_NAME}}_r = _{{FIELD_NAME}}->Get(i);";
|
||||
code_ += " if({{FIELD_NAME}}_l != {{FIELD_NAME}}_r) ";
|
||||
code_ +=
|
||||
" return static_cast<int>({{FIELD_NAME}}_l > "
|
||||
"{{FIELD_NAME}}_r)"
|
||||
" - static_cast<int>({{FIELD_NAME}}_l < {{FIELD_NAME}}_r);";
|
||||
code_ += " }";
|
||||
code_ += " return 0;";
|
||||
}
|
||||
} else {
|
||||
FLATBUFFERS_ASSERT(IsScalar(field.value.type.base_type));
|
||||
auto type = GenTypeBasic(field.value.type, false);
|
||||
@@ -2307,8 +2334,8 @@ class CppGenerator : public BaseGenerator {
|
||||
code_ +=
|
||||
" return static_cast<int>({{FIELD_NAME}}() > _{{FIELD_NAME}}) - "
|
||||
"static_cast<int>({{FIELD_NAME}}() < _{{FIELD_NAME}});";
|
||||
code_ += " }";
|
||||
}
|
||||
code_ += " }";
|
||||
}
|
||||
|
||||
void GenTableUnionAsGetters(const FieldDef &field) {
|
||||
|
||||
@@ -1057,8 +1057,12 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
|
||||
if (field->key) {
|
||||
if (struct_def.has_key) return Error("only one field may be set as 'key'");
|
||||
struct_def.has_key = true;
|
||||
if (!IsScalar(type.base_type) && !IsString(type)) {
|
||||
return Error("'key' field must be string or scalar type");
|
||||
auto is_valid = IsScalar(type.base_type) || IsString(type);
|
||||
if (IsArray(type)) { is_valid |= IsScalar(type.VectorType().base_type); }
|
||||
if (!is_valid) {
|
||||
return Error(
|
||||
"'key' field must be string, scalar type or fixed size array of "
|
||||
"scalars");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1502,7 +1506,7 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
|
||||
if (!struct_def.sortbysize ||
|
||||
size == SizeOf(field_value.type.base_type)) {
|
||||
switch (field_value.type.base_type) {
|
||||
// clang-format off
|
||||
// clang-format off
|
||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
|
||||
case BASE_TYPE_ ## ENUM: \
|
||||
builder_.Pad(field->padding); \
|
||||
@@ -1631,7 +1635,7 @@ CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue,
|
||||
// start at the back, since we're building the data backwards.
|
||||
auto &val = field_stack_.back().first;
|
||||
switch (val.type.base_type) {
|
||||
// clang-format off
|
||||
// clang-format off
|
||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE,...) \
|
||||
case BASE_TYPE_ ## ENUM: \
|
||||
if (IsStruct(val.type)) SerializeStruct(*val.type.struct_def, val); \
|
||||
@@ -2267,8 +2271,12 @@ template<typename T> void EnumDef::ChangeEnumValue(EnumVal *ev, T new_value) {
|
||||
}
|
||||
|
||||
namespace EnumHelper {
|
||||
template<BaseType E> struct EnumValType { typedef int64_t type; };
|
||||
template<> struct EnumValType<BASE_TYPE_ULONG> { typedef uint64_t type; };
|
||||
template<BaseType E> struct EnumValType {
|
||||
typedef int64_t type;
|
||||
};
|
||||
template<> struct EnumValType<BASE_TYPE_ULONG> {
|
||||
typedef uint64_t type;
|
||||
};
|
||||
} // namespace EnumHelper
|
||||
|
||||
struct EnumValBuilder {
|
||||
|
||||
Reference in New Issue
Block a user