Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement @optional annotation #4364

Open
wants to merge 158 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 129 commits
Commits
Show all changes
158 commits
Select commit Hold shift + click to select a range
2460409
updated test
tmayoff Nov 22, 2023
c5a6265
start on rough implementation
tmayoff Nov 22, 2023
2067e9d
todo
tmayoff Nov 22, 2023
17ddd27
ValueReade/Writer generation
tmayoff Nov 22, 2023
ba1428b
fixed build errors
tmayoff Nov 22, 2023
ccf9455
add gtest to optional test
tmayoff Nov 25, 2023
6be278f
Added support for serialization functions
tmayoff Nov 25, 2023
1794a2d
extended tests
tmayoff Nov 25, 2023
6f44dc7
fixed lint
tmayoff Nov 25, 2023
00f998b
Added another optional test
tmayoff Nov 25, 2023
801a714
^
tmayoff Nov 25, 2023
734cc57
Merge branch 'master' into optional
tmayoff Nov 27, 2023
5595efc
add googletest to mpc
tmayoff Dec 3, 2023
4762462
mpc options
tmayoff Dec 3, 2023
c86171c
Fixed test, and final code gen
tmayoff Dec 3, 2023
bfed4f5
use 0 not nullptr
tmayoff Dec 3, 2023
d549aec
Serialize the has_value of optional
tmayoff Dec 3, 2023
b9e5f0e
proper defaulting of optional
tmayoff Dec 3, 2023
2fd23ed
updates to tests
tmayoff Dec 7, 2023
ecb8241
Merge branch 'master' into optional
tmayoff Jan 13, 2024
ba74b43
Some fixes to CMake setup
tmayoff Jan 18, 2024
8a9968f
Fixed some more copy/paste bugs in cmake build
tmayoff Jan 18, 2024
8844ae6
Fixed tests to work with static libs
tmayoff Jan 18, 2024
7bbe231
Merge branch 'master' into optional
tmayoff Jan 18, 2024
14e7cea
Cleaned up some code, set cmake C++ version
tmayoff Jan 18, 2024
e7745f4
Added a cxx_17 config for MPC
tmayoff Jan 19, 2024
9092820
Add no_cxx17 to configure script
tmayoff Jan 19, 2024
724b1e8
Add opendds_cxx17 to MPC compiler test for optional
tmayoff Jan 19, 2024
3e02ca9
Fixed missing comma
tmayoff Jan 19, 2024
edd1a07
Updated cmake tests to compile IDLs with C++17
tmayoff Jan 19, 2024
9b65b9f
Added to compiler tests
tmayoff Jan 19, 2024
601396d
Merge branch 'optional' of github.com:tmayoff/OpenDDS into optional
tmayoff Jan 19, 2024
eccc5bd
Use typedef in test
tmayoff Jan 19, 2024
3717a57
Fix for generating std::nullopt when it shouldn't
tmayoff Jan 19, 2024
20c4b01
Switched to order of the arguments
tmayoff Jan 19, 2024
e21cd7e
Fixing tests
tmayoff Jan 20, 2024
78756cf
Fixed crash with serialization functions
tmayoff Jan 20, 2024
a64a5c0
Fixed deserialization for real this time, tests passing locally
tmayoff Jan 20, 2024
833361c
Fixed warning
tmayoff Jan 20, 2024
fb94d5e
Updated mpc files
tmayoff Jan 23, 2024
e26eac2
Add optional to tests
tmayoff Jan 23, 2024
fb3987a
Add extra () to some code gen
tmayoff Jan 24, 2024
9019966
Revert "Add extra () to some code gen"
tmayoff Jan 24, 2024
872999a
Merge branch 'master' into optional
tmayoff Jan 24, 2024
b80dbc5
Formatting + consolidated configure script ifs
tmayoff Jan 25, 2024
a04b2a1
Merge branch 'optional' of github.com:tmayoff/OpenDDS into optional
tmayoff Jan 25, 2024
732ce89
Fixed copy-paste bug
tmayoff Jan 25, 2024
88691ef
Removed no_cxx17=0 from MSVC and remove opendds_cxx11 from tests
tmayoff Jan 25, 2024
ee61ec0
Fixed optional test configuration
tmayoff Jan 25, 2024
e12ec8f
Merge branch 'optional' of github.com:tmayoff/OpenDDS into optional
tmayoff Jan 25, 2024
4bc51d3
Update tests/dcps_tests.lst
tmayoff Jan 25, 2024
0b69bde
Bump cache prefix
tmayoff Jan 25, 2024
d36569a
Merge branch 'optional' of github.com:tmayoff/OpenDDS into optional
tmayoff Jan 25, 2024
e1b7c25
Added XCDR2 test,
tmayoff Jan 28, 2024
ee8ce39
Serialization test with comparing bytes
tmayoff Feb 1, 2024
a411e5d
Remove some codegen in favour of Serializer funcs
tmayoff Feb 1, 2024
cf6f834
Added guards to the Serializer functions,
tmayoff Feb 1, 2024
a8c8305
Moved function into #if
tmayoff Feb 1, 2024
a0c5bb2
Reverted to codegen stuff
tmayoff Feb 2, 2024
ba323f2
Merge branch 'master' into optional
tmayoff Feb 2, 2024
0ea901c
Merge branch 'master' into optional
tmayoff Feb 2, 2024
8e87e91
Removed templated >>
tmayoff Feb 2, 2024
9911509
Update configure
tmayoff Feb 3, 2024
418e109
Update dds/idl/langmap_generator.cpp
tmayoff Feb 3, 2024
30c7197
Discard changes to dds/DCPS/Serializer.h
tmayoff Feb 3, 2024
7d9da5c
Merge remote-tracking branch 'origin/main' into optional
tmayoff Feb 16, 2024
227f1a5
Little bit of cleanup
tmayoff Feb 16, 2024
2fb4e94
Added an extra nullcheck
tmayoff Feb 16, 2024
0fd6e2c
Fixed null check
tmayoff Feb 16, 2024
7f2a42a
Added -lc++11 to test .mpc file
tmayoff Feb 16, 2024
03fd220
Add '.value()' to strings
tmayoff Feb 17, 2024
af94ba7
Merge branch 'optional' of github.com:tmayoff/OpenDDS into optional
tmayoff Feb 17, 2024
a7e25e9
Removed include
tmayoff Feb 17, 2024
dae3a07
Merge branch 'master' into optional
tmayoff Feb 17, 2024
067c2db
Moved '.value()' gen
tmayoff Feb 17, 2024
74ad061
Merge branch 'optional' of github.com:tmayoff/OpenDDS into optional
tmayoff Feb 17, 2024
72762e3
null check
tmayoff Feb 17, 2024
6525ac2
Merge branch 'master' into optional
tmayoff Feb 20, 2024
e8ba3f7
Updated mpc build for optional tests
tmayoff Feb 22, 2024
0e9feb6
Merge branch 'optional' of github.com:tmayoff/OpenDDS into optional
tmayoff Feb 22, 2024
da6d465
Find and replace -Config CXX11 with -Config CXX11 -Config CXX17
tmayoff Feb 22, 2024
6fbb6d0
Removed IDL_Files
tmayoff Feb 26, 2024
a15d02a
Removed or fixed CXX17 from CI tests
tmayoff Feb 27, 2024
99f556e
Merge branch 'master' into optional
tmayoff Feb 27, 2024
ddd5693
Merge branch 'main' into optional
tmayoff Mar 1, 2024
31dbf1f
Readded deserialize check
tmayoff Mar 1, 2024
103558f
Fixed mpc builds
tmayoff Mar 1, 2024
47412a6
Merge branch 'master' into optional
tmayoff Mar 4, 2024
985f630
Addressed some review comments
tmayoff Mar 9, 2024
9801a28
Merge branch 'optional' of github.com:tmayoff/OpenDDS into optional
tmayoff Mar 9, 2024
14fdcea
Addressed some more review comments
tmayoff Mar 9, 2024
e8e7bea
Fixed formatting
tmayoff Mar 9, 2024
3234f7d
Fixed XcdrValueWriter
tmayoff Mar 10, 2024
00c7e95
Formatting
tmayoff Mar 10, 2024
920cef2
Added begin/end _optional to PrinterValueWriter in a test
tmayoff Mar 10, 2024
e0805a0
Merge branch 'master' into optional
tmayoff Mar 10, 2024
475eaa3
Merge branch 'master' into optional
tmayoff Mar 11, 2024
cb93a19
Sinplified value_writer generation
tmayoff Mar 15, 2024
05eb15a
Formatted
tmayoff Mar 15, 2024
0e485ca
Removed being_optional from PrinterValueWriter
tmayoff Mar 15, 2024
d659623
Discard changes to dds/DCPS/PrinterValueWriter.h
tmayoff Mar 15, 2024
0d6cdee
Merge branch 'master' into optional
tmayoff Mar 19, 2024
48f9d57
Fixed tests and started with vread
tmayoff Mar 19, 2024
07e4664
Cleanup some optional handling
tmayoff Mar 19, 2024
df12b8d
fixed formatting
tmayoff Mar 19, 2024
67f94d9
Fixed vread generation
tmayoff Mar 19, 2024
05e1afc
Remove include
tmayoff Mar 19, 2024
8ae3dbd
Cleanup and improve the vread for optionals
tmayoff Mar 20, 2024
7b018ed
Remove test REQUIRE_TRUE(false)
tmayoff Mar 20, 2024
25678f3
Removed unused functions
tmayoff Mar 20, 2024
185adad
Formatted
tmayoff Mar 22, 2024
47e284e
Removed duplicate temporary values
tmayoff Mar 29, 2024
eb32ce4
Fixed the member_has_value wrapping
tmayoff Mar 29, 2024
66f63c5
Fixed formatting
tmayoff Mar 29, 2024
bf2b132
Fixed struct compilation
tmayoff Mar 29, 2024
9b384a8
Updated test
tmayoff Mar 29, 2024
96118fd
Removed comments in .idl file
tmayoff Mar 29, 2024
be21157
Cleanup comments, and uneeded changes
tmayoff Mar 29, 2024
68e3d06
Merge branch 'master' into optional
tmayoff Mar 29, 2024
8004336
Fix .gitignore
tmayoff Apr 10, 2024
1a22b27
Merge branch 'refs/heads/main' into optional
tmayoff Apr 18, 2024
d659e7f
Fixed merge issues
tmayoff Apr 18, 2024
4e86f11
Remove commented out merge conflict
tmayoff Apr 18, 2024
97c8f42
minor cleanup
tmayoff Apr 18, 2024
cde05d0
Merge branch 'master' into optional
tmayoff Apr 28, 2024
4ede16e
Merge remote-tracking branch 'upstream/master' into optional
jrw972 Apr 30, 2024
db857d4
Fix bugs in value_*_generator.cpp
jrw972 Apr 30, 2024
82017fd
Fixed KeyOnly tests
tmayoff Apr 30, 2024
0e2c272
Optional non KeyOnly structs use the "tmp" variable rather than
tmayoff Apr 30, 2024
82d06a6
Merge branch 'main' into optional
tmayoff May 9, 2024
68f5f80
Fixed cmake CXX_STD year, and gtest EXPECT_EQ macros
tmayoff May 10, 2024
d574746
Fixed lint issue
tmayoff May 10, 2024
e64c915
linting issue again
tmayoff May 10, 2024
aac7634
linted, for real this time. ran script locally
tmayoff May 10, 2024
af968cf
Merge remote-tracking branch 'upstream/master' into optional
jrw972 May 16, 2024
08ac017
Fix build errors
jrw972 May 16, 2024
93e9d28
Remove test
jrw972 May 16, 2024
7bfb2d8
Integrate test into xcdr test
jrw972 May 17, 2024
5ea4b4a
Merge pull request #7 from jrw972/optional-integration
tmayoff May 24, 2024
fb7a2d7
Remove the add_subdirectory for the now moved optional tests
tmayoff May 24, 2024
b1a68dc
Readd boolean edgecase
tmayoff May 24, 2024
0885928
Use OPENDDS_OPTIONAL_NS
tmayoff May 24, 2024
897ee02
Fixed optional include
tmayoff May 25, 2024
043c46b
Replace std::nullopt with {} for the default value
tmayoff May 25, 2024
6a0d3f9
Add nullopt implementation, this may not work for C++ less than C++11
tmayoff May 25, 2024
abcdc68
removed constexpr
tmayoff May 25, 2024
f3f28f8
Maybe fixed the nullopt
tmayoff May 27, 2024
81cfbf9
const ref nullopt constructor
tmayoff May 27, 2024
2077b6d
Remove nullopt and just default construct the optional
tmayoff May 27, 2024
1d8c53c
Fix integration issues
jrw972 May 28, 2024
64274a3
Fixes for DynamicData implementations
jrw972 May 30, 2024
e905ac9
Fix bad access
jrw972 May 31, 2024
0317ecc
Add news fragment for optional, and updated the docs removing optiona…
tmayoff Jun 3, 2024
7fa6c88
Remove `-Config CXX17`
jrw972 Jun 3, 2024
8ec4721
Apply suggestions from code review
tmayoff Jun 4, 2024
550e85a
Resolved some review comments
tmayoff Jun 4, 2024
8f215bd
Merge branch 'optional' of github.com:tmayoff/OpenDDS into optional
tmayoff Jun 4, 2024
8d5deee
more docs, not done will address https://github.com/OpenDDS/OpenDDS/p…
tmayoff Jun 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
60 changes: 30 additions & 30 deletions .github/workflows/build_and_test.yml

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions MPC/config/opendds_uses_cxx17.mpb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
project: dcpslib {
avoids += no_cxx17
requires += no_opendds_safety_profile
macros += OPENDDS_HAS_CXX17
}
15 changes: 11 additions & 4 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,6 @@ if (!exists $platforminfo{$opts{'host'}} ||
}
print "host system is: $opts{'host'}\n" if $opts{'verbose'};


