@############################################### @# @# ROS message source code generation for C++ @# @# EmPy template for generating .h files @# @############################################### @# Start of Template @# @# Context: @# - file_name_in (String) Source file @# - spec (msggen.MsgSpec) Parsed specification of the .msg file @# - md5sum (String) MD5Sum of the .msg specification @############################################### /* Software License Agreement (BSD License) * * Copyright (c) 2011, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of Willow Garage, Inc. nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Auto-generated by genmsg_cpp from file @file_name_in * */ @{ import genmsg.msgs import gencpp cpp_namespace = '::%s::'%(spec.package) # TODO handle nested namespace cpp_class = '%s_'%spec.short_name cpp_full_name = '%s%s'%(cpp_namespace,cpp_class) cpp_full_name_with_alloc = '%s'%(cpp_full_name) cpp_msg_definition = gencpp.escape_message_definition(msg_definition) }@ #ifndef @(spec.package.upper())_MESSAGE_@(spec.short_name.upper())_H #define @(spec.package.upper())_MESSAGE_@(spec.short_name.upper())_H @############################## @# Generic Includes @############################## #include #include #include #include #include #include #include @############################## @# Includes for dependencies @############################## @{ for field in spec.parsed_fields(): if (not field.is_builtin): if (field.is_header): print('#include ') else: (package, name) = genmsg.names.package_resource_name(field.base_type) package = package or spec.package # convert '' to package print('#include <%s/%s.h>'%(package, name)) }@ namespace @(spec.package) { template struct @(spec.short_name)_ { typedef @(spec.short_name)_ Type; @# constructors (with and without allocator) @[for (alloc_type,alloc_name) in [['',''],['const ContainerAllocator& ','_alloc']]]@ @(spec.short_name)_(@(alloc_type+alloc_name)) @# Write initializer list @('\n '.join(gencpp.generate_initializer_list(spec, alloc_name != '' )))@ { @# Fixed length arrays @('\n '.join(gencpp.generate_fixed_length_assigns(spec, alloc_name != '', '%s::'%(spec.package))))@ } @[end for] @[for field in spec.parsed_fields()] @{cpp_type = gencpp.msg_type_to_cpp(field.type)}@ typedef @(cpp_type) _@(field.name)_type; _@(field.name)_type @(field.name); @[end for] @# Constants @[for constant in spec.constants]@ @[if (constant.type in ['byte', 'int8', 'int16', 'int32', 'int64', 'char'])]@ enum { @(constant.name) = @(int(constant.val)) }; @[elif (constant.type in ['uint8', 'uint16', 'uint32', 'uint64'])]@ enum { @(constant.name) = @(int(constant.val))u }; @[else]@ static const @(gencpp.msg_type_to_cpp(constant.type)) @(constant.name); @[end if]@ @[end for] @# Shared pointer typedefs typedef boost::shared_ptr< @(cpp_full_name) > Ptr; typedef boost::shared_ptr< @(cpp_full_name) const> ConstPtr; }; // struct @(cpp_class) @# Typedef of template instance using std::allocator typedef @(cpp_full_name) > @(spec.short_name); @# Shared pointer typedefs typedef boost::shared_ptr< @(cpp_namespace+spec.short_name) > @(spec.short_name)Ptr; typedef boost::shared_ptr< @(cpp_namespace+spec.short_name) const> @(spec.short_name)ConstPtr; // constants requiring out of line definition @[for c in spec.constants] @[if c.type not in ['byte', 'int8', 'int16', 'int32', 'int64', 'char', 'uint8', 'uint16', 'uint32', 'uint64']] template const @(gencpp.msg_type_to_cpp(c.type)) @(spec.short_name)_::@(c.name) = @[if c.type == 'string'] "@(gencpp.escape_string(c.val))" @[elif c.type == 'bool'] @(int(c.val)) @[else] @c.val @[end if] ; @[end if] @[end for] @# Printer template std::ostream& operator<<(std::ostream& s, const @(cpp_full_name_with_alloc) & v) { ros::message_operations::Printer< @(cpp_full_name_with_alloc) >::stream(s, "", v); return s; } @# End of namespace } // namespace @(spec.package) @# Message Traits namespace ros { namespace message_traits { @{ bool_traits = dict(IsMessage=True, IsFixedSize=gencpp.is_fixed_length(spec, msg_context, search_path), HasHeader=spec.has_header(), ) def booltotype(b): return "TrueType" if b else "FalseType" } // BOOLTRAITS @bool_traits // @search_path @# TODO // !!!!!!!!!!! @(dir(spec)) @#if spec.is_fixed_length(): @# traits = traits.append('IsFixedSize') @#template @#struct IsFixedSize<@(cpp_full_name_with_alloc) >:: @(dir(spec)) ? "TrueType" ! "FalseType") { }; @#template @#struct IsFixedSize<@(cpp_full_name_with_alloc) const >:: @(dir(spec)) ? "TrueType" ! "FalseType") { }; @# Binary traits @[for k, v in bool_traits.items()]@ template struct @(k)< @(cpp_full_name_with_alloc) > : @(booltotype(v)) { }; template struct @(k)< @(cpp_full_name_with_alloc) const> : @(booltotype(v)) { }; @[end for]@ @# String traits @[for trait_class,trait_value in [['MD5Sum', md5sum], ['DataType', spec.full_name], ['Definition', cpp_msg_definition]]]@ template struct @(trait_class)< @(cpp_full_name_with_alloc) > { static const char* value() { return "@(trait_value)"; } static const char* value(const @(cpp_full_name_with_alloc)&) { return value(); } @{ if trait_class == 'MD5Sum': iter_count = int(len(trait_value) / 16) for i in range(0, iter_count): start = i*16 print(' static const uint64_t static_value%s = 0x%sULL;'%((i+1), trait_value[start:start+16])) }@ }; @[end for]@ @# End of traits } // namespace message_traits } // namespace ros @# Serialization namespace ros { namespace serialization { template struct Serializer< @(cpp_full_name_with_alloc) > { @[if spec.parsed_fields()]@ template inline static void allInOne(Stream& stream, T m) { @[for field in spec.parsed_fields()]@ stream.next(m.@(field.name)); @[end for]@ } @[else]@ template inline static void allInOne(Stream&, T) {} @[end if]@ ROS_DECLARE_ALLINONE_SERIALIZER; }; // struct @(cpp_class) } // namespace serialization } // namespace ros @# Message Operations namespace ros { namespace message_operations { @# Printer operation template struct Printer< @(cpp_full_name_with_alloc) > { @[if spec.parsed_fields()]@ template static void stream(Stream& s, const std::string& indent, const @(cpp_full_name_with_alloc)& v) { @# todo, change this stuff below into proper EmPy syntax @{ for field in spec.parsed_fields(): cpp_type = gencpp.msg_type_to_cpp(field.base_type) if (field.is_array): print(' s << indent << "%s[]" << std::endl;'%(field.name)) print(' for (size_t i = 0; i < v.%s.size(); ++i)'%(field.name)) print(' {') print(' s << indent << " %s[" << i << "]: ";'%(field.name)) indent_increment = ' ' if (not field.is_builtin): print(' s << std::endl;') print(' s << indent;') indent_increment = ' '; print(' Printer<%s>::stream(s, indent + "%s", v.%s[i]);'%(cpp_type, indent_increment, field.name)) print(' }') else: print(' s << indent << "%s: ";'%(field.name)) indent_increment = ' ' if (not field.is_builtin or field.is_array): print(' s << std::endl;') print(' Printer<%s>::stream(s, indent + "%s", v.%s);'%(cpp_type, indent_increment, field.name)) }@ } @[else]@ template static void stream(Stream&, const std::string&, const @(cpp_full_name_with_alloc)&) {} @[end if]@ }; } // namespace message_operations } // namespace ros #endif // @(spec.package.upper())_MESSAGE_@(spec.short_name.upper())_H