Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef RVE_PROPERTIES_PROPERTY_VALUE_H
00031 #define RVE_PROPERTIES_PROPERTY_VALUE_H
00032
00033 #include "forwards.h"
00034
00035 #include <sstream>
00036
00037 #include <ros/types.h>
00038 #include <ros/assert.h>
00039
00040 #include <typeinfo>
00041 #include <stdexcept>
00042
00043 #include <cstdlib>
00044
00045 namespace rve_properties
00046 {
00047
00048 template<typename T>
00049 struct ValueTraits
00050 {
00051
00052 inline static const char* typeName() { return "unknown"; }
00053 inline static std::string toString(void* mem)
00054 {
00055 T* val = reinterpret_cast<T*>(mem);
00056 std::stringstream ss;
00057 ss << *val;
00058 return ss.str();
00059 }
00060
00061 inline static void fromString(void* mem, const std::string& str)
00062 {
00063 T* val = reinterpret_cast<T*>(mem);
00064 std::istringstream in(str);
00065 in >> *val;
00066 }
00067 };
00068
00069 #define RVE_PROPERTIES_DEFINE_SIMPLE_VALUE_TRAITS(type, name) \
00070 template<> \
00071 struct ValueTraits<type> \
00072 { \
00073 inline static const char* typeName() { return #name; } \
00074 inline static std::string toString(void* mem) \
00075 { \
00076 type* val = reinterpret_cast<type*>(mem); \
00077 std::stringstream ss; \
00078 ss << *val; \
00079 return ss.str(); \
00080 } \
00081 \
00082 inline static void fromString(void* mem, const std::string& str) \
00083 { \
00084 type* val = reinterpret_cast<type*>(mem); \
00085 std::istringstream in(str); \
00086 in >> *val; \
00087 } \
00088 };
00089
00090 RVE_PROPERTIES_DEFINE_SIMPLE_VALUE_TRAITS(bool, bool);
00091 RVE_PROPERTIES_DEFINE_SIMPLE_VALUE_TRAITS(uint8_t, uint8);
00092 RVE_PROPERTIES_DEFINE_SIMPLE_VALUE_TRAITS(int8_t, int8);
00093 RVE_PROPERTIES_DEFINE_SIMPLE_VALUE_TRAITS(uint16_t, uint16);
00094 RVE_PROPERTIES_DEFINE_SIMPLE_VALUE_TRAITS(int16_t, int16);
00095 RVE_PROPERTIES_DEFINE_SIMPLE_VALUE_TRAITS(uint32_t, uint32);
00096 RVE_PROPERTIES_DEFINE_SIMPLE_VALUE_TRAITS(int32_t, int32);
00097 RVE_PROPERTIES_DEFINE_SIMPLE_VALUE_TRAITS(uint64_t, uint64);
00098 RVE_PROPERTIES_DEFINE_SIMPLE_VALUE_TRAITS(int64_t, int64);
00099 RVE_PROPERTIES_DEFINE_SIMPLE_VALUE_TRAITS(float, float);
00100 RVE_PROPERTIES_DEFINE_SIMPLE_VALUE_TRAITS(double, double);
00101
00102 template<>
00103 struct ValueTraits<const char*>
00104 {
00105 inline static const char* typeName() { return "string"; }
00106
00107
00108 inline static std::string toString(void* mem)
00109 {
00110 ROS_BREAK();
00111 return std::string();
00112 }
00113 inline static void fromString(void* mem, const std::string& str)
00114 {
00115 ROS_BREAK();
00116 }
00117 };
00118
00119 template<>
00120 struct ValueTraits<std::string>
00121 {
00122 inline static const char* typeName() { return "string"; }
00123
00124 inline static std::string toString(void* mem)
00125 {
00126 return *reinterpret_cast<std::string*>(mem);
00127 }
00128 inline static void fromString(void* mem, const std::string& str)
00129 {
00130 *reinterpret_cast<std::string*>(mem) = str;
00131 }
00132 };
00133
00134 struct PropertyValueOperators
00135 {
00136 virtual std::string toString(void* mem) = 0;
00137 virtual void fromString(void* mem, const std::string& str) = 0;
00138 virtual void valueDestructor(void* mem) = 0;
00139 virtual void valueCopy(void* dst, const void* src) = 0;
00140 virtual const std::type_info& typeInfo() = 0;
00141 virtual const char* typeName() = 0;
00142 };
00143
00144 template<typename T>
00145 struct PropertyValueOperatorsT : public PropertyValueOperators
00146 {
00147 virtual std::string toString(void* mem)
00148 {
00149 return ValueTraits<T>::toString(mem);
00150 }
00151
00152 virtual void fromString(void* mem, const std::string& str)
00153 {
00154 return ValueTraits<T>::fromString(mem, str);
00155 }
00156
00157 virtual void valueDestructor(void* mem)
00158 {
00159 T* val = reinterpret_cast<T*>(mem);
00160 val->~T();
00161 }
00162
00163 virtual void valueCopy(void* dst, const void* src)
00164 {
00165 const T* src_val = reinterpret_cast<const T*>(src);
00166 new(dst) T(*src_val);
00167 }
00168
00169 virtual const std::type_info& typeInfo()
00170 {
00171 return typeid(T);
00172 }
00173
00174 virtual const char* typeName()
00175 {
00176 return ValueTraits<T>::typeName();
00177 }
00178
00179 static PropertyValueOperatorsT<T> static_copy;
00180 };
00181
00182 template<typename T> PropertyValueOperatorsT<T> PropertyValueOperatorsT<T>::static_copy;
00183
00184 class PropertyValue
00185 {
00186 public:
00187 PropertyValue()
00188 : large_buffer_(0)
00189 , buffer_size_(0)
00190 , ops_(0)
00191 {
00192 }
00193
00194 ~PropertyValue()
00195 {
00196 free(large_buffer_);
00197 }
00198
00199 PropertyValue(const PropertyValue& rhs)
00200 {
00201 *this = rhs;
00202 }
00203
00204 PropertyValue& operator=(const PropertyValue& rhs)
00205 {
00206 void* buf = large_buffer_ ? large_buffer_ : small_buffer_;
00207 if (filled())
00208 {
00209 ops_->valueDestructor(buf);
00210 }
00211
00212 buffer_size_ = rhs.buffer_size_;
00213 ops_ = rhs.ops_;
00214
00215 const void* source_buf = rhs.large_buffer_ ? rhs.large_buffer_ : rhs.small_buffer_;
00216 void* dest_buf = 0;
00217 if (rhs.large_buffer_)
00218 {
00219 large_buffer_ = (uint8_t*)realloc(large_buffer_, buffer_size_);
00220 dest_buf = large_buffer_;
00221 }
00222 else
00223 {
00224 free(large_buffer_);
00225 dest_buf = small_buffer_;
00226 }
00227
00228 ops_->valueCopy(dest_buf, source_buf);
00229
00230 return *this;
00231 }
00232
00233 template<typename T>
00234 void set(T t)
00235 {
00236 void* buf = large_buffer_ ? large_buffer_ : small_buffer_;
00237 if (filled())
00238 {
00239 ops_->valueDestructor(buf);
00240 }
00241
00242 buffer_size_ = sizeof(T);
00243 if (sizeof(T) <= sizeof(small_buffer_))
00244 {
00245 free(large_buffer_);
00246 large_buffer_ = 0;
00247
00248 T* copy = new (small_buffer_) T;
00249 *copy = t;
00250 }
00251 else
00252 {
00253 large_buffer_ = (uint8_t*)realloc(large_buffer_, sizeof(T));
00254 T* copy = new (large_buffer_) T;
00255 *copy = t;
00256 }
00257
00258 ops_ = &PropertyValueOperatorsT<T>::static_copy;
00259 }
00260
00261 template<typename T>
00262 void get(T& t, T default_value)
00263 {
00264 if (!ops_)
00265 {
00266 t = default_value;
00267 set(default_value);
00268 }
00269
00270 getImpl(t);
00271 }
00272
00273 template<typename T>
00274 void get(T& t)
00275 {
00276 if (!ops_)
00277 {
00278 throw std::bad_cast();
00279 }
00280
00281 getImpl(t);
00282 }
00283
00284 template<typename T>
00285 T get()
00286 {
00287 T t;
00288 get(t);
00289 return t;
00290 }
00291
00292 bool empty()
00293 {
00294 return !ops_;
00295 }
00296
00297 bool filled()
00298 {
00299 return ops_;
00300 }
00301
00302 const char* getTypeName()
00303 {
00304 if (!ops_)
00305 {
00306 return "empty";
00307 }
00308
00309 return ops_->typeName();
00310 }
00311
00312 const std::type_info& getTypeInfo()
00313 {
00314 if (!ops_)
00315 {
00316 return typeid(void);
00317 }
00318
00319 return ops_->typeInfo();
00320 }
00321
00322 private:
00323 template<typename T>
00324 void getImpl(T& t)
00325 {
00326 void* buf = large_buffer_ ? large_buffer_ : small_buffer_;
00327
00328
00329 if (typeid(T) == ops_->typeInfo())
00330 {
00331 t = *reinterpret_cast<T*>(buf);
00332 return;
00333 }
00334
00335
00336 std::string str = ops_->toString(buf);
00337 ValueTraits<T>::fromString(&t, str);
00338 }
00339
00340 uint8_t small_buffer_[8];
00341 uint8_t* large_buffer_;
00342 size_t buffer_size_;
00343 PropertyValueOperators* ops_;
00344 };
00345
00346 template<>
00347 inline void PropertyValue::set<const char*>(const char* str)
00348 {
00349 set<std::string>(std::string(str));
00350 }
00351
00352 template<>
00353 inline void PropertyValue::getImpl<std::string>(std::string& str)
00354 {
00355 void* buf = large_buffer_ ? large_buffer_ : small_buffer_;
00356
00357
00358 if (typeid(std::string) == ops_->typeInfo())
00359 {
00360 str = *reinterpret_cast<std::string*>(buf);
00361 return;
00362 }
00363
00364
00365 str = ops_->toString(buf);
00366 }
00367
00368 template<>
00369 inline void PropertyValue::getImpl<char*>(char*& str)
00370 {
00371 ROS_BREAK();
00372 }
00373
00374 #define PROPERTY_VALUE_EXTERNS(type) \
00375 extern template class PropertyValueOperatorsT<type>; \
00376 extern template void PropertyValue::set(type); \
00377 extern template void PropertyValue::get(type&, type); \
00378 extern template void PropertyValue::get(type&); \
00379 extern template type PropertyValue::get(); \
00380 extern template void PropertyValue::getImpl(type&);
00381
00382 PROPERTY_VALUE_EXTERNS(bool);
00383 PROPERTY_VALUE_EXTERNS(uint8_t);
00384 PROPERTY_VALUE_EXTERNS(int8_t);
00385 PROPERTY_VALUE_EXTERNS(uint16_t);
00386 PROPERTY_VALUE_EXTERNS(int16_t);
00387 PROPERTY_VALUE_EXTERNS(uint32_t);
00388 PROPERTY_VALUE_EXTERNS(int32_t);
00389 PROPERTY_VALUE_EXTERNS(uint64_t);
00390 PROPERTY_VALUE_EXTERNS(int64_t);
00391 PROPERTY_VALUE_EXTERNS(float);
00392 PROPERTY_VALUE_EXTERNS(double);
00393 PROPERTY_VALUE_EXTERNS(std::string);
00394
00395 }
00396
00397 #endif // RVE_PROPERTIES_PROPERTY_VALUE_H
00398