ardupilot/mk/PX4/Tools/gencpp/scripts/msg.h.template

310 lines
9.5 KiB
Plaintext

@###############################################
@#
@# ROS message source code generation for C++
@#
@# EmPy template for generating <msg>.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<ContainerAllocator>'%(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 <string>
#include <vector>
#include <map>
#include <ros/types.h>
#include <ros/serialization.h>
#include <ros/builtin_message_traits.h>
#include <ros/message_operations.h>
@##############################
@# Includes for dependencies
@##############################
@{
for field in spec.parsed_fields():
if (not field.is_builtin):
if (field.is_header):
print('#include <std_msgs/Header.h>')
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 <class ContainerAllocator>
struct @(spec.short_name)_
{
typedef @(spec.short_name)_<ContainerAllocator> 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)<ContainerAllocator> > Ptr;
typedef boost::shared_ptr< @(cpp_full_name)<ContainerAllocator> const> ConstPtr;
}; // struct @(cpp_class)
@# Typedef of template instance using std::allocator
typedef @(cpp_full_name)<std::allocator<void> > @(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<typename ContainerAllocator> const @(gencpp.msg_type_to_cpp(c.type))
@(spec.short_name)_<ContainerAllocator>::@(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<typename ContainerAllocator>
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 <class ContainerAllocator>
@#struct IsFixedSize<@(cpp_full_name_with_alloc) >:: @(dir(spec)) ? "TrueType" ! "FalseType") { };
@#template <class ContainerAllocator>
@#struct IsFixedSize<@(cpp_full_name_with_alloc) const >:: @(dir(spec)) ? "TrueType" ! "FalseType") { };
@# Binary traits
@[for k, v in bool_traits.items()]@
template <class ContainerAllocator>
struct @(k)< @(cpp_full_name_with_alloc) >
: @(booltotype(v))
{ };
template <class ContainerAllocator>
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<class ContainerAllocator>
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<class ContainerAllocator> struct Serializer< @(cpp_full_name_with_alloc) >
{
@[if spec.parsed_fields()]@
template<typename Stream, typename T> inline static void allInOne(Stream& stream, T m)
{
@[for field in spec.parsed_fields()]@
stream.next(m.@(field.name));
@[end for]@
}
@[else]@
template<typename Stream, typename T> 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<class ContainerAllocator>
struct Printer< @(cpp_full_name_with_alloc) >
{
@[if spec.parsed_fields()]@
template<typename Stream> 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<typename Stream> 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