Go to the documentation of this file.00001 #ifndef RTABMAP_FLANN_ANY_H_
00002 #define RTABMAP_FLANN_ANY_H_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <stdexcept>
00016 #include <ostream>
00017 #include <typeinfo>
00018
00019 namespace rtflann
00020 {
00021
00022 namespace anyimpl
00023 {
00024
00025 struct bad_any_cast : public std::runtime_error
00026 {
00027 bad_any_cast() : std::runtime_error("Cannot convert 'any' value") { }
00028 };
00029
00030 struct empty_any
00031 {
00032 };
00033
00034 inline std::ostream& operator <<(std::ostream& out, const empty_any&)
00035 {
00036 out << "[empty_any]";
00037 return out;
00038 }
00039
00040 struct base_any_policy
00041 {
00042 virtual void static_delete(void** x) = 0;
00043 virtual void copy_from_value(void const* src, void** dest) = 0;
00044 virtual void clone(void* const* src, void** dest) = 0;
00045 virtual void move(void* const* src, void** dest) = 0;
00046 virtual void* get_value(void** src) = 0;
00047 virtual const void* get_value(void* const * src) = 0;
00048 virtual ::size_t get_size() = 0;
00049 virtual const std::type_info& type() = 0;
00050 virtual void print(std::ostream& out, void* const* src) = 0;
00051 };
00052
00053 template<typename T>
00054 struct typed_base_any_policy : base_any_policy
00055 {
00056 virtual ::size_t get_size() { return sizeof(T); }
00057 virtual const std::type_info& type() { return typeid(T); }
00058
00059 };
00060
00061 template<typename T>
00062 struct small_any_policy : typed_base_any_policy<T>
00063 {
00064 virtual void static_delete(void**) { }
00065 virtual void copy_from_value(void const* src, void** dest)
00066 {
00067 new (dest) T(* reinterpret_cast<T const*>(src));
00068 }
00069 virtual void clone(void* const* src, void** dest) { *dest = *src; }
00070 virtual void move(void* const* src, void** dest) { *dest = *src; }
00071 virtual void* get_value(void** src) { return reinterpret_cast<void*>(src); }
00072 virtual const void* get_value(void* const * src) { return reinterpret_cast<const void*>(src); }
00073 virtual void print(std::ostream& out, void* const* src) { out << *reinterpret_cast<T const*>(src); }
00074 };
00075
00076 template<typename T>
00077 struct big_any_policy : typed_base_any_policy<T>
00078 {
00079 virtual void static_delete(void** x)
00080 {
00081 if (* x) delete (* reinterpret_cast<T**>(x)); *x = NULL;
00082 }
00083 virtual void copy_from_value(void const* src, void** dest)
00084 {
00085 *dest = new T(*reinterpret_cast<T const*>(src));
00086 }
00087 virtual void clone(void* const* src, void** dest)
00088 {
00089 *dest = new T(**reinterpret_cast<T* const*>(src));
00090 }
00091 virtual void move(void* const* src, void** dest)
00092 {
00093 (*reinterpret_cast<T**>(dest))->~T();
00094 **reinterpret_cast<T**>(dest) = **reinterpret_cast<T* const*>(src);
00095 }
00096 virtual void* get_value(void** src) { return *src; }
00097 virtual const void* get_value(void* const * src) { return *src; }
00098 virtual void print(std::ostream& out, void* const* src) { out << *reinterpret_cast<T const*>(*src); }
00099 };
00100
00101 template<typename T>
00102 struct choose_policy
00103 {
00104 typedef big_any_policy<T> type;
00105 };
00106
00107 template<typename T>
00108 struct choose_policy<T*>
00109 {
00110 typedef small_any_policy<T*> type;
00111 };
00112
00113 struct any;
00114
00117 template<>
00118 struct choose_policy<any>
00119 {
00120 typedef void type;
00121 };
00122
00124 #define SMALL_POLICY(TYPE) \
00125 template<> \
00126 struct choose_policy<TYPE> { typedef small_any_policy<TYPE> type; \
00127 }
00128
00129 SMALL_POLICY(signed char);
00130 SMALL_POLICY(unsigned char);
00131 SMALL_POLICY(signed short);
00132 SMALL_POLICY(unsigned short);
00133 SMALL_POLICY(signed int);
00134 SMALL_POLICY(unsigned int);
00135 SMALL_POLICY(signed long);
00136 SMALL_POLICY(unsigned long);
00137 SMALL_POLICY(float);
00138 SMALL_POLICY(bool);
00139
00140
00141
00143 template<typename T>
00144 base_any_policy* get_policy()
00145 {
00146 static typename choose_policy<T>::type policy;
00147 return &policy;
00148 }
00149 }
00150
00151 class any
00152 {
00153 typedef any any_t;
00154 private:
00155
00156 anyimpl::base_any_policy* policy;
00157 void* object;
00158
00159 public:
00161 template <typename T>
00162 any(const T& x)
00163 : policy(anyimpl::get_policy<anyimpl::empty_any>()), object(NULL)
00164 {
00165 assign(x);
00166 }
00167
00169 any()
00170 : policy(anyimpl::get_policy<anyimpl::empty_any>()), object(NULL)
00171 { }
00172
00174 any(const char* x)
00175 : policy(anyimpl::get_policy<anyimpl::empty_any>()), object(NULL)
00176 {
00177 assign(x);
00178 }
00179
00181 any(const any& x)
00182 : policy(anyimpl::get_policy<anyimpl::empty_any>()), object(NULL)
00183 {
00184 assign(x);
00185 }
00186
00188 ~any()
00189 {
00190 policy->static_delete(&object);
00191 }
00192
00194 any& assign(const any& x)
00195 {
00196 reset();
00197 policy = x.policy;
00198 policy->clone(&x.object, &object);
00199 return *this;
00200 }
00201
00203 template <typename T>
00204 any_t& assign(const T& x)
00205 {
00206 reset();
00207 policy = anyimpl::get_policy<T>();
00208 policy->copy_from_value(&x, &object);
00209 return *this;
00210 }
00211
00213 template<typename T>
00214 any_t& operator=(const T& x)
00215 {
00216 return assign(x);
00217 }
00218
00221 any& operator=(const char* x)
00222 {
00223 return assign(x);
00224 }
00225
00227 any& swap(any& x)
00228 {
00229 std::swap(policy, x.policy);
00230 std::swap(object, x.object);
00231 return *this;
00232 }
00233
00235 template<typename T>
00236 T& cast()
00237 {
00238 if (policy->type() != typeid(T)) throw anyimpl::bad_any_cast();
00239 T* r = reinterpret_cast<T*>(policy->get_value(&object));
00240 return *r;
00241 }
00242
00244 template<typename T>
00245 const T& cast() const
00246 {
00247 if (policy->type() != typeid(T)) throw anyimpl::bad_any_cast();
00248 const T* r = reinterpret_cast<const T*>(policy->get_value(&object));
00249 return *r;
00250 }
00251
00253 bool empty() const
00254 {
00255 return policy->type() == typeid(anyimpl::empty_any);
00256 }
00257
00259 void reset()
00260 {
00261 policy->static_delete(&object);
00262 policy = anyimpl::get_policy<anyimpl::empty_any>();
00263 }
00264
00266 bool compatible(const any& x) const
00267 {
00268 return policy->type() == x.policy->type();
00269 }
00270
00272 template<typename T>
00273 bool has_type()
00274 {
00275 return policy->type() == typeid(T);
00276 }
00277
00278 const std::type_info& type() const
00279 {
00280 return policy->type();
00281 }
00282
00283 friend std::ostream& operator <<(std::ostream& out, const any& any_val);
00284 };
00285
00286 inline std::ostream& operator <<(std::ostream& out, const any& any_val)
00287 {
00288 any_val.policy->print(out,&any_val.object);
00289 return out;
00290 }
00291
00292 }
00293
00294 #endif // FLANN_ANY_H_