$opts{'target'} = $opts{'host'} unless $opts{'target'};

if (!exists $platforminfo{$opts{'target'}}) {
Expand Down Expand Up @@ -822,9 +821,17 @@ EOF
}
}

if ($opts{'std'} && $opts{'std'} =~ /(0x|11|1y|14|1z|17|2a|20|2b|23)$/) {
push(@{$opts{'features'}}, 'no_cxx11=0');
print "Compiler has >= C++11 support\n" if $opts{'verbose'};
if ($opts{'std'}) {
my $cpp17 = qr/(17|2a|20|2b|23)/;
if ($opts{'std'} =~ /(0x|11|1y|14|1z|$cpp17)$/) {
push(@{$opts{'features'}}, 'no_cxx11=0');
print "Compiler has >= C++11 support\n" if $opts{'verbose'};
}

if ($opts{'std'} =~ /$cpp17$/) {
push(@{$opts{'features'}}, 'no_cxx17=0');
print "Compiler has >= C++17 support\n" if $opts{'verbose'};
}
}
}
}
Expand Down
7 changes: 5 additions & 2 deletions dds/idl/dds_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ string type_to_default_array(const std::string& indent, AST_Type* type, const st
}

string type_to_default(const std::string& indent, AST_Type* type, const string& name,
bool is_anonymous, bool is_union)
bool is_anonymous, bool is_union, bool is_optional)
{
AST_Type* actual_type = resolveActualType(type);
Classification fld_cls = classify(actual_type);
Expand All @@ -409,7 +409,10 @@ string type_to_default(const std::string& indent, AST_Type* type, const string&
pre = "(";
post = ")";
}
if (fld_cls & (CL_STRUCTURE | CL_UNION)) {

if (is_optional) {
return indent + name + " = std::nullopt;\n";
} else if (fld_cls & (CL_STRUCTURE | CL_UNION)) {
return indent + "set_default(" + name + (is_union ? "()" : "") + ");\n";
} else if (fld_cls & CL_ARRAY) {
return type_to_default_array(
Expand Down
2 changes: 1 addition & 1 deletion dds/idl/dds_generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,7 @@ inline std::string bounded_arg(AST_Type* type)
}

std::string type_to_default(const std::string& indent, AST_Type* type,
const std::string& name, bool is_anonymous = false, bool is_union = false);
const std::string& name, bool is_anonymous = false, bool is_union = false, bool is_optional = false);

inline
void generateBranchLabels(AST_UnionBranch* branch, AST_Type* discriminator,
Expand Down
6 changes: 6 additions & 0 deletions dds/idl/dynamic_data_adapter_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,12 @@ namespace {
} else {
value += (use_cxx11 ? "_" : "") + cpp_field_name;
}

if (field != 0) {
const bool is_optional = be_global->is_optional(field);
if (is_optional) value += ".value()";
}

generate_op(4, set, field_type, type_name, op_type, is_complex,
value + extra_access, rc_dest);
if (union_node && set) {
Expand Down
7 changes: 6 additions & 1 deletion dds/idl/langmap_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1476,7 +1476,12 @@ struct Cxx11Generator : GeneratorBase {
}
}

const std::string lang_field_type = generator_->map_type(field);
const bool is_optional = be_global->is_optional(field);
const std::string lang_field_type = is_optional ? "std::optional<" + generator_->map_type(field) + ">" : generator_->map_type(field);
if (is_optional) {
be_global->add_include("<optional>", BE_GlobalData::STREAM_LANG_H);
}

const std::string assign_pre = "{ _" + af.name_ + " = ",
assign = assign_pre + "val; }\n",
move = assign_pre + "std::move(val); }\n",
Expand Down
104 changes: 84 additions & 20 deletions dds/idl/marshal_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1571,40 +1571,57 @@ namespace {
{
const bool use_cxx11 = be_global->language_mapping() == BE_GlobalData::LANGMAP_CXX11;
const bool is_union_member = prefix == "uni";
const bool is_optional = field != 0 ? be_global->is_optional(field) : false;

AST_Type* const actual_type = resolveActualType(type);
const Classification fld_cls = classify(actual_type);

const string qual = prefix + '.' + insert_cxx11_accessor_parens(name, is_union_member);
const std::string field_name = prefix + '.' + insert_cxx11_accessor_parens(name, is_union_member);
const string qual = prefix + '.' + insert_cxx11_accessor_parens(name, is_union_member)
tmayoff marked this conversation as resolved.
Show resolved Hide resolved
+ (is_optional ? ".value()" : "");

std::string line = "";
if (is_optional) {
line += indent + "primitive_serialized_size_boolean(encoding, size);\n"
+ indent + "if (" + field_name + ") {\n";
}

if (fld_cls & CL_ENUM) {
return indent + "primitive_serialized_size_ulong(encoding, size);\n";
line += indent + "primitive_serialized_size_ulong(encoding, size);\n";
} else if (fld_cls & CL_STRING) {
const string suffix = is_union_member ? "" : ".in()";
const string get_size = use_cxx11 ? (qual + ".size()")
: ("ACE_OS::strlen(" + qual + suffix + ")");
return indent + "primitive_serialized_size_ulong(encoding, size);\n" +

line += indent + "primitive_serialized_size_ulong(encoding, size);\n" +
indent + "size += " + get_size
+ ((fld_cls & CL_WIDE) ? " * char16_cdr_size;\n"
: " + 1;\n");
} else if (fld_cls & CL_PRIMITIVE) {
AST_PredefinedType* const p = dynamic_cast<AST_PredefinedType*>(actual_type);
if (p->pt() == AST_PredefinedType::PT_longdouble) {
// special case use to ACE's NONNATIVE_LONGDOUBLE in CDR_Base.h
return indent +
line += indent +
"primitive_serialized_size(encoding, size, ACE_CDR::LongDouble());\n";
} else {
line += indent + "primitive_serialized_size(encoding, size, " +
getWrapper(qual, actual_type, WD_OUTPUT) + ");\n";
}
return indent + "primitive_serialized_size(encoding, size, " +
getWrapper(qual, actual_type, WD_OUTPUT) + ");\n";
} else if (fld_cls == CL_UNKNOWN) {
return ""; // warning will be issued for the serialize functions
} else { // sequence, struct, union, array
RefWrapper wrapper(type, field_type_name(dynamic_cast<AST_Field*>(field), type),
prefix + "." + insert_cxx11_accessor_parens(name, is_union_member));
prefix + "." + insert_cxx11_accessor_parens(name, is_union_member) + (is_optional ? ".value()" : ""));
wrapper.nested_key_only_ = wrap_nested_key_only;
wrapper.done(&intro);
return indent + "serialized_size(encoding, size, " + wrapper.ref() + ");\n";
line += indent + "serialized_size(encoding, size, " + wrapper.ref() + ");\n";
}

if (is_optional) {
line += indent + "}\n";
}

return line;
}

string findSizeMutableUnion(const string& indent, AST_Decl* node, const string& name, AST_Type* type,
Expand Down Expand Up @@ -1639,6 +1656,7 @@ namespace {
{
const bool use_cxx11 = be_global->language_mapping() == BE_GlobalData::LANGMAP_CXX11;
const bool is_union_member = prefix.substr(3) == "uni";
const bool is_optional = field != 0 ? be_global->is_optional(field) : false;

AST_Type* const actual_type = resolveActualType(type);
const Classification fld_cls = classify(actual_type);
Expand Down Expand Up @@ -1672,6 +1690,10 @@ namespace {
const bool accessor = local.size() > 2 && local.substr(local.size() - 2) == "()";
if (fld_cls & CL_STRING) {
if (!accessor && !use_cxx11) {
if (is_optional) {
local += ".value()";
}

local += ".in()";
}
if ((fld_cls & CL_BOUNDED)) {
Expand All @@ -1688,10 +1710,11 @@ namespace {
}

std::string generate_field_stream(
const std::string& indent, AST_Field* field, const std::string& prefix,
const std::string& indent, AST_Field* field, const std::string& prefix, const std::string& field_name,
bool wrap_nested_key_only, Intro& intro)
{
FieldInfo af(*field);

if (af.anonymous()) {
RefWrapper wrapper(af.type_, af.scoped_type_,
prefix + "." + insert_cxx11_accessor_parens(af.name_));
Expand All @@ -1700,7 +1723,7 @@ namespace {
return "(strm " + wrapper.stream() + ")";
}
return streamCommon(
indent, field, field->local_name()->get_string(), field->field_type(), prefix,
indent, field, field_name, field->field_type(), prefix,
wrap_nested_key_only, intro);
}

Expand Down Expand Up @@ -2475,7 +2498,7 @@ namespace {
cases <<
" case " << id << ": {\n"
" if (!" << generate_field_stream(
indent, field, ">> stru" + value_access, wrap_nested_key_only, intro) << ") {\n";
indent, field, ">> stru" + value_access, field->local_name()->get_string(), wrap_nested_key_only, intro) << ") {\n";
AST_Type* const field_type = resolveActualType(field->field_type());
const Classification fld_cls = classify(field_type);

Expand Down Expand Up @@ -2572,6 +2595,8 @@ namespace {
expr = "";
for (Fields::Iterator i = fields.begin(); i != fields_end; ++i) {
AST_Field* const field = *i;
const bool is_optional = be_global->is_optional(field);

if (expr.size() && exten != extensibilitykind_appendable) {
expr += "\n && ";
}
Expand Down Expand Up @@ -2603,16 +2628,44 @@ namespace {
}
expr +=
" if (reached_end_of_struct) {\n" +
type_to_default(" ", type, stru_field_name, type->anonymous()) +
" } else {\n"
" if (!";
type_to_default(" ", type, stru_field_name, type->anonymous(), false, is_optional) +
" } else {\n";
if (!is_optional) {
expr += " if (!";
}
}

// TODO(tyler) This feels kind of hacky
// Can the optional branch be isolated completely
// Assigns strm value to temporary values
if (is_optional) {
//TODO(tyler) Is there an easier way to deal with strings here
AST_Type* const field_type = resolveActualType(field->field_type());
tmayoff marked this conversation as resolved.
Show resolved Hide resolved
Classification fld_cls = classify(field_type);
const std::string type_name = fld_cls & CL_STRING ? "String" : field->field_type()->full_name();
const std::string has_value_name = field_name + "_has_value";
expr += " bool " + field_name + "_has_value = false;\n";
expr += " strm >> ACE_InputCDR::to_boolean(" + has_value_name + ");\n";
expr += " " + type_name + " " + field_name + "_tmp;\n";
expr += " if (" + has_value_name + " && !";
expr += "(strm >> " + field_name + "_tmp)";
} else {
expr += generate_field_stream(
indent, field, ">> stru" + value_access, field->local_name()->get_string(), wrap_nested_key_only, intro);
}
expr += generate_field_stream(
indent, field, ">> stru" + value_access, wrap_nested_key_only, intro);
if (is_appendable) {
expr += ") {\n"
" return false;\n"
" }\n";

// Copy temporaries to the struct
if (is_optional) {
string stru_field_name = "stru" + value_access + "." + field_name;
if (use_cxx11) {
stru_field_name += "()";
}
expr += " if (" + field_name + "_has_value) " + stru_field_name + " = " + field_name + "_tmp;\n";
}
if (cond.empty()) {
expr +=
" }\n";
Expand Down Expand Up @@ -2756,7 +2809,7 @@ namespace {
" }\n"
" size = 0;\n"
" if (!" << generate_field_stream(
mutable_indent, field, "<< stru" + value_access, wrap_nested_key_only, intro)
mutable_indent, field, "<< stru" + value_access, field->local_name()->get_string(), wrap_nested_key_only, intro)
<< ") {\n"
" return false;\n"
" }\n";
Expand All @@ -2773,14 +2826,25 @@ namespace {
string expr;
for (Fields::Iterator i = fields.begin(); i != fields_end; ++i) {
AST_Field* const field = *i;
const bool is_optional = be_global->is_optional(field);;
if (expr.size()) expr += "\n && ";
const string field_name = field->local_name()->get_string(),
cond = rtpsCustom.getConditional(field_name);
if (!cond.empty()) {
expr += "(!(" + cond + ") || ";
}
expr += generate_field_stream(
indent, field, "<< stru" + value_access, wrap_nested_key_only, intro);

if (is_optional) {
expr += "(strm << ACE_OutputCDR::from_boolean(stru" + value_access + "." + field_name + "().has_value()) && ";
expr += "stru" + value_access + "." + field_name + "().has_value() ? ";
expr += generate_field_stream(
indent, field, "<< stru" + value_access, field_name + ".value", wrap_nested_key_only, intro);
expr += " : true)";
} else {
expr += generate_field_stream(
indent, field, "<< stru" + value_access, field_name, wrap_nested_key_only, intro);
}

if (!cond.empty()) {
expr += ")";
}
Expand Down Expand Up @@ -2841,7 +2905,7 @@ bool marshal_generator::gen_struct(AST_Structure* node,
if (use_cxx11) {
field_name += "()";
}
contents << type_to_default(" ", type, field_name, type->anonymous());
contents << type_to_default(" ", type, field_name, type->anonymous(), false, be_global->is_optional(field));
}
intro.join(be_global->impl_, " ");
be_global->impl_ << contents.str();
Expand Down
16 changes: 13 additions & 3 deletions dds/idl/metaclass_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ namespace {
{
const bool use_cxx11 = be_global->language_mapping() == BE_GlobalData::LANGMAP_CXX11;
const Classification cls = classify(field->field_type());
const std::string fieldName = field->local_name()->get_string();
std::string fieldName = field->local_name()->get_string();

const std::string idl_name = canonical_name(field);
if (cls & CL_SCALAR) {
std::string prefix, suffix;
Expand All @@ -61,6 +62,11 @@ namespace {
} else if (use_cxx11) {
suffix += "()";
}

if (be_global->is_optional(field)) {
fieldName += "().value";
}

const std::string string_to_ptr = use_cxx11 ? "" : ".in()";
be_global->impl_ <<
" if (std::strcmp(field, \"" << idl_name << "\") == 0) {\n"
Expand All @@ -69,8 +75,12 @@ namespace {
" }\n";
be_global->add_include("<cstring>", BE_GlobalData::STREAM_CPP);
} else if (cls & CL_STRUCTURE) {
delegateToNested(idl_name, field,
"&typed." + std::string(use_cxx11 ? "_" : "") + fieldName);
std::string fieldAccessor = "&typed." + std::string(use_cxx11 ? "_" : "") + fieldName;
if (be_global->is_optional(field)) {
fieldAccessor += ".value()";
}

delegateToNested(idl_name, field, fieldAccessor);
be_global->add_include("<cstring>", BE_GlobalData::STREAM_CPP);
}
}
Expand Down