any.h
Go to the documentation of this file.
00001 #ifndef RTABMAP_FLANN_ANY_H_
00002 #define RTABMAP_FLANN_ANY_H_
00003 /*
00004  * (C) Copyright Christopher Diggins 2005-2011
00005  * (C) Copyright Pablo Aguilar 2005
00006  * (C) Copyright Kevlin Henney 2001
00007  *
00008  * Distributed under the Boost Software License, Version 1.0. (See
00009  * accompanying file LICENSE_1_0.txt or copy at
00010  * http://www.boost.org/LICENSE_1_0.txt
00011  *
00012  * Adapted for FLANN by Marius Muja
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 //#undef SMALL_POLICY
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 } // namespace anyimpl
00150 
00151 class any
00152 {
00153         typedef any any_t; // workaround for the NVCC compiler under windows
00154 private:
00155     // fields
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_


rtabmap
Author(s): Mathieu Labbe
autogenerated on Sat Jul 23 2016 11:44:15