00001 /* 00002 * Copyright (C) 2009, Willow Garage, Inc. 00003 * 00004 * Redistribution and use in source and binary forms, with or without 00005 * modification, are permitted provided that the following conditions are met: 00006 * * Redistributions of source code must retain the above copyright notice, 00007 * this list of conditions and the following disclaimer. 00008 * * Redistributions in binary form must reproduce the above copyright 00009 * notice, this list of conditions and the following disclaimer in the 00010 * documentation and/or other materials provided with the distribution. 00011 * * Neither the names of Willow Garage, Inc. nor the names of its 00012 * contributors may be used to endorse or promote products derived from 00013 * this software without specific prior written permission. 00014 * 00015 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00016 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00017 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00018 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00019 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00020 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00021 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00022 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00023 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00024 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00025 * POSSIBILITY OF SUCH DAMAGE. 00026 */ 00027 00028 #ifndef ROSLIB_MESSAGE_TRAITS_H 00029 #define ROSLIB_MESSAGE_TRAITS_H 00030 00031 #include "message_forward.h" 00032 00033 #include <ros/time.h> 00034 00035 #include <string> 00036 #include <boost/utility/enable_if.hpp> 00037 #include <boost/type_traits/remove_const.hpp> 00038 #include <boost/type_traits/remove_reference.hpp> 00039 00040 namespace std_msgs 00041 { 00042 ROS_DECLARE_MESSAGE(Header); 00043 } 00044 00045 #define ROS_IMPLEMENT_SIMPLE_TOPIC_TRAITS(msg, md5sum, datatype, definition) \ 00046 namespace ros \ 00047 { \ 00048 namespace message_traits \ 00049 { \ 00050 template<> struct MD5Sum<msg> \ 00051 { \ 00052 static const char* value() { return md5sum; } \ 00053 static const char* value(const msg&) { return value(); } \ 00054 }; \ 00055 template<> struct DataType<msg> \ 00056 { \ 00057 static const char* value() { return datatype; } \ 00058 static const char* value(const msg&) { return value(); } \ 00059 }; \ 00060 template<> struct Definition<msg> \ 00061 { \ 00062 static const char* value() { return definition; } \ 00063 static const char* value(const msg&) { return value(); } \ 00064 }; \ 00065 } \ 00066 } 00067 00068 00069 namespace ros 00070 { 00071 namespace message_traits 00072 { 00073 00078 struct TrueType 00079 { 00080 static const bool value = true; 00081 typedef TrueType type; 00082 }; 00083 00088 struct FalseType 00089 { 00090 static const bool value = false; 00091 typedef FalseType type; 00092 }; 00093 00098 template<typename M> struct IsSimple : public FalseType {}; 00102 template<typename M> struct IsFixedSize : public FalseType {}; 00106 template<typename M> struct HasHeader : public FalseType {}; 00107 00111 template<typename M> struct IsMessage : public FalseType {}; 00112 00116 template<typename M> 00117 struct MD5Sum 00118 { 00119 static const char* value() 00120 { 00121 return M::__s_getMD5Sum().c_str(); 00122 } 00123 00124 static const char* value(const M& m) 00125 { 00126 return m.__getMD5Sum().c_str(); 00127 } 00128 }; 00129 00133 template<typename M> 00134 struct DataType 00135 { 00136 static const char* value() 00137 { 00138 return M::__s_getDataType().c_str(); 00139 } 00140 00141 static const char* value(const M& m) 00142 { 00143 return m.__getDataType().c_str(); 00144 } 00145 }; 00146 00150 template<typename M> 00151 struct Definition 00152 { 00153 static const char* value() 00154 { 00155 return M::__s_getMessageDefinition().c_str(); 00156 } 00157 00158 static const char* value(const M& m) 00159 { 00160 return m.__getMessageDefinition().c_str(); 00161 } 00162 }; 00163 00168 template<typename M, typename Enable = void> 00169 struct Header 00170 { 00171 static std_msgs::Header* pointer(M& m) { return 0; } 00172 static std_msgs::Header const* pointer(const M& m) { return 0; } 00173 }; 00174 00175 template<typename M> 00176 struct Header<M, typename boost::enable_if<HasHeader<M> >::type > 00177 { 00178 static std_msgs::Header* pointer(M& m) { return &m.header; } 00179 static std_msgs::Header const* pointer(const M& m) { return &m.header; } 00180 }; 00181 00187 template<typename M, typename Enable = void> 00188 struct FrameId 00189 { 00190 static std::string* pointer(M& m) { return 0; } 00191 static std::string const* pointer(const M& m) { return 0; } 00192 }; 00193 00194 template<typename M> 00195 struct FrameId<M, typename boost::enable_if<HasHeader<M> >::type > 00196 { 00197 static std::string* pointer(M& m) { return &m.header.frame_id; } 00198 static std::string const* pointer(const M& m) { return &m.header.frame_id; } 00199 static std::string value(const M& m) { return m.header.frame_id; } 00200 }; 00201 00207 template<typename M, typename Enable = void> 00208 struct TimeStamp 00209 { 00210 static ros::Time* pointer(M& m) { return 0; } 00211 static ros::Time const* pointer(const M& m) { return 0; } 00212 }; 00213 00214 template<typename M> 00215 struct TimeStamp<M, typename boost::enable_if<HasHeader<M> >::type > 00216 { 00217 static ros::Time* pointer(typename boost::remove_const<M>::type &m) { return &m.header.stamp; } 00218 static ros::Time const* pointer(const M& m) { return &m.header.stamp; } 00219 static ros::Time value(const M& m) { return m.header.stamp; } 00220 }; 00221 00225 template<typename M> 00226 inline const char* md5sum() 00227 { 00228 return MD5Sum<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::value(); 00229 } 00230 00234 template<typename M> 00235 inline const char* datatype() 00236 { 00237 return DataType<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::value(); 00238 } 00239 00243 template<typename M> 00244 inline const char* definition() 00245 { 00246 return Definition<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::value(); 00247 } 00248 00252 template<typename M> 00253 inline const char* md5sum(const M& m) 00254 { 00255 return MD5Sum<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::value(m); 00256 } 00257 00261 template<typename M> 00262 inline const char* datatype(const M& m) 00263 { 00264 return DataType<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::value(m); 00265 } 00266 00270 template<typename M> 00271 inline const char* definition(const M& m) 00272 { 00273 return Definition<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::value(m); 00274 } 00275 00279 template<typename M> 00280 inline std_msgs::Header* header(M& m) 00281 { 00282 return Header<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::pointer(m); 00283 } 00284 00288 template<typename M> 00289 inline std_msgs::Header const* header(const M& m) 00290 { 00291 return Header<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::pointer(m); 00292 } 00293 00297 template<typename M> 00298 inline std::string* frameId(M& m) 00299 { 00300 return FrameId<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::pointer(m); 00301 } 00302 00306 template<typename M> 00307 inline std::string const* frameId(const M& m) 00308 { 00309 return FrameId<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::pointer(m); 00310 } 00311 00315 template<typename M> 00316 inline ros::Time* timeStamp(M& m) 00317 { 00318 return TimeStamp<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::pointer(m); 00319 } 00320 00324 template<typename M> 00325 inline ros::Time const* timeStamp(const M& m) 00326 { 00327 return TimeStamp<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::pointer(m); 00328 } 00329 00333 template<typename M> 00334 inline bool isSimple() 00335 { 00336 return IsSimple<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::value; 00337 } 00338 00342 template<typename M> 00343 inline bool isFixedSize() 00344 { 00345 return IsFixedSize<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::value; 00346 } 00347 00351 template<typename M> 00352 inline bool hasHeader() 00353 { 00354 return HasHeader<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::value; 00355 } 00356 00357 } // namespace message_traits 00358 } // namespace ros 00359 00360 #endif // ROSLIB_MESSAGE_TRAITS_H