diff --git a/samples/monster_generated.h b/samples/monster_generated.h index 74cb96253..a2a8308bd 100644 --- a/samples/monster_generated.h +++ b/samples/monster_generated.h @@ -564,7 +564,7 @@ inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function { auto _e = name(); if (_e) _o->name = _e->str(); } { auto _e = inventory(); if (_e) { _o->inventory.resize(_e->size()); std::copy(_e->begin(), _e->end(), _o->inventory.begin()); } } { auto _e = color(); _o->color = _e; } - { auto _e = weapons(); if (_e) { _o->weapons.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->weapons[_i] = flatbuffers::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } } + { auto _e = weapons(); if (_e) { _o->weapons.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { if(_o->weapons[_i]) { _e->Get(_i)->UnPackTo(_o->weapons[_i].get(), _resolver); } else { _o->weapons[_i] = flatbuffers::unique_ptr(_e->Get(_i)->UnPack(_resolver)); }; } } } { auto _e = equipped_type(); _o->equipped.type = _e; } { auto _e = equipped(); if (_e) _o->equipped.value = MyGame::Sample::EquipmentUnion::UnPack(_e, equipped_type(), _resolver); } { auto _e = path(); if (_e) { _o->path.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->path[_i] = *_e->Get(_i); } } } diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index 019845db4..455637127 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -2767,9 +2767,19 @@ class CppGenerator : public BaseGenerator { code += "/* else do nothing */"; } } else { + const bool is_pointer = + field.value.type.VectorType().base_type == BASE_TYPE_STRUCT && + !IsStruct(field.value.type.VectorType()); + if (is_pointer) { + code += "if(_o->" + name + "[_i]" + ") { "; + code += indexing + "->UnPackTo(_o->" + name + + "[_i].get(), _resolver);"; + code += " } else { "; + } code += "_o->" + name + "[_i]" + access + " = "; code += GenUnpackVal(field.value.type.VectorType(), indexing, true, field); + if (is_pointer) { code += "; }"; } } code += "; } }"; } @@ -2816,8 +2826,17 @@ class CppGenerator : public BaseGenerator { } else { // Generate code for assigning the value, of the form: // _o->field = value; + const bool is_pointer = + field.value.type.base_type == BASE_TYPE_STRUCT && + !IsStruct(field.value.type); + if (is_pointer) { + code += "{ if(_o->" + Name(field) + ") { "; + code += "_e->UnPackTo(_o->" + Name(field) + ".get(), _resolver);"; + code += " } else { "; + } code += "_o->" + Name(field) + " = "; code += GenUnpackVal(field.value.type, "_e", false, field) + ";"; + if (is_pointer) { code += " } }"; } } break; } diff --git a/tests/cpp17/generated_cpp17/monster_test_generated.h b/tests/cpp17/generated_cpp17/monster_test_generated.h index 06477eab3..c95be273f 100644 --- a/tests/cpp17/generated_cpp17/monster_test_generated.h +++ b/tests/cpp17/generated_cpp17/monster_test_generated.h @@ -2686,10 +2686,10 @@ inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function { auto _e = test(); if (_e) _o->test.value = MyGame::Example::AnyUnion::UnPack(_e, test_type(), _resolver); } { auto _e = test4(); if (_e) { _o->test4.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->test4[_i] = *_e->Get(_i); } } } { auto _e = testarrayofstring(); if (_e) { _o->testarrayofstring.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofstring[_i] = _e->Get(_i)->str(); } } } - { auto _e = testarrayoftables(); if (_e) { _o->testarrayoftables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayoftables[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } } - { auto _e = enemy(); if (_e) _o->enemy = std::unique_ptr(_e->UnPack(_resolver)); } + { auto _e = testarrayoftables(); if (_e) { _o->testarrayoftables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { if(_o->testarrayoftables[_i]) { _e->Get(_i)->UnPackTo(_o->testarrayoftables[_i].get(), _resolver); } else { _o->testarrayoftables[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); }; } } } + { auto _e = enemy(); if (_e) { if(_o->enemy) { _e->UnPackTo(_o->enemy.get(), _resolver); } else { _o->enemy = std::unique_ptr(_e->UnPack(_resolver)); } } } { auto _e = testnestedflatbuffer(); if (_e) { _o->testnestedflatbuffer.resize(_e->size()); std::copy(_e->begin(), _e->end(), _o->testnestedflatbuffer.begin()); } } - { auto _e = testempty(); if (_e) _o->testempty = std::unique_ptr(_e->UnPack(_resolver)); } + { auto _e = testempty(); if (_e) { if(_o->testempty) { _e->UnPackTo(_o->testempty.get(), _resolver); } else { _o->testempty = std::unique_ptr(_e->UnPack(_resolver)); } } } { auto _e = testbool(); _o->testbool = _e; } { auto _e = testhashs32_fnv1(); _o->testhashs32_fnv1 = _e; } { auto _e = testhashu32_fnv1(); _o->testhashu32_fnv1 = _e; } @@ -2710,13 +2710,13 @@ if (_resolver) (*_resolver)(reinterpret_cast(&_o->testhashu32_fnv1a), s { auto _e = test5(); if (_e) { _o->test5.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->test5[_i] = *_e->Get(_i); } } } { auto _e = vector_of_longs(); if (_e) { _o->vector_of_longs.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_longs[_i] = _e->Get(_i); } } } { auto _e = vector_of_doubles(); if (_e) { _o->vector_of_doubles.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_doubles[_i] = _e->Get(_i); } } } - { auto _e = parent_namespace_test(); if (_e) _o->parent_namespace_test = std::unique_ptr(_e->UnPack(_resolver)); } - { auto _e = vector_of_referrables(); if (_e) { _o->vector_of_referrables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_referrables[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } } + { auto _e = parent_namespace_test(); if (_e) { if(_o->parent_namespace_test) { _e->UnPackTo(_o->parent_namespace_test.get(), _resolver); } else { _o->parent_namespace_test = std::unique_ptr(_e->UnPack(_resolver)); } } } + { auto _e = vector_of_referrables(); if (_e) { _o->vector_of_referrables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { if(_o->vector_of_referrables[_i]) { _e->Get(_i)->UnPackTo(_o->vector_of_referrables[_i].get(), _resolver); } else { _o->vector_of_referrables[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); }; } } } { auto _e = single_weak_reference(); //scalar resolver, naked if (_resolver) (*_resolver)(reinterpret_cast(&_o->single_weak_reference), static_cast(_e)); else _o->single_weak_reference = nullptr; } { auto _e = vector_of_weak_references(); if (_e) { _o->vector_of_weak_references.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { //vector resolver, naked if (_resolver) (*_resolver)(reinterpret_cast(&_o->vector_of_weak_references[_i]), static_cast(_e->Get(_i))); else _o->vector_of_weak_references[_i] = nullptr; } } } - { auto _e = vector_of_strong_referrables(); if (_e) { _o->vector_of_strong_referrables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_strong_referrables[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } } + { auto _e = vector_of_strong_referrables(); if (_e) { _o->vector_of_strong_referrables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { if(_o->vector_of_strong_referrables[_i]) { _e->Get(_i)->UnPackTo(_o->vector_of_strong_referrables[_i].get(), _resolver); } else { _o->vector_of_strong_referrables[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); }; } } } { auto _e = co_owning_reference(); //scalar resolver, naked if (_resolver) (*_resolver)(reinterpret_cast(&_o->co_owning_reference), static_cast(_e)); else _o->co_owning_reference = nullptr; } { auto _e = vector_of_co_owning_references(); if (_e) { _o->vector_of_co_owning_references.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { //vector resolver, default_ptr_type @@ -2732,7 +2732,7 @@ if (_resolver) (*_resolver)(reinterpret_cast(&_o->vector_of_non_owning_ { auto _e = vector_of_enums(); if (_e) { _o->vector_of_enums.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_enums[_i] = static_cast(_e->Get(_i)); } } } { auto _e = signed_enum(); _o->signed_enum = _e; } { auto _e = testrequirednestedflatbuffer(); if (_e) { _o->testrequirednestedflatbuffer.resize(_e->size()); std::copy(_e->begin(), _e->end(), _o->testrequirednestedflatbuffer.begin()); } } - { auto _e = scalar_key_sorted_tables(); if (_e) { _o->scalar_key_sorted_tables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->scalar_key_sorted_tables[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } } + { auto _e = scalar_key_sorted_tables(); if (_e) { _o->scalar_key_sorted_tables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { if(_o->scalar_key_sorted_tables[_i]) { _e->Get(_i)->UnPackTo(_o->scalar_key_sorted_tables[_i].get(), _resolver); } else { _o->scalar_key_sorted_tables[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); }; } } } } inline flatbuffers::Offset Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) { diff --git a/tests/monster_test_generated.h b/tests/monster_test_generated.h index 1a887aabc..575bff25d 100644 --- a/tests/monster_test_generated.h +++ b/tests/monster_test_generated.h @@ -2635,10 +2635,10 @@ inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function { auto _e = test(); if (_e) _o->test.value = MyGame::Example::AnyUnion::UnPack(_e, test_type(), _resolver); } { auto _e = test4(); if (_e) { _o->test4.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->test4[_i] = *_e->Get(_i); } } } { auto _e = testarrayofstring(); if (_e) { _o->testarrayofstring.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofstring[_i] = _e->Get(_i)->str(); } } } - { auto _e = testarrayoftables(); if (_e) { _o->testarrayoftables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayoftables[_i] = flatbuffers::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } } - { auto _e = enemy(); if (_e) _o->enemy = flatbuffers::unique_ptr(_e->UnPack(_resolver)); } + { auto _e = testarrayoftables(); if (_e) { _o->testarrayoftables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { if(_o->testarrayoftables[_i]) { _e->Get(_i)->UnPackTo(_o->testarrayoftables[_i].get(), _resolver); } else { _o->testarrayoftables[_i] = flatbuffers::unique_ptr(_e->Get(_i)->UnPack(_resolver)); }; } } } + { auto _e = enemy(); if (_e) { if(_o->enemy) { _e->UnPackTo(_o->enemy.get(), _resolver); } else { _o->enemy = flatbuffers::unique_ptr(_e->UnPack(_resolver)); } } } { auto _e = testnestedflatbuffer(); if (_e) { _o->testnestedflatbuffer.resize(_e->size()); std::copy(_e->begin(), _e->end(), _o->testnestedflatbuffer.begin()); } } - { auto _e = testempty(); if (_e) _o->testempty = flatbuffers::unique_ptr(_e->UnPack(_resolver)); } + { auto _e = testempty(); if (_e) { if(_o->testempty) { _e->UnPackTo(_o->testempty.get(), _resolver); } else { _o->testempty = flatbuffers::unique_ptr(_e->UnPack(_resolver)); } } } { auto _e = testbool(); _o->testbool = _e; } { auto _e = testhashs32_fnv1(); _o->testhashs32_fnv1 = _e; } { auto _e = testhashu32_fnv1(); _o->testhashu32_fnv1 = _e; } @@ -2659,13 +2659,13 @@ if (_resolver) (*_resolver)(reinterpret_cast(&_o->testhashu32_fnv1a), s { auto _e = test5(); if (_e) { _o->test5.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->test5[_i] = *_e->Get(_i); } } } { auto _e = vector_of_longs(); if (_e) { _o->vector_of_longs.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_longs[_i] = _e->Get(_i); } } } { auto _e = vector_of_doubles(); if (_e) { _o->vector_of_doubles.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_doubles[_i] = _e->Get(_i); } } } - { auto _e = parent_namespace_test(); if (_e) _o->parent_namespace_test = flatbuffers::unique_ptr(_e->UnPack(_resolver)); } - { auto _e = vector_of_referrables(); if (_e) { _o->vector_of_referrables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_referrables[_i] = flatbuffers::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } } + { auto _e = parent_namespace_test(); if (_e) { if(_o->parent_namespace_test) { _e->UnPackTo(_o->parent_namespace_test.get(), _resolver); } else { _o->parent_namespace_test = flatbuffers::unique_ptr(_e->UnPack(_resolver)); } } } + { auto _e = vector_of_referrables(); if (_e) { _o->vector_of_referrables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { if(_o->vector_of_referrables[_i]) { _e->Get(_i)->UnPackTo(_o->vector_of_referrables[_i].get(), _resolver); } else { _o->vector_of_referrables[_i] = flatbuffers::unique_ptr(_e->Get(_i)->UnPack(_resolver)); }; } } } { auto _e = single_weak_reference(); //scalar resolver, naked if (_resolver) (*_resolver)(reinterpret_cast(&_o->single_weak_reference), static_cast(_e)); else _o->single_weak_reference = nullptr; } { auto _e = vector_of_weak_references(); if (_e) { _o->vector_of_weak_references.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { //vector resolver, naked if (_resolver) (*_resolver)(reinterpret_cast(&_o->vector_of_weak_references[_i]), static_cast(_e->Get(_i))); else _o->vector_of_weak_references[_i] = nullptr; } } } - { auto _e = vector_of_strong_referrables(); if (_e) { _o->vector_of_strong_referrables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_strong_referrables[_i] = flatbuffers::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } } + { auto _e = vector_of_strong_referrables(); if (_e) { _o->vector_of_strong_referrables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { if(_o->vector_of_strong_referrables[_i]) { _e->Get(_i)->UnPackTo(_o->vector_of_strong_referrables[_i].get(), _resolver); } else { _o->vector_of_strong_referrables[_i] = flatbuffers::unique_ptr(_e->Get(_i)->UnPack(_resolver)); }; } } } { auto _e = co_owning_reference(); //scalar resolver, naked if (_resolver) (*_resolver)(reinterpret_cast(&_o->co_owning_reference), static_cast(_e)); else _o->co_owning_reference = nullptr; } { auto _e = vector_of_co_owning_references(); if (_e) { _o->vector_of_co_owning_references.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { //vector resolver, default_ptr_type @@ -2681,7 +2681,7 @@ if (_resolver) (*_resolver)(reinterpret_cast(&_o->vector_of_non_owning_ { auto _e = vector_of_enums(); if (_e) { _o->vector_of_enums.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_enums[_i] = static_cast(_e->Get(_i)); } } } { auto _e = signed_enum(); _o->signed_enum = _e; } { auto _e = testrequirednestedflatbuffer(); if (_e) { _o->testrequirednestedflatbuffer.resize(_e->size()); std::copy(_e->begin(), _e->end(), _o->testrequirednestedflatbuffer.begin()); } } - { auto _e = scalar_key_sorted_tables(); if (_e) { _o->scalar_key_sorted_tables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->scalar_key_sorted_tables[_i] = flatbuffers::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } } + { auto _e = scalar_key_sorted_tables(); if (_e) { _o->scalar_key_sorted_tables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { if(_o->scalar_key_sorted_tables[_i]) { _e->Get(_i)->UnPackTo(_o->scalar_key_sorted_tables[_i].get(), _resolver); } else { _o->scalar_key_sorted_tables[_i] = flatbuffers::unique_ptr(_e->Get(_i)->UnPack(_resolver)); }; } } } } inline flatbuffers::Offset Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) { diff --git a/tests/namespace_test/namespace_test2_generated.h b/tests/namespace_test/namespace_test2_generated.h index b53bc1517..8db01254b 100644 --- a/tests/namespace_test/namespace_test2_generated.h +++ b/tests/namespace_test/namespace_test2_generated.h @@ -359,7 +359,7 @@ inline TableInFirstNST *TableInFirstNS::UnPack(const flatbuffers::resolver_funct inline void TableInFirstNS::UnPackTo(TableInFirstNST *_o, const flatbuffers::resolver_function_t *_resolver) const { (void)_o; (void)_resolver; - { auto _e = foo_table(); if (_e) _o->foo_table = flatbuffers::unique_ptr(_e->UnPack(_resolver)); } + { auto _e = foo_table(); if (_e) { if(_o->foo_table) { _e->UnPackTo(_o->foo_table.get(), _resolver); } else { _o->foo_table = flatbuffers::unique_ptr(_e->UnPack(_resolver)); } } } { auto _e = foo_enum(); _o->foo_enum = _e; } { auto _e = foo_union_type(); _o->foo_union.type = _e; } { auto _e = foo_union(); if (_e) _o->foo_union.value = NamespaceA::NamespaceB::UnionInNestedNSUnion::UnPack(_e, foo_union_type(), _resolver); } @@ -413,8 +413,8 @@ inline TableInCT *TableInC::UnPack(const flatbuffers::resolver_function_t *_reso inline void TableInC::UnPackTo(TableInCT *_o, const flatbuffers::resolver_function_t *_resolver) const { (void)_o; (void)_resolver; - { auto _e = refer_to_a1(); if (_e) _o->refer_to_a1 = flatbuffers::unique_ptr(_e->UnPack(_resolver)); } - { auto _e = refer_to_a2(); if (_e) _o->refer_to_a2 = flatbuffers::unique_ptr(_e->UnPack(_resolver)); } + { auto _e = refer_to_a1(); if (_e) { if(_o->refer_to_a1) { _e->UnPackTo(_o->refer_to_a1.get(), _resolver); } else { _o->refer_to_a1 = flatbuffers::unique_ptr(_e->UnPack(_resolver)); } } } + { auto _e = refer_to_a2(); if (_e) { if(_o->refer_to_a2) { _e->UnPackTo(_o->refer_to_a2.get(), _resolver); } else { _o->refer_to_a2 = flatbuffers::unique_ptr(_e->UnPack(_resolver)); } } } } inline flatbuffers::Offset TableInC::Pack(flatbuffers::FlatBufferBuilder &_fbb, const TableInCT* _o, const flatbuffers::rehasher_function_t *_rehasher) { @@ -457,7 +457,7 @@ inline SecondTableInAT *SecondTableInA::UnPack(const flatbuffers::resolver_funct inline void SecondTableInA::UnPackTo(SecondTableInAT *_o, const flatbuffers::resolver_function_t *_resolver) const { (void)_o; (void)_resolver; - { auto _e = refer_to_c(); if (_e) _o->refer_to_c = flatbuffers::unique_ptr(_e->UnPack(_resolver)); } + { auto _e = refer_to_c(); if (_e) { if(_o->refer_to_c) { _e->UnPackTo(_o->refer_to_c.get(), _resolver); } else { _o->refer_to_c = flatbuffers::unique_ptr(_e->UnPack(_resolver)); } } } } inline flatbuffers::Offset SecondTableInA::Pack(flatbuffers::FlatBufferBuilder &_fbb, const SecondTableInAT* _o, const flatbuffers::rehasher_function_t *_rehasher) {