diff --git a/src/main/java/com/eprosima/fastcdr/idl/templates/FastCdrCommon.stg b/src/main/java/com/eprosima/fastcdr/idl/templates/FastCdrCommon.stg index 12bc5f26..0f8f316d 100644 --- a/src/main/java/com/eprosima/fastcdr/idl/templates/FastCdrCommon.stg +++ b/src/main/java/com/eprosima/fastcdr/idl/templates/FastCdrCommon.stg @@ -59,3 +59,13 @@ member_array_cstring_destructor(ctx, name, loopvar, dims) ::= <<$if(rest(dims))$ { free(str); }$endif$>> + +member_default_init(member) ::= <% +$if(member.annotationDefault)$ + {$member.annotationDefaultValue$} +$elseif(!member.annotationOptional && !member.annotationExternal)$ +$if(member.typecode.initialValue)$ + {$member.typecode.initialValue$} +$endif$ +$endif$ +%> diff --git a/src/main/java/com/eprosima/fastcdr/idl/templates/TypesHeader.stg b/src/main/java/com/eprosima/fastcdr/idl/templates/TypesHeader.stg index 675a88b3..93200dbe 100644 --- a/src/main/java/com/eprosima/fastcdr/idl/templates/TypesHeader.stg +++ b/src/main/java/com/eprosima/fastcdr/idl/templates/TypesHeader.stg @@ -30,6 +30,9 @@ $if(ctx.thereIsBitset)$ #include $endif$ #include +$if(ctx.thereIsUnion)$ +#include +$endif$ $if(ctx.thereIsMap)$ #include $endif$ @@ -295,10 +298,8 @@ public: */ eProsima_user_DllExport $union.name$() { - $if(union.defaultvalue)$ - m__d = $union.defaultvalue$; - $else$ - m__d = $first(first(union.members).labels)$; + $if(union.defaultMember)$ + $union.defaultMember.name$_(); $endif$ } @@ -307,6 +308,10 @@ public: */ eProsima_user_DllExport ~$union.name$() { + if (member_destructor_) + { + member_destructor_(); + } } /*! @@ -318,10 +323,13 @@ public: { m__d = x.m__d; - switch (m__d) + switch (x.selected_member_) { - $union.members:{ member | $unionmember_copy(member)$}; separator="\n"$ - $unionmemberdefault_copy(union.defaultMember)$ + $union.members:{ member | + case $member.id$: + $member.name$_() = x.m_$member.name$; + break; + }; separator="\n"$ } } @@ -334,10 +342,13 @@ public: { m__d = x.m__d; - switch (m__d) + switch (x.selected_member_) { - $union.members:{ member | $unionmember_move(member)$}; separator="\n"$ - $unionmemberdefault_move(union.defaultMember)$ + $union.members:{ member | + case $member.id$: + $member.name$_() = std::move(x.m_$member.name$); + break; + }; separator="\n"$ } } @@ -350,10 +361,13 @@ public: { m__d = x.m__d; - switch (m__d) + switch (x.selected_member_) { - $union.members:{ member | $unionmember_copy(member)$}; separator="\n"$ - $unionmemberdefault_copy(union.defaultMember)$ + $union.members:{ member | + case $member.id$: + $member.name$_() = x.m_$member.name$; + break; + }; separator="\n"$ } return *this; @@ -368,10 +382,13 @@ public: { m__d = x.m__d; - switch (m__d) + switch (x.selected_member_) { - $union.members:{ member | $unionmember_move(member)$}; separator="\n"$ - $unionmemberdefault_move(union.defaultMember)$ + $union.members:{ member | + case $member.id$: + $member.name$_() = std::move(x.m_$member.name$); + break; + }; separator="\n"$ } return *this; @@ -384,19 +401,22 @@ public: eProsima_user_DllExport bool operator ==( const $union.name$& x) const { - if (m__d != x.m__d) - { - return false; - } + bool ret_value {false}; - switch (m__d) + if (m__d == x.m__d && + selected_member_ == x.selected_member_) { - $union.members:{ member | $unionmember_compare(member)$}; separator="\n"$ - $unionmemberdefault_compare(union.defaultMember)$ + switch (selected_member_) + { + $union.members:{ member | + case $member.id$: + ret_value = (m_$member.name$ == x.m_$member.name$); + break; + }; separator="\n"$ + } } - $if(!union.defaultMember)$ - return false; - $endif$ + + return ret_value; } /*! @@ -417,18 +437,24 @@ public: eProsima_user_DllExport void _d( $union.discriminator.typecode.cppTypename$ __d) { - bool b = false; + bool valid_discriminator = false; - switch (m__d) + switch (__d) { - $union.members:{ member | $unionmember_discriminator_case(member=member, totallabels=union.totallabels)$}; separator="\n"$ - $if(!union.defaultMember)$ + $union.members:{ member | + $member.labels:{ label | case $label$:}; separator="\n"$ + $if(member.default)$ default: - break; $endif$ + if ($member.id$ == selected_member_) + { + valid_discriminator = true; + \} + break; + }; separator="\n"$ } - if (!b) + if (!valid_discriminator) { throw eprosima::fastcdr::exception::BadParamException("Discriminator doesn't correspond with the selected union member"); } @@ -445,24 +471,58 @@ public: return m__d; } - /*! - * @brief This function returns a reference to the discriminator. - * @return Reference to the discriminator. - */ - eProsima_user_DllExport $union.discriminator.typecode.cppTypename$& _d() + $union.members: { member | $public_union_member_declaration(union, member)$}; separator="\n"$ + + $if(!union.defaultMember)$ + void _default() { - return m__d; - } + if (member_destructor_) + { + member_destructor_(); + } - $union.members:{ member | $public_unionmember_declaration(union, member)$}; separator="\n"$ + selected_member_ = 0x0FFFFFFFu; + } + $endif$ $extensions : {extension | $extension$}; separator="\n"$ private: - $union.discriminator.typecode.cppTypename$ m__d; + $union.members: { member | + $member_type_declaration(member)$& $member.name$_() + { + if ($member.id$ != selected_member_) + { + if (member_destructor_) + { + member_destructor_(); + \} + + selected_member_ = $member.id$; + $if(member.typecode.primitive)$ + member_destructor_ = nullptr; + m_$member.name$ = $member_default_init(member)$; + $else$ + member_destructor_ = [&]() {$union_member_destroy_call(member)$\}; + new(&m_$member.name$) $member_type_declaration(member)$(); + $endif$; + \} + + return m_$member.name$; + \} + }; separator="\n"$ + + $union.discriminator.typecode.cppTypename$ m__d {$union.defaultvalue$}; + + union + { + $union.members:{ member | $union_member_declaration(member=member)$}; separator="\n"$ + }; + + uint32_t selected_member_ {0x0FFFFFFFu}; - $union.members:{ member | $private_member_declaration(member=member)$}; separator="\n"$ + std::function member_destructor_; }; >> @@ -775,17 +835,17 @@ private_member_declaration(member) ::= << $member_type_declaration(member)$ m_$member.name$$member_default_init(member)$; >> -public_unionmember_declaration(union, member) ::= << +public_union_member_declaration(union, member) ::= << $if(member.annotationExternal)$ -$public_unionmember_common_declaration(union, member)$ +$public_union_member_common_declaration(union, member)$ $elseif(member.typecode.primitive)$ -$public_unionmember_primitive_declaration(union, member)$ +$public_union_member_primitive_declaration(union, member)$ $else$ -$public_unionmember_common_declaration(union, member)$ +$public_union_member_common_declaration(union, member)$ $endif$ >> -public_unionmember_primitive_declaration(union, member) ::= << +public_union_member_primitive_declaration(union, member) ::= << /*! * @brief This function sets a value in member $member.name$ * @param _$member.name$ New value for member $member.name$ @@ -793,8 +853,8 @@ public_unionmember_primitive_declaration(union, member) ::= << eProsima_user_DllExport void $member.name$( $member.typecode.cppTypename$ _$member.name$) { - m_$member.name$ = _$member.name$; - $unionmember_set_discriminator(member=member, defaultvalue=union.defaultvalue)$ + $member.name$_() = _$member.name$; + $union_member_set_discriminator(member=member, defaultvalue=union.defaultvalue)$ } /*! @@ -804,7 +864,10 @@ eProsima_user_DllExport void $member.name$( */ eProsima_user_DllExport $member.typecode.cppTypename$ $member.name$() const { - $unionmember_check_case_list(member=member, totallabels=union.totallabels)$ + if ($member.id$ != selected_member_) + { + throw eprosima::fastcdr::exception::BadParamException("This member has not been selected"); + } return m_$member.name$; } @@ -816,13 +879,16 @@ eProsima_user_DllExport $member.typecode.cppTypename$ $member.name$() const */ eProsima_user_DllExport $member.typecode.cppTypename$& $member.name$() { - $unionmember_check_case_list(member=member, totallabels=union.totallabels)$ + if ($member.id$ != selected_member_) + { + throw eprosima::fastcdr::exception::BadParamException("This member has not been selected"); + } return m_$member.name$; } >> -public_unionmember_common_declaration(union, member) ::= << +public_union_member_common_declaration(union, member) ::= << /*! * @brief This function copies the value in member $member.name$ * @param _$member.name$ New value to be copied in member $member.name$ @@ -830,8 +896,8 @@ public_unionmember_common_declaration(union, member) ::= << eProsima_user_DllExport void $member.name$( const $member_type_declaration(member)$& _$member.name$) { - m_$member.name$ = _$member.name$; - $unionmember_set_discriminator(member=member, defaultvalue=union.defaultvalue)$ + $member.name$_() = _$member.name$; + $union_member_set_discriminator(member=member, defaultvalue=union.defaultvalue)$ } /*! @@ -841,8 +907,8 @@ eProsima_user_DllExport void $member.name$( eProsima_user_DllExport void $member.name$( $member_type_declaration(member)$&& _$member.name$) { - m_$member.name$ = std::move(_$member.name$); - $unionmember_set_discriminator(member=member, defaultvalue=union.defaultvalue)$ + $member.name$_() = _$member.name$; + $union_member_set_discriminator(member=member, defaultvalue=union.defaultvalue)$ } /*! @@ -852,7 +918,10 @@ eProsima_user_DllExport void $member.name$( */ eProsima_user_DllExport const $member_type_declaration(member)$& $member.name$() const { - $unionmember_check_case_list(member=member, totallabels=union.totallabels)$ + if ($member.id$ != selected_member_) + { + throw eprosima::fastcdr::exception::BadParamException("This member has not been selected"); + } return m_$member.name$; } @@ -864,22 +933,15 @@ eProsima_user_DllExport const $member_type_declaration(member)$& $member.name$() */ eProsima_user_DllExport $member_type_declaration(member)$& $member.name$() { - $unionmember_check_case_list(member=member, totallabels=union.totallabels)$ + if ($member.id$ != selected_member_) + { + throw eprosima::fastcdr::exception::BadParamException("This member has not been selected"); + } return m_$member.name$; } >> -member_default_init(member) ::= <% -$if(member.annotationDefault)$ - {$member.annotationDefaultValue$} -$elseif(!member.annotationOptional && !member.annotationExternal)$ -$if(member.typecode.initialValue)$ - {$member.typecode.initialValue$} -$endif$ -$endif$ -%> - member_move(member) ::= <% $if(member.typecode.primitive)$ m_$member.name$ = x.m_$member.name$; @@ -888,137 +950,38 @@ m_$member.name$ = std::move(x.m_$member.name$); $endif$ %> -unionmember_discriminator_case(member, totallabels) ::= << -$if(member.default)$ -default: - b = true; - switch (__d) - { - $totallabels:{ label | case $label$:}; separator="\n"$ - b = false; - break; - default: - break; - } - break; -$else$ -$member.labels:{ label | case $label$:}; separator="\n"$ - switch (__d) - { - $member.labels:{ label | case $label$:}; separator="\n"$ - b = true; - break; - default: - break; - } - break; -$endif$ ->> - -unionmember_copy(member) ::= << -$if(member.labels)$ -$member.labels:{ label | case $label$:}; separator="\n"$ - m_$member.name$ = x.m_$member.name$; - break; -$endif$ +union_member_declaration(member) ::= << +$member_type_declaration(member)$ m_$member.name$; >> -unionmemberdefault_copy(member) ::= << -default: -$if(member)$ -$if(member.default)$ - m_$member.name$ = x.m_$member.name$; -$endif$ -$endif$ - - break; ->> - -unionmember_move(member) ::= << -$if(member.labels)$ -$member.labels:{ label | case $label$:}; separator="\n"$ -$if(member.typecode.primitive)$ - m_$member.name$ = x.m_$member.name$; +union_member_destroy_call(member) ::= <% +m_$member.name$. +$if(member.annotationExternal)$ +~external(); +$elseif(!member.typecode.isAliasType && (member.typecode.isStringType || member.typecode.isWStringType))$ +$if(member.typecode.isBounded && member.typecode.isStringType)$ +~fixed_string(); $else$ - m_$member.name$ = std::move(x.m_$member.name$); -$endif$ - - break; -$endif$ ->> - -unionmemberdefault_move(member) ::= << -default: -$if(member)$ -$if(member.default)$ -$if(member.typecode.primitive)$ - m_$member.name$ = x.m_$member.name$; +~basic_string(); +$endif$ +$elseif(!member.typecode.isAliasType && member.typecode.isSequenceType)$ +~vector(); +$elseif(!member.typecode.isAliasType && member.typecode.isArrayType)$ +~array(); +$elseif(!member.typecode.isAliasType && member.typecode.isMapType)$ +~map(); $else$ - m_$member.name$ = std::move(x.m_$member.name$); -$endif$ -$endif$ -$endif$ - - break; ->> - -unionmember_compare(member) ::= << -$if(member.labels)$ -$member.labels:{ label | case $label$:}; separator="\n"$ - return (m_$member.name$ == x.m_$member.name$); - break; +~$member.typecode.noScopedCppTypename$(); $endif$ ->> - -unionmemberdefault_compare(member) ::= << -default: -$if(member)$ -$if(member.default)$ - return m_$member.name$ == x.m_$member.name$; -$endif$ -$endif$ - - break; ->> +%> -unionmember_set_discriminator(member, defaultvalue) ::= << +union_member_set_discriminator(member, defaultvalue) ::= <% $if(member.default)$ m__d = $defaultvalue$; $else$ m__d = $first(member.labels)$; $endif$ ->> - -unionmember_check_case_list(member, totallabels) ::= << -$if(member.default)$ -bool b = true; - -switch (m__d) -{ - $totallabels:{ label | case $label$:}; separator="\n"$ - b = false; - break; - default: - break; -} -$else$ -bool b = false; - -switch (m__d) -{ - $member.labels:{ label | case $label$:}; separator="\n"$ - b = true; - break; - default: - break; -} -$endif$ - -if (!b) -{ - throw eprosima::fastcdr::exception::BadParamException("This member has not been selected"); -} ->> +%> //{ Fast DDS-Gen extensions module_conversion(ctx, parent, modules, definition_list) ::= << diff --git a/src/main/java/com/eprosima/fastdds/idl/templates/TypesCdrAuxHeaderImpl.stg b/src/main/java/com/eprosima/fastdds/idl/templates/TypesCdrAuxHeaderImpl.stg index 4f2ab62d..8f597fe6 100644 --- a/src/main/java/com/eprosima/fastdds/idl/templates/TypesCdrAuxHeaderImpl.stg +++ b/src/main/java/com/eprosima/fastdds/idl/templates/TypesCdrAuxHeaderImpl.stg @@ -15,6 +15,7 @@ group TypesCdrAuxHeader; import "eprosima.stg" +import "com/eprosima/fastcdr/idl/templates/FastCdrCommon.stg" main(ctx, definitions, extensions) ::= << $fileHeader(ctx=ctx, file=[ctx.filename, "CdrAux.ipp"], description=["This source file contains some declarations of CDR related functions."])$ @@ -251,12 +252,12 @@ eProsima_user_DllExport size_t calculate_serialized_size( switch (data._d()) { - $union.membersDefaultAtEnd:{ member | $if(member.printable)$$member.labels:{ label |case $label$:}; separator="\n"$ + $union.members :{ member | + $member.labels:{ label |case $label$:}; separator="\n"$ $if(member.default)$default:$endif$ calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId($if(union.annotationMutable)$$member.id$$else$$member.index$$endif$), data.$member.name$(), current_alignment); break; - $endif$ }; separator="\n"$ $if(!union.defaultMember)$ default: @@ -291,12 +292,11 @@ eProsima_user_DllExport void serialize( switch (data._d()) { - $union.membersDefaultAtEnd:{ member | $if(member.printable)$ + $union.members :{ member | $member.labels:{ label |case $label$:}; separator="\n"$ $if(member.default)$default:$endif$ scdr << eprosima::fastcdr::MemberId($if(union.annotationMutable)$$member.id$$else$$member.index$$endif$) << data.$member.name$(); break; - $endif$ }; separator="\n"$ $if(!union.defaultMember)$ default: @@ -322,34 +322,52 @@ eProsima_user_DllExport void deserialize( [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool { bool ret_value = true; - switch (mid.id) + if (0 == mid.id) { - case 0: - dcdr \>> data._d(); - break; - default: - switch (data._d()) - { - $union.membersDefaultAtEnd:{ member | $if(member.printable)$ - $member.labels:{ label |case $label$:}; separator="\n"$ - $if(member.default)$default:$endif$ - $if(union.annotationMutable || member.annotationOptional)$ - if (mid != $member.id$) - { - throw BadParamException("Deserializing union member $member.name$ the MemberId doesn't match"); - \} - $endif$ - dcdr \>> data.$member.name$(); - break; - $endif$ - }; separator="\n"$ - $if(!union.defaultMember)$ - default: + $union.discriminator.typecode.cppTypename$ discriminator; + dcdr \>> discriminator; + + switch (discriminator) + { + $union.members:{ member | + $member.labels:{ label |case $label$:}; separator="\n"$ + $if(member.default)$default:$endif$ + { + $member_type_declaration(member)$ $member.name$_value$member_default_init(member)$; + data.$member.name$(std::move($member.name$_value)); + data._d(discriminator); break; + \} + }; separator="\n"$ + $if(!union.defaultMember)$ + default: + data._default(); + break; + $endif$ + } + } + else + { + switch (data._d()) + { + $union.members :{ member | + $member.labels:{ label |case $label$:}; separator="\n"$ + $if(member.default)$default:$endif$ + $if(union.annotationMutable || member.annotationOptional)$ + if (mid != $member.id$) + { + throw BadParamException("Deserializing union member $member.name$ the MemberId doesn't match"); + \} $endif$ - } - $if(!union.annotationMutable)$ret_value = false;$endif$ - break; + dcdr \>> data.$member.name$(); + break; + }; separator="\n"$ + $if(!union.defaultMember)$ + default: + break; + $endif$ + } + $if(!union.annotationMutable)$ret_value = false;$endif$ } return ret_value; }); diff --git a/thirdparty/dds-types-test b/thirdparty/dds-types-test index 604460f6..ef234fb8 160000 --- a/thirdparty/dds-types-test +++ b/thirdparty/dds-types-test @@ -1 +1 @@ -Subproject commit 604460f658b0721cb4a6b5bf19bf157e2160676a +Subproject commit ef234fb8071c0a93fee23a40537592df7e1778bc diff --git a/thirdparty/idl-parser b/thirdparty/idl-parser index c5a8f087..f3fdedfe 160000 --- a/thirdparty/idl-parser +++ b/thirdparty/idl-parser @@ -1 +1 @@ -Subproject commit c5a8f087ded0d3decd26e7a89db21b6b0d35563d +Subproject commit f3fdedfeea7958afaf8808447923f886efb3a40e