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> 00112 struct MD5Sum 00113 { 00114 static const char* value() 00115 { 00116 return M::__s_getMD5Sum().c_str(); 00117 } 00118 00119 static const char* value(const M& m) 00120 { 00121 return m.__getMD5Sum().c_str(); 00122 } 00123 }; 00124 00128 template<typename M> 00129 struct DataType 00130 { 00131 static const char* value() 00132 { 00133 return M::__s_getDataType().c_str(); 00134 } 00135 00136 static const char* value(const M& m) 00137 { 00138 return m.__getDataType().c_str(); 00139 } 00140 }; 00141 00145 template<typename M> 00146 struct Definition 00147 { 00148 static const char* value() 00149 { 00150 return M::__s_getMessageDefinition().c_str(); 00151 } 00152 00153 static const char* value(const M& m) 00154 { 00155 return m.__getMessageDefinition().c_str(); 00156 } 00157 }; 00158 00163 template<typename M, typename Enable = void> 00164 struct Header 00165 { 00166 static std_msgs::Header* pointer(M& m) { return 0; } 00167 static std_msgs::Header const* pointer(const M& m) { return 0; } 00168 }; 00169 00170 template<typename M> 00171 struct Header<M, typename boost::enable_if<HasHeader<M> >::type > 00172 { 00173 static std_msgs::Header* pointer(M& m) { return &m.header; } 00174 static std_msgs::Header const* pointer(const M& m) { return &m.header; } 00175 }; 00176 00182 template<typename M, typename Enable = void> 00183 struct FrameId 00184 { 00185 static std::string* pointer(M& m) { return 0; } 00186 static std::string const* pointer(const M& m) { return 0; } 00187 }; 00188 00189 template<typename M> 00190 struct FrameId<M, typename boost::enable_if<HasHeader<M> >::type > 00191 { 00192 static std::string* pointer(M& m) { return &m.header.frame_id; } 00193 static std::string const* pointer(const M& m) { return &m.header.frame_id; } 00194 static std::string value(const M& m) { return m.header.frame_id; } 00195 }; 00196 00202 template<typename M, typename Enable = void> 00203 struct TimeStamp 00204 { 00205 static ros::Time* pointer(M& m) { return 0; } 00206 static ros::Time const* pointer(const M& m) { return 0; } 00207 }; 00208 00209 template<typename M> 00210 struct TimeStamp<M, typename boost::enable_if<HasHeader<M> >::type > 00211 { 00212 static ros::Time* pointer(typename boost::remove_const<M>::type &m) { return &m.header.stamp; } 00213 static ros::Time const* pointer(const M& m) { return &m.header.stamp; } 00214 static ros::Time value(const M& m) { return m.header.stamp; } 00215 }; 00216 00220 template<typename M> 00221 inline const char* md5sum() 00222 { 00223 return MD5Sum<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::value(); 00224 } 00225 00229 template<typename M> 00230 inline const char* datatype() 00231 { 00232 return DataType<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::value(); 00233 } 00234 00238 template<typename M> 00239 inline const char* definition() 00240 { 00241 return Definition<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::value(); 00242 } 00243 00247 template<typename M> 00248 inline const char* md5sum(const M& m) 00249 { 00250 return MD5Sum<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::value(m); 00251 } 00252 00256 template<typename M> 00257 inline const char* datatype(const M& m) 00258 { 00259 return DataType<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::value(m); 00260 } 00261 00265 template<typename M> 00266 inline const char* definition(const M& m) 00267 { 00268 return Definition<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::value(m); 00269 } 00270 00274 template<typename M> 00275 inline std_msgs::Header* header(M& m) 00276 { 00277 return Header<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::pointer(m); 00278 } 00279 00283 template<typename M> 00284 inline std_msgs::Header const* header(const M& m) 00285 { 00286 return Header<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::pointer(m); 00287 } 00288 00292 template<typename M> 00293 inline std::string* frameId(M& m) 00294 { 00295 return FrameId<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::pointer(m); 00296 } 00297 00301 template<typename M> 00302 inline std::string const* frameId(const M& m) 00303 { 00304 return FrameId<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::pointer(m); 00305 } 00306 00310 template<typename M> 00311 inline ros::Time* timeStamp(M& m) 00312 { 00313 return TimeStamp<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::pointer(m); 00314 } 00315 00319 template<typename M> 00320 inline ros::Time const* timeStamp(const M& m) 00321 { 00322 return TimeStamp<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::pointer(m); 00323 } 00324 00328 template<typename M> 00329 inline bool isSimple() 00330 { 00331 return IsSimple<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::value; 00332 } 00333 00337 template<typename M> 00338 inline bool isFixedSize() 00339 { 00340 return IsFixedSize<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::value; 00341 } 00342 00346 template<typename M> 00347 inline bool hasHeader() 00348 { 00349 return HasHeader<typename boost::remove_reference<typename boost::remove_const<M>::type>::type>::value; 00350 } 00351 00352 } // namespace message_traits 00353 } // namespace ros 00354 00355 #endif // ROSLIB_MESSAGE_TRAITS_H