@@ -501,7 +501,10 @@ class CppGenerator : public BaseGenerator {
501501 }
502502 }
503503
504- if (!struct_def->fixed ) {
504+ // Don't declare a new object API struct type if the table is a
505+ // native type.
506+ const auto native_type = struct_def->attributes .Lookup (" native_type" );
507+ if (!struct_def->fixed && !native_type) {
505508 code_ += " struct " + nativeName + " ;" ;
506509 }
507510 }
@@ -886,12 +889,23 @@ class CppGenerator : public BaseGenerator {
886889
887890 static std::string NativeName (const std::string& name, const StructDef* sd,
888891 const IDLOptions& opts) {
892+ // If the table is a native_type, return the native_type name.
893+ const auto native_type = sd->attributes .Lookup (" native_type" );
894+ if (native_type && !sd->fixed ) {
895+ return native_type->constant ;
896+ }
897+
889898 return sd && !sd->fixed ? opts.object_prefix + name + opts.object_suffix
890899 : name;
891900 }
892901
893902 std::string WrapNativeNameInNameSpace (const StructDef& struct_def,
894903 const IDLOptions& opts) {
904+ // If the table is a native_type, return the native_type name.
905+ const auto native_type = struct_def.attributes .Lookup (" native_type" );
906+ if (native_type && !struct_def.fixed ) {
907+ return native_type->constant ;
908+ }
895909 return WrapInNameSpace (struct_def.defined_namespace ,
896910 NativeName (Name (struct_def), &struct_def, opts));
897911 }
@@ -2883,14 +2897,18 @@ class CppGenerator : public BaseGenerator {
28832897
28842898 // Generate an accessor struct, builder structs & function for a table.
28852899 void GenTable (const StructDef& struct_def) {
2886- if (opts_.generate_object_based_api ) {
2900+ // Don't generate an object API struct for the table if it is a native type.
2901+ const auto native_type = struct_def.attributes .Lookup (" native_type" );
2902+ if (opts_.generate_object_based_api && !native_type) {
28872903 GenNativeTable (struct_def);
28882904 }
28892905
28902906 // Generate an accessor struct, with methods of the form:
28912907 // type name() const { return GetField<type>(offset, defaultval); }
28922908 GenComment (struct_def.doc_comment );
28932909
2910+ const auto native_name = NativeName (Name (struct_def), &struct_def, opts_);
2911+ code_.SetValue (" NATIVE_NAME" , native_name);
28942912 code_.SetValue (" STRUCT_NAME" , Name (struct_def));
28952913 code_ +=
28962914 " struct {{STRUCT_NAME}} FLATBUFFERS_FINAL_CLASS"
@@ -3766,7 +3784,9 @@ class CppGenerator : public BaseGenerator {
37663784
37673785 // Generate code for tables that needs to come after the regular definition.
37683786 void GenTablePost (const StructDef& struct_def) {
3769- if (opts_.generate_object_based_api ) {
3787+ // Don't generate an object API struct for the table if it is a native type.
3788+ const auto native_type = struct_def.attributes .Lookup (" native_type" );
3789+ if (opts_.generate_object_based_api && !native_type) {
37703790 GenNativeTablePost (struct_def);
37713791 }
37723792
@@ -3776,7 +3796,9 @@ class CppGenerator : public BaseGenerator {
37763796
37773797 if (opts_.generate_object_based_api ) {
37783798 // Generate the >= C++11 copy ctor and assignment operator definitions.
3779- GenCopyCtorAssignOpDefs (struct_def);
3799+ if (!native_type) {
3800+ GenCopyCtorAssignOpDefs (struct_def);
3801+ }
37803802
37813803 // Generate the X::UnPack() method.
37823804 code_ +=
@@ -3799,33 +3821,38 @@ class CppGenerator : public BaseGenerator {
37993821 code_ += " return _o.release();" ;
38003822 code_ += " }" ;
38013823 code_ += " " ;
3802- code_ +=
3803- " inline " + TableUnPackToSignature (struct_def, false , opts_) + " {" ;
3804- code_ += " (void)_o;" ;
3805- code_ += " (void)_resolver;" ;
38063824
3807- for (auto it = struct_def.fields .vec .begin ();
3808- it != struct_def.fields .vec .end (); ++it) {
3809- const auto & field = **it;
3810- if (field.deprecated ) {
3811- continue ;
3812- }
3825+ // Generate an Unpack method for the C++ object if that table does not
3826+ // have a native type.
3827+ if (!native_type) {
3828+ code_ +=
3829+ " inline " + TableUnPackToSignature (struct_def, false , opts_) + " {" ;
3830+ code_ += " (void)_o;" ;
3831+ code_ += " (void)_resolver;" ;
3832+
3833+ for (auto it = struct_def.fields .vec .begin ();
3834+ it != struct_def.fields .vec .end (); ++it) {
3835+ const auto & field = **it;
3836+ if (field.deprecated ) {
3837+ continue ;
3838+ }
38133839
3814- // Assign a value from |this| to |_o|. Values from |this| are stored
3815- // in a variable |_e| by calling this->field_type(). The value is then
3816- // assigned to |_o| using the GenUnpackFieldStatement.
3817- const bool is_union = field.value .type .base_type == BASE_TYPE_UTYPE;
3818- const auto statement =
3819- GenUnpackFieldStatement (field, is_union ? *(it + 1 ) : nullptr );
3820-
3821- code_.SetValue (" FIELD_NAME" , Name (field));
3822- auto prefix = " { auto _e = {{FIELD_NAME}}(); " ;
3823- auto check = IsScalar (field.value .type .base_type ) ? " " : " if (_e) " ;
3824- auto postfix = " }" ;
3825- code_ += std::string (prefix) + check + statement + postfix;
3840+ // Assign a value from |this| to |_o|. Values from |this| are stored
3841+ // in a variable |_e| by calling this->field_type(). The value is
3842+ // then assigned to |_o| using the GenUnpackFieldStatement.
3843+ const bool is_union = field.value .type .base_type == BASE_TYPE_UTYPE;
3844+ const auto statement =
3845+ GenUnpackFieldStatement (field, is_union ? *(it + 1 ) : nullptr );
3846+
3847+ code_.SetValue (" FIELD_NAME" , Name (field));
3848+ auto prefix = " { auto _e = {{FIELD_NAME}}(); " ;
3849+ auto check = IsScalar (field.value .type .base_type ) ? " " : " if (_e) " ;
3850+ auto postfix = " }" ;
3851+ code_ += std::string (prefix) + check + statement + postfix;
3852+ }
3853+ code_ += " }" ;
3854+ code_ += " " ;
38263855 }
3827- code_ += " }" ;
3828- code_ += " " ;
38293856
38303857 // Generate the global CreateX function that simply calls the
38313858 // X::Pack member function.
@@ -3835,78 +3862,85 @@ class CppGenerator : public BaseGenerator {
38353862 code_ += " }" ;
38363863 code_ += " " ;
38373864
3838- // Generate a CreateX method that works with an unpacked C++ object.
3839- code_ += " inline " + TablePackSignature (struct_def, false , opts_) + " {" ;
3840- code_ += " (void)_rehasher;" ;
3841- code_ += " (void)_o;" ;
3865+ if (!native_type) {
3866+ // Generate a Pack method that works with an unpacked C++ object if it
3867+ // does not have a native type.
3868+ code_ +=
3869+ " inline " + TablePackSignature (struct_def, false , opts_) + " {" ;
3870+ code_ += " (void)_rehasher;" ;
3871+ code_ += " (void)_o;" ;
38423872
3843- code_ +=
3844- " struct _VectorArgs "
3845- " { " +
3846- GetBuilder () +
3847- " *__fbb; "
3848- " const " +
3849- NativeName (Name (struct_def), &struct_def, opts_) +
3850- " * __o; "
3851- " const ::flatbuffers::rehasher_function_t *__rehasher; } _va = { "
3852- " &_fbb, _o, _rehasher}; (void)_va;" ;
3853-
3854- for (auto it = struct_def.fields .vec .begin ();
3855- it != struct_def.fields .vec .end (); ++it) {
3856- auto & field = **it;
3857- if (field.deprecated ) {
3858- continue ;
3859- }
3860- if (IsVector (field.value .type )) {
3861- const std::string force_align_code =
3862- GenVectorForceAlign (field, " _o->" + Name (field) + " .size()" );
3863- if (!force_align_code.empty ()) {
3864- code_ += " " + force_align_code;
3873+ code_ +=
3874+ " struct _VectorArgs "
3875+ " { " +
3876+ GetBuilder () +
3877+ " *__fbb; "
3878+ " const " +
3879+ NativeName (Name (struct_def), &struct_def, opts_) +
3880+ " * __o; "
3881+ " const ::flatbuffers::rehasher_function_t *__rehasher; } _va = { "
3882+ " &_fbb, _o, _rehasher}; (void)_va;" ;
3883+
3884+ for (auto it = struct_def.fields .vec .begin ();
3885+ it != struct_def.fields .vec .end (); ++it) {
3886+ auto & field = **it;
3887+ if (field.deprecated ) {
3888+ continue ;
38653889 }
3890+ if (IsVector (field.value .type )) {
3891+ const std::string force_align_code =
3892+ GenVectorForceAlign (field, " _o->" + Name (field) + " .size()" );
3893+ if (!force_align_code.empty ()) {
3894+ code_ += " " + force_align_code;
3895+ }
3896+ }
3897+ code_ +=
3898+ " auto _" + Name (field) + " = " + GenCreateParam (field) + " ;" ;
38663899 }
3867- code_ += " auto _" + Name (field) + " = " + GenCreateParam (field) + " ;" ;
3868- }
3869- // Need to call "Create" with the struct namespace.
3870- const auto qualified_create_name =
3871- struct_def.defined_namespace ->GetFullyQualifiedName (" Create" );
3872- code_.SetValue (" CREATE_NAME" , TranslateNameSpace (qualified_create_name));
3873-
3874- code_ += " return {{CREATE_NAME}}{{STRUCT_NAME}}(" ;
3875- code_ += " _fbb\\ " ;
3876- for (const auto & field : struct_def.fields .vec ) {
3877- if (field->deprecated ) {
3878- continue ;
3879- }
3900+ // Need to call "Create" with the struct namespace.
3901+ const auto qualified_create_name =
3902+ struct_def.defined_namespace ->GetFullyQualifiedName (" Create" );
3903+ code_.SetValue (" CREATE_NAME" ,
3904+ TranslateNameSpace (qualified_create_name));
3905+
3906+ code_ += " return {{CREATE_NAME}}{{STRUCT_NAME}}(" ;
3907+ code_ += " _fbb\\ " ;
3908+ for (const auto & field : struct_def.fields .vec ) {
3909+ if (field->deprecated ) {
3910+ continue ;
3911+ }
38803912
3881- bool pass_by_address = false ;
3882- bool check_ptr = false ;
3883- if (field->value .type .base_type == BASE_TYPE_STRUCT) {
3884- if (IsStruct (field->value .type )) {
3885- auto native_type =
3886- field->value .type .struct_def ->attributes .Lookup (" native_type" );
3887- auto native_inline = field->attributes .Lookup (" native_inline" );
3888- if (native_type) {
3889- pass_by_address = true ;
3890- }
3891- if (native_type && !native_inline) {
3892- check_ptr = true ;
3913+ bool pass_by_address = false ;
3914+ bool check_ptr = false ;
3915+ if (field->value .type .base_type == BASE_TYPE_STRUCT) {
3916+ if (IsStruct (field->value .type )) {
3917+ auto native_type =
3918+ field->value .type .struct_def ->attributes .Lookup (
3919+ " native_type" );
3920+ auto native_inline = field->attributes .Lookup (" native_inline" );
3921+ if (native_type) {
3922+ pass_by_address = true ;
3923+ }
3924+ if (native_type && !native_inline) {
3925+ check_ptr = true ;
3926+ }
38933927 }
38943928 }
3895- }
38963929
3897- // Call the CreateX function using values from |_o|.
3898- if (pass_by_address && check_ptr) {
3899- code_ += " ,\n _o->" + Name (*field) + " ? &_" + Name (*field) +
3900- " : nullptr\\ " ;
3901- } else if (pass_by_address) {
3902- code_ += " ,\n &_" + Name (*field) + " \\ " ;
3903- } else {
3904- code_ += " ,\n _" + Name (*field) + " \\ " ;
3930+ // Call the CreateX function using values from |_o|.
3931+ if (pass_by_address && check_ptr) {
3932+ code_ += " ,\n _o->" + Name (*field) + " ? &_" + Name (*field) +
3933+ " : nullptr\\ " ;
3934+ } else if (pass_by_address) {
3935+ code_ += " ,\n &_" + Name (*field) + " \\ " ;
3936+ } else {
3937+ code_ += " ,\n _" + Name (*field) + " \\ " ;
3938+ }
39053939 }
3940+ code_ += " );" ;
3941+ code_ += " }" ;
3942+ code_ += " " ;
39063943 }
3907- code_ += " );" ;
3908- code_ += " }" ;
3909- code_ += " " ;
39103944 }
39113945 }
39123946
0 commit comments