diff --git a/rosidl_generator_cpp/resource/msg__struct.hpp.em b/rosidl_generator_cpp/resource/msg__struct.hpp.em index 6e583888f..867b8c624 100644 --- a/rosidl_generator_cpp/resource/msg__struct.hpp.em +++ b/rosidl_generator_cpp/resource/msg__struct.hpp.em @@ -5,6 +5,8 @@ from rosidl_generator_cpp import escape_string from rosidl_generator_cpp import escape_wstring from rosidl_generator_cpp import msg_type_to_cpp from rosidl_generator_cpp import MSG_TYPE_TO_CPP +from rosidl_generator_cpp import generate_zero_string +from rosidl_generator_cpp import generate_default_string from rosidl_parser.definition import AbstractNestedType from rosidl_parser.definition import AbstractString from rosidl_parser.definition import AbstractWString @@ -108,48 +110,6 @@ struct @(message.structure.namespaced_type.name)_ # http://design.ros2.org/articles/generated_interfaces_cpp.html#constructors # for a detailed explanation of the different _init parameters. init_list, alloc_list, member_list = create_init_alloc_and_member_lists(message) - -def generate_default_string(membset): - from rosidl_generator_cpp import msg_type_only_to_cpp - from rosidl_generator_cpp import msg_type_to_cpp - strlist = [] - for member in membset.members: - if member.default_value is not None: - if member.num_prealloc > 0: - strlist.append('this->%s.resize(%d);' % (member.name, member.num_prealloc)) - if isinstance(member.default_value, list): - if all(v == member.default_value[0] for v in member.default_value): - # Specifying type for std::fill because of MSVC 14.12 warning about casting 'const int' to smaller types (C4244) - # For more info, see https://github.com/ros2/rosidl/issues/309 - # TODO(jacobperron): Investigate reason for build warnings on Windows - # TODO(jacobperron): Write test case for this path of execution - strlist.append('std::fill(this->%s.begin(), this->%s.end(), %s);' % (msg_type_to_cpp(member.type), msg_type_only_to_cpp(member.type), member.name, member.name, member.default_value[0])) - else: - for index, val in enumerate(member.default_value): - strlist.append('this->%s[%d] = %s;' % (member.name, index, val)) - else: - strlist.append('this->%s = %s;' % (member.name, member.default_value)) - - return strlist - -def generate_zero_string(membset, fill_args): - from rosidl_generator_cpp import msg_type_only_to_cpp - from rosidl_generator_cpp import msg_type_to_cpp - strlist = [] - for member in membset.members: - if isinstance(member.zero_value, list): - if member.num_prealloc > 0: - strlist.append('this->%s.resize(%d);' % (member.name, member.num_prealloc)) - if member.zero_need_array_override: - strlist.append('this->%s.fill(%s{%s});' % (member.name, msg_type_only_to_cpp(member.type), fill_args)) - else: - # Specifying type for std::fill because of MSVC 14.12 warning about casting 'const int' to smaller types (C4244) - # For more info, see https://github.com/ros2/rosidl/issues/309 - # TODO(jacobperron): Investigate reason for build warnings on Windows - strlist.append('std::fill(this->%s.begin(), this->%s.end(), %s);' % (msg_type_to_cpp(member.type), msg_type_only_to_cpp(member.type), member.name, member.name, member.zero_value[0])) - else: - strlist.append('this->%s = %s;' % (member.name, member.zero_value)) - return strlist }@ explicit @(message.structure.namespaced_type.name)_(rosidl_runtime_cpp::MessageInitialization _init = rosidl_runtime_cpp::MessageInitialization::ALL) @[if init_list]@ diff --git a/rosidl_generator_cpp/rosidl_generator_cpp/__init__.py b/rosidl_generator_cpp/rosidl_generator_cpp/__init__.py index 85db597c7..a87092274 100644 --- a/rosidl_generator_cpp/rosidl_generator_cpp/__init__.py +++ b/rosidl_generator_cpp/rosidl_generator_cpp/__init__.py @@ -56,7 +56,7 @@ def prefix_with_bom_if_necessary(content: str) -> str: MSG_TYPE_TO_CPP = { 'boolean': 'bool', 'octet': 'unsigned char', # TODO change to std::byte with C++17 - 'char': 'unsigned char', + 'char': 'unsigned char', # TODO change to char8_t with C++20 'wchar': 'char16_t', 'float': 'float', 'double': 'double', @@ -196,11 +196,15 @@ def primitive_value_to_cpp(type_, value): if type_.typename == 'boolean': return 'true' if value else 'false' + if type_.typename in [ + 'char', 'octet' + ]: + return f'static_cast({value})' + if type_.typename in [ 'short', 'unsigned short', - 'char', 'wchar', + 'wchar', 'double', 'long double', - 'octet', 'int8', 'uint8', 'int16', 'uint16', ]: @@ -343,3 +347,44 @@ def add_member(self, member): member_list.append(commonset) return init_list, alloc_list, member_list + + +def generate_default_string(membset: list) -> list[str]: + strlist: list[str] = [] + for member in membset.members: + if member.default_value is not None: + if member.num_prealloc > 0: + strlist.append('this->%s.resize(%d);' % (member.name, member.num_prealloc)) + if isinstance(member.default_value, list): + if all(v == member.default_value[0] for v in member.default_value): + strlist.append( + 'std::fill(this->%s.begin(), this->%s.end(), %s);' % ( + member.name, + member.name, + member.default_value[0] + ) + ) + else: + for index, val in enumerate(member.default_value): + strlist.append('this->%s[%d] = %s;' % (member.name, index, val)) + else: + strlist.append('this->%s = %s;' % (member.name, member.default_value)) + + return strlist + + +def generate_zero_string(membset: list, fill_args: str) -> list[str]: + strlist: list[str] = [] + for member in membset.members: + if isinstance(member.zero_value, list): + if member.num_prealloc > 0: + strlist.append('this->%s.resize(%d);' % (member.name, member.num_prealloc)) + if member.zero_need_array_override: + strlist.append('this->%s.fill(%s{%s});' % ( + member.name, msg_type_only_to_cpp(member.type), fill_args)) + else: + strlist.append('std::fill(this->%s.begin(), this->%s.end(), %s);' % ( + member.name, member.name, member.zero_value[0])) + else: + strlist.append('this->%s = %s;' % (member.name, member.zero_value)) + return strlist