Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 2 additions & 42 deletions rosidl_generator_cpp/resource/msg__struct.hpp.em
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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<typename %s::iterator, %s>(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<typename %s::iterator, %s>(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]@
Expand Down
51 changes: 48 additions & 3 deletions rosidl_generator_cpp/rosidl_generator_cpp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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<unsigned char>({value})'

if type_.typename in [
'short', 'unsigned short',
'char', 'wchar',
'wchar',
'double', 'long double',
'octet',
'int8', 'uint8',
'int16', 'uint16',
]:
Expand Down Expand Up @@ -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