Go to the documentation of this file.00001 #ifndef OPENCV_FLANN_ANY_H_
00002 #define OPENCV_FLANN_ANY_H_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "defines.h"
00016 #include <stdexcept>
00017 #include <ostream>
00018 #include <typeinfo>
00019
00020 namespace cvflann
00021 {
00022
00023 namespace anyimpl
00024 {
00025
00026 struct bad_any_cast
00027 {
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 ::size_t get_size() = 0;
00048 virtual const std::type_info& type() = 0;
00049 virtual void print(std::ostream& out, void* const* src) = 0;
00050
00051 #ifdef OPENCV_CAN_BREAK_BINARY_COMPATIBILITY
00052 virtual ~base_any_policy() {}
00053 #endif
00054 };
00055
00056 template<typename T>
00057 struct typed_base_any_policy : base_any_policy
00058 {
00059 virtual ::size_t get_size() { return sizeof(T); }
00060 virtual const std::type_info& type() { return typeid(T); }
00061
00062 };
00063
00064 template<typename T>
00065 struct small_any_policy : typed_base_any_policy<T>
00066 {
00067 virtual void static_delete(void**) { }
00068 virtual void copy_from_value(void const* src, void** dest)
00069 {
00070 new (dest) T(* reinterpret_cast<T const*>(src));
00071 }
00072 virtual void clone(void* const* src, void** dest) { *dest = *src; }
00073 virtual void move(void* const* src, void** dest) { *dest = *src; }
00074 virtual void* get_value(void** src) { return reinterpret_cast<void*>(src); }
00075 virtual void print(std::ostream& out, void* const* src) { out << *reinterpret_cast<T const*>(src); }
00076 };
00077
00078 template<typename T>
00079 struct big_any_policy : typed_base_any_policy<T>
00080 {
00081 virtual void static_delete(void** x)
00082 {
00083 if (* x) delete (* reinterpret_cast<T**>(x)); *x = NULL;
00084 }
00085 virtual void copy_from_value(void const* src, void** dest)
00086 {
00087 *dest = new T(*reinterpret_cast<T const*>(src));
00088 }
00089 virtual void clone(void* const* src, void** dest)
00090 {
00091 *dest = new T(**reinterpret_cast<T* const*>(src));
00092 }
00093 virtual void move(void* const* src, void** dest)
00094 {
00095 (*reinterpret_cast<T**>(dest))->~T();
00096 **reinterpret_cast<T**>(dest) = **reinterpret_cast<T* const*>(src);
00097 }
00098 virtual void* get_value(void** src) { return *src; }
00099 virtual void print(std::ostream& out, void* const* src) { out << *reinterpret_cast<T const*>(*src); }
00100 };
00101
00102 template<> inline void big_any_policy<flann_centers_init_t>::print(std::ostream& out, void* const* src)
00103 {
00104 out << int(*reinterpret_cast<flann_centers_init_t const*>(*src));
00105 }
00106
00107 template<> inline void big_any_policy<flann_algorithm_t>::print(std::ostream& out, void* const* src)
00108 {
00109 out << int(*reinterpret_cast<flann_algorithm_t const*>(*src));
00110 }
00111
00112 template<typename T>
00113 struct choose_policy
00114 {
00115 typedef big_any_policy<T> type;
00116 };
00117
00118 template<typename T>
00119 struct choose_policy<T*>
00120 {
00121 typedef small_any_policy<T*> type;
00122 };
00123
00124 struct any;
00125
00128 template<>
00129 struct choose_policy<any>
00130 {
00131 typedef void type;
00132 };
00133
00135 #define SMALL_POLICY(TYPE) \
00136 template<> \
00137 struct choose_policy<TYPE> { typedef small_any_policy<TYPE> type; \
00138 }
00139
00140 SMALL_POLICY(signed char);
00141 SMALL_POLICY(unsigned char);
00142 SMALL_POLICY(signed short);
00143 SMALL_POLICY(unsigned short);
00144 SMALL_POLICY(signed int);
00145 SMALL_POLICY(unsigned int);
00146 SMALL_POLICY(signed long);
00147 SMALL_POLICY(unsigned long);
00148 SMALL_POLICY(float);
00149 SMALL_POLICY(bool);
00150
00151 #undef SMALL_POLICY
00152
00154 template<typename T>
00155 base_any_policy* get_policy()
00156 {
00157 static typename choose_policy<T>::type policy;
00158 return &policy;
00159 }
00160 }
00161
00162 struct any
00163 {
00164 private:
00165
00166 anyimpl::base_any_policy* policy;
00167 void* object;
00168
00169 public:
00171 template <typename T>
00172 any(const T& x)
00173 : policy(anyimpl::get_policy<anyimpl::empty_any>()), object(NULL)
00174 {
00175 assign(x);
00176 }
00177
00179 any()
00180 : policy(anyimpl::get_policy<anyimpl::empty_any>()), object(NULL)
00181 { }
00182
00184 any(const char* x)
00185 : policy(anyimpl::get_policy<anyimpl::empty_any>()), object(NULL)
00186 {
00187 assign(x);
00188 }
00189
00191 any(const any& x)
00192 : policy(anyimpl::get_policy<anyimpl::empty_any>()), object(NULL)
00193 {
00194 assign(x);
00195 }
00196
00198 ~any()
00199 {
00200 policy->static_delete(&object);
00201 }
00202
00204 any& assign(const any& x)
00205 {
00206 reset();
00207 policy = x.policy;
00208 policy->clone(&x.object, &object);
00209 return *this;
00210 }
00211
00213 template <typename T>
00214 any& assign(const T& x)
00215 {
00216 reset();
00217 policy = anyimpl::get_policy<T>();
00218 policy->copy_from_value(&x, &object);
00219 return *this;
00220 }
00221
00223 template<typename T>
00224 any& operator=(const T& x)
00225 {
00226 return assign(x);
00227 }
00228
00231 any& operator=(const char* x)
00232 {
00233 return assign(x);
00234 }
00235
00237 any& swap(any& x)
00238 {
00239 std::swap(policy, x.policy);
00240 std::swap(object, x.object);
00241 return *this;
00242 }
00243
00245 template<typename T>
00246 T& cast()
00247 {
00248 if (policy->type() != typeid(T)) throw anyimpl::bad_any_cast();
00249 T* r = reinterpret_cast<T*>(policy->get_value(&object));
00250 return *r;
00251 }
00252
00254 template<typename T>
00255 const T& cast() const
00256 {
00257 if (policy->type() != typeid(T)) throw anyimpl::bad_any_cast();
00258 void* obj = const_cast<void*>(object);
00259 T* r = reinterpret_cast<T*>(policy->get_value(&obj));
00260 return *r;
00261 }
00262
00264 bool empty() const
00265 {
00266 return policy->type() == typeid(anyimpl::empty_any);
00267 }
00268
00270 void reset()
00271 {
00272 policy->static_delete(&object);
00273 policy = anyimpl::get_policy<anyimpl::empty_any>();
00274 }
00275
00277 bool compatible(const any& x) const
00278 {
00279 return policy->type() == x.policy->type();
00280 }
00281
00283 template<typename T>
00284 bool has_type()
00285 {
00286 return policy->type() == typeid(T);
00287 }
00288
00289 const std::type_info& type() const
00290 {
00291 return policy->type();
00292 }
00293
00294 friend std::ostream& operator <<(std::ostream& out, const any& any_val);
00295 };
00296
00297 inline std::ostream& operator <<(std::ostream& out, const any& any_val)
00298 {
00299 any_val.policy->print(out,&any_val.object);
00300 return out;
00301 }
00302
00303 }
00304
00305 #endif // OPENCV_FLANN_ANY_H_