Renesas / opencv-lib

Dependents:   RZ_A2M_Mbed_samples

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers any.h Source File

any.h

00001 #ifndef OPENCV_FLANN_ANY_H_
00002 #define OPENCV_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 "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 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     virtual ~base_any_policy() {}
00052 };
00053 
00054 template<typename T>
00055 struct typed_base_any_policy : base_any_policy
00056 {
00057     virtual ::size_t get_size() { return sizeof(T); }
00058     virtual const std::type_info& type() { return typeid(T); }
00059 
00060 };
00061 
00062 template<typename T>
00063 struct small_any_policy : typed_base_any_policy<T>
00064 {
00065     virtual void static_delete(void**) { }
00066     virtual void copy_from_value(void const* src, void** dest)
00067     {
00068         new (dest) T(* reinterpret_cast<T const*>(src));
00069     }
00070     virtual void clone(void* const* src, void** dest) { *dest = *src; }
00071     virtual void move(void* const* src, void** dest) { *dest = *src; }
00072     virtual void* get_value(void** src) { return reinterpret_cast<void*>(src); }
00073     virtual const void* get_value(void* const * src) { return reinterpret_cast<const void*>(src); }
00074     virtual void print(std::ostream& out, void* const* src) { out << *reinterpret_cast<T const*>(src); }
00075 };
00076 
00077 template<typename T>
00078 struct big_any_policy : typed_base_any_policy<T>
00079 {
00080     virtual void static_delete(void** x)
00081     {
00082         if (* x) delete (* reinterpret_cast<T**>(x));
00083         *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 const void* get_value(void* const * src) { return *src; }
00100     virtual void print(std::ostream& out, void* const* src) { out << *reinterpret_cast<T const*>(*src); }
00101 };
00102 
00103 template<> inline void big_any_policy<flann_centers_init_t>::print(std::ostream& out, void* const* src)
00104 {
00105     out << int(*reinterpret_cast<flann_centers_init_t const*>(*src));
00106 }
00107 
00108 template<> inline void big_any_policy<flann_algorithm_t>::print(std::ostream& out, void* const* src)
00109 {
00110     out << int(*reinterpret_cast<flann_algorithm_t const*>(*src));
00111 }
00112 
00113 template<> inline void big_any_policy<cv::String>::print(std::ostream& out, void* const* src)
00114 {
00115     out << (*reinterpret_cast<cv::String const*>(*src)).c_str();
00116 }
00117 
00118 template<typename T>
00119 struct choose_policy
00120 {
00121     typedef big_any_policy<T> type;
00122 };
00123 
00124 template<typename T>
00125 struct choose_policy<T*>
00126 {
00127     typedef small_any_policy<T*> type;
00128 };
00129 
00130 struct any;
00131 
00132 /// Choosing the policy for an any type is illegal, but should never happen.
00133 /// This is designed to throw a compiler error.
00134 template<>
00135 struct choose_policy<any>
00136 {
00137     typedef void type;
00138 };
00139 
00140 /// Specializations for small types.
00141 #define SMALL_POLICY(TYPE) \
00142     template<> \
00143     struct choose_policy<TYPE> { typedef small_any_policy<TYPE> type; \
00144     }
00145 
00146 SMALL_POLICY(signed char);
00147 SMALL_POLICY(unsigned char);
00148 SMALL_POLICY(signed short);
00149 SMALL_POLICY(unsigned short);
00150 SMALL_POLICY(signed int);
00151 SMALL_POLICY(unsigned int);
00152 SMALL_POLICY(signed long);
00153 SMALL_POLICY(unsigned long);
00154 SMALL_POLICY(float);
00155 SMALL_POLICY(bool);
00156 
00157 #undef SMALL_POLICY
00158 
00159 template <typename T>
00160 class SinglePolicy
00161 {
00162     SinglePolicy();
00163     SinglePolicy(const SinglePolicy& other);
00164     SinglePolicy& operator=(const SinglePolicy& other);
00165 
00166 public:
00167     static base_any_policy* get_policy();
00168 
00169 private:
00170     static typename choose_policy<T>::type policy;
00171 };
00172 
00173 template <typename T>
00174 typename choose_policy<T>::type SinglePolicy<T>::policy;
00175 
00176 /// This function will return a different policy for each type.
00177 template <typename T>
00178 inline base_any_policy* SinglePolicy<T>::get_policy() { return &policy; }
00179 
00180 } // namespace anyimpl
00181 
00182 struct any
00183 {
00184 private:
00185     // fields
00186     anyimpl::base_any_policy* policy;
00187     void* object;
00188 
00189 public:
00190     /// Initializing constructor.
00191     template <typename T>
00192     any(const T& x)
00193         : policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL)
00194     {
00195         assign(x);
00196     }
00197 
00198     /// Empty constructor.
00199     any()
00200         : policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL)
00201     { }
00202 
00203     /// Special initializing constructor for string literals.
00204     any(const char* x)
00205         : policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL)
00206     {
00207         assign(x);
00208     }
00209 
00210     /// Copy constructor.
00211     any(const any& x)
00212         : policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL)
00213     {
00214         assign(x);
00215     }
00216 
00217     /// Destructor.
00218     ~any()
00219     {
00220         policy->static_delete(&object);
00221     }
00222 
00223     /// Assignment function from another any.
00224     any& assign(const any& x)
00225     {
00226         reset();
00227         policy = x.policy;
00228         policy->clone(&x.object, &object);
00229         return *this;
00230     }
00231 
00232     /// Assignment function.
00233     template <typename T>
00234     any& assign(const T& x)
00235     {
00236         reset();
00237         policy = anyimpl::SinglePolicy<T>::get_policy();
00238         policy->copy_from_value(&x, &object);
00239         return *this;
00240     }
00241 
00242     /// Assignment operator.
00243     template<typename T>
00244     any& operator=(const T& x)
00245     {
00246         return assign(x);
00247     }
00248 
00249     /// Assignment operator, specialed for literal strings.
00250     /// They have types like const char [6] which don't work as expected.
00251     any& operator=(const char* x)
00252     {
00253         return assign(x);
00254     }
00255 
00256     /// Utility functions
00257     any& swap(any& x)
00258     {
00259         std::swap(policy, x.policy);
00260         std::swap(object, x.object);
00261         return *this;
00262     }
00263 
00264     /// Cast operator. You can only cast to the original type.
00265     template<typename T>
00266     T& cast()
00267     {
00268         if (policy->type() != typeid(T)) throw anyimpl::bad_any_cast();
00269         T* r = reinterpret_cast<T*>(policy->get_value(&object));
00270         return *r;
00271     }
00272 
00273     /// Cast operator. You can only cast to the original type.
00274     template<typename T>
00275     const T& cast() const
00276     {
00277         if (policy->type() != typeid(T)) throw anyimpl::bad_any_cast();
00278         const T* r = reinterpret_cast<const T*>(policy->get_value(&object));
00279         return *r;
00280     }
00281 
00282     /// Returns true if the any contains no value.
00283     bool empty() const
00284     {
00285         return policy->type() == typeid(anyimpl::empty_any);
00286     }
00287 
00288     /// Frees any allocated memory, and sets the value to NULL.
00289     void reset()
00290     {
00291         policy->static_delete(&object);
00292         policy = anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy();
00293     }
00294 
00295     /// Returns true if the two types are the same.
00296     bool compatible(const any& x) const
00297     {
00298         return policy->type() == x.policy->type();
00299     }
00300 
00301     /// Returns if the type is compatible with the policy
00302     template<typename T>
00303     bool has_type()
00304     {
00305         return policy->type() == typeid(T);
00306     }
00307 
00308     const std::type_info& type() const
00309     {
00310         return policy->type();
00311     }
00312 
00313     friend std::ostream& operator <<(std::ostream& out, const any& any_val);
00314 };
00315 
00316 inline std::ostream& operator <<(std::ostream& out, const any& any_val)
00317 {
00318     any_val.policy->print(out,&any_val.object);
00319     return out;
00320 }
00321 
00322 }
00323 
00324 #endif // OPENCV_FLANN_ANY_H_