#ifndef {{ spec.package|upper }}_MESSAGE_{{ spec.short_name|upper }} #define {{ spec.package|upper }}_MESSAGE_{{ spec.short_name|upper }} #include #include #include #include #include #include #include {% for field in spec.fields %} {%- if not is_intrinsic_type(field) %} #include <{{ field.package }}/{{ field.field_type }}.h> {%- endif -%} {%- endfor %} namespace {{ spec.package }} { template struct {{ spec.short_name }}_ { typedef {{ spec.short_name }}_ Type; {#- Constructors and initializer lists #} {%- if spec.fields|length > 0 %} {{ spec.short_name }}_() : {{ spec.fields|map(attribute="name")|join('()\n , ') }}() { } {{ spec.short_name }}_(const ContainerAllocator& _alloc) : {{ spec.fields|map(attribute="name")|join('(_alloc)\n , ') }}(_alloc) { (void)_alloc; } {%- else %} {{ spec.short_name }}_() { } {{ spec.short_name }}_(const ContainerAllocator& _alloc) { (void)_alloc; } {%- endif %} {#- Each variable field of the message type is defined here #} {%- for field in spec.fields %} {# This section is extremely verbose with repeated elements. Trade-off here between repetition and ability to reason about what code should be generated. #} {%- if is_vector(field) %} {%- if is_intrinsic_type(field) %} typedef std::vector<{{ field.field_type|typename_conversion }}, typename std::allocator_traits::template rebind_alloc<{{ field.field_type|typename_conversion }}>> _{{ field.name }}_type; {%- else %} typedef std::vector<::{{ field.package }}::{{ field.field_type }}_, typename std::allocator_traits::template rebind_alloc<::{{ field.package }}::{{ field.field_type }}_>> _{{ field.name }}_type; {%- endif %} {%- elif is_fixed_array(field) %} {%- if is_intrinsic_type(field) %} typedef boost::array<{{ field.field_type|typename_conversion }}, {{ field|fixed_size_array_size }}> _{{ field.name }}_type; {%- else %} typedef boost::array<::{{ field.package }}::{{ field.field_type }}_, {{ field|fixed_size_array_size }}> _{{ field.name }}_type; {%- endif %} {%- else %} {%- if is_intrinsic_type(field) %} typedef {{ field.field_type|typename_conversion }} _{{ field.name }}_type; {%- else %} typedef ::{{ field.package }}::{{ field.field_type }}_ _{{ field.name }}_type; {%- endif %} {%- endif %} _{{ field.name }}_type {{ field.name }}; {%- endfor %} {# Numeric constant fields (like enums ) are each defined here #} {%- if spec.constants|length > 0 %} enum { {%- for constant in spec.constants %} {%- if constant.constant_type in ['byte', 'int8', 'int16', 'int32', 'int64', 'char'] %} {{ constant.name }} = {{ constant.constant_value }}, {%- elif constant.constant_type in ['uint8', 'uint16', 'uint32', 'uint64'] %} {{ constant.name }} = {{ constant.constant_value }}u, {%- endif -%} {%- endfor %} }; {%- endif %} {#- Non-numeric constant fields are declared here, but defined below outside of the class definition. #} {%- for constant in spec.constants %} {%- if constant.constant_type not in ['byte', 'int8', 'int16', 'int32', 'int64', 'char', 'uint8', 'uint16', 'uint32', 'uint64'] %} static const {{ constant.constant_type|typename_conversion }} {{ constant.name }}; {%- endif %} {%- endfor %} typedef boost::shared_ptr< ::{{ spec.package }}::{{ spec.short_name }}_> Ptr; typedef boost::shared_ptr< ::{{ spec.package }}::{{ spec.short_name }}_ const> ConstPtr; }; // struct {{ spec.short_name }}_ typedef ::{{ spec.package }}::{{ spec.short_name }}_> {{ spec.short_name }}; typedef boost::shared_ptr< ::{{ spec.package }}::{{ spec.short_name }}> {{ spec.short_name }}Ptr; typedef boost::shared_ptr< ::{{ spec.package }}::{{ spec.short_name }} const> {{ spec.short_name }}ConstPtr; // constants requiring out of line definition {%- for constant in spec.constants %} {%- if constant.constant_type not in ['byte', 'int8', 'int16', 'int32', 'int64', 'char', 'uint8', 'uint16', 'uint32', 'uint64'] %} template const {{ constant.constant_type|typename_conversion }} {{ spec.short_name }}_::{{ constant.name }} = {%- if constant.constant_type == 'string' %} u8{{ constant.constant_value }} {%- elif constant.constant_type == 'bool' %} int({{ constant.constant_value|lower }}) {%- else %} {{ constant.constant_value }} {% endif -%} ; {% endif -%} {%- endfor %} template std::ostream& operator<<(std::ostream& s, const ::{{ spec.package }}::{{ spec.short_name }}_ & v) { ros::message_operations::Printer< ::{{ spec.package }}::{{ spec.short_name }}_ >::stream(s, "", v); return s; } template bool operator==(const ::{{ spec.package }}::{{ spec.short_name }}_ & lhs, const ::{{ spec.package }}::{{ spec.short_name }}_ & rhs) { return {%- for field in spec.fields %} lhs.{{ field.name }} == rhs.{{ field.name }} && {%- endfor %} true; } template bool operator!=(const ::{{ spec.package }}::{{ spec.short_name }}_ & lhs, const ::{{ spec.package }}::{{ spec.short_name }}_ & rhs) { return !(lhs == rhs); } } // namespace {{ spec.package }} namespace ros { namespace message_traits { template struct IsMessage< ::{{ spec.package }}::{{ spec.short_name }}_> : TrueType { }; template struct IsMessage< ::{{ spec.package }}::{{ spec.short_name }}_ const> : TrueType { }; template struct IsFixedSize< ::{{ spec.package }}::{{ spec.short_name }}_> : {% if is_fixed_length(spec) -%} TrueType {% else -%} FalseType {% endif -%} { }; template struct IsFixedSize< ::{{ spec.package }}::{{ spec.short_name }}_ const> : {% if is_fixed_length(spec) -%} TrueType {% else -%} FalseType {% endif -%} { }; template struct HasHeader< ::{{ spec.package }}::{{ spec.short_name }}_> : {% if has_header(spec) -%} TrueType {% else -%} FalseType {% endif -%} { }; template struct HasHeader< ::{{ spec.package }}::{{ spec.short_name }}_ const> : {% if has_header(spec) -%} TrueType {% else -%} FalseType {% endif -%} { }; template struct MD5Sum< ::{{ spec.package }}::{{ spec.short_name }}_> { static constexpr char const * value() { return "{{ spec.md5sum_first }}{{ spec.md5sum_second }}"; } static const char* value(const ::{{ spec.package }}::{{ spec.short_name }}_&) { return value(); } static const uint64_t static_value1 = 0x{{ spec.md5sum_first }}ULL; static const uint64_t static_value2 = 0x{{ spec.md5sum_second }}ULL; }; template struct DataType< ::{{ spec.package }}::{{ spec.short_name }}_> { static constexpr char const* value() { return "{{ spec.package }}/{{ spec.short_name }}"; } static const char* value(const ::{{ spec.package }}::{{ spec.short_name }}_&) { return value(); } }; template struct Definition< ::{{ spec.package }}::{{ spec.short_name }}_> { static constexpr char const* value() { return "{{ spec.description }}"; } static const char* value(const ::{{ spec.package }}::{{ spec.short_name }}_&) { return value(); } }; } // namespace message_traits } // namespace ros namespace ros { namespace serialization { template struct Serializer< ::{{ spec.package }}::{{ spec.short_name }}_> { {%- if spec.fields|count > 0 %} template inline static void allInOne(Stream& stream, T m) { {%- for field in spec.fields %} stream.next(m.{{ field.name }}); {%- endfor %} } {%- else %} template inline static void allInOne(Stream&, T) {} {%- endif %} ROS_DECLARE_ALLINONE_SERIALIZER }; // struct {{ spec.short_name }}_ } // namespace serialization } // namespace ros namespace ros { namespace message_operations { template struct Printer< ::{{ spec.package }}::{{ spec.short_name }}_> { {%- if spec.fields|count > 0 %} template static void stream(Stream& s, const std::string& indent, const ::{{ spec.package }}::{{ spec.short_name }}_& v) { {%- for field in spec.fields %} {%- if is_vector(field) %} s << indent << "{{ field.name }}[]" << std::endl; for (size_t i = 0; i < v.{{ field.name }}.size(); ++i) { s << indent << " {{ field.name }}[" << i << "]: "; {%- if not is_intrinsic_type(field) %} s << std::endl; s << indent; Printer<::{{ field.package }}::{{ field.field_type}}>::stream(s, indent + " ", v.{{ field.name }}[i]); {%- else %} Printer<{{ field.field_type|typename_conversion }}>::stream(s, indent + " ", v.{{ field.name }}[i]); {%- endif %} } {%- else %} s << indent << "{{ field.name }}: "; {%- if is_intrinsic_type(field) %} Printer< {{ field.field_type|typename_conversion }}>::stream(s, indent + " ", v.{{ field.name }}); {%- else %} s << std::endl; Printer< ::{{ field.package }}::{{ field.field_type }}_>::stream(s, indent + " ", v.{{ field.name }}); {%- endif %} {%- endif %} {%- endfor %} } {%- else %} template static void stream(Stream& s, const std::string& indent, const ::{{ spec.package }}::{{ spec.short_name }}_& v) {} {%- endif %} }; } // namespace message_operations } // namespace ros #endif // {{ spec.package|upper }}_MESSAGE_{{ spec.short_name|upper }}