Joe Verbout / Mbed 2 deprecated main

Dependencies:   mbed

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