any.h 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. #ifndef OPENCV_FLANN_ANY_H_
  2. #define OPENCV_FLANN_ANY_H_
  3. /*
  4. * (C) Copyright Christopher Diggins 2005-2011
  5. * (C) Copyright Pablo Aguilar 2005
  6. * (C) Copyright Kevlin Henney 2001
  7. *
  8. * Distributed under the Boost Software License, Version 1.0. (See
  9. * accompanying file LICENSE_1_0.txt or copy at
  10. * http://www.boost.org/LICENSE_1_0.txt
  11. *
  12. * Adapted for FLANN by Marius Muja
  13. */
  14. #include "defines.h"
  15. #include <stdexcept>
  16. #include <ostream>
  17. #include <typeinfo>
  18. namespace cvflann
  19. {
  20. namespace anyimpl
  21. {
  22. struct bad_any_cast
  23. {
  24. };
  25. struct empty_any
  26. {
  27. };
  28. inline std::ostream& operator <<(std::ostream& out, const empty_any&)
  29. {
  30. out << "[empty_any]";
  31. return out;
  32. }
  33. struct base_any_policy
  34. {
  35. virtual void static_delete(void** x) = 0;
  36. virtual void copy_from_value(void const* src, void** dest) = 0;
  37. virtual void clone(void* const* src, void** dest) = 0;
  38. virtual void move(void* const* src, void** dest) = 0;
  39. virtual void* get_value(void** src) = 0;
  40. virtual const void* get_value(void* const * src) = 0;
  41. virtual ::size_t get_size() = 0;
  42. virtual const std::type_info& type() = 0;
  43. virtual void print(std::ostream& out, void* const* src) = 0;
  44. virtual ~base_any_policy() {}
  45. };
  46. template<typename T>
  47. struct typed_base_any_policy : base_any_policy
  48. {
  49. virtual ::size_t get_size() { return sizeof(T); }
  50. virtual const std::type_info& type() { return typeid(T); }
  51. };
  52. template<typename T>
  53. struct small_any_policy : typed_base_any_policy<T>
  54. {
  55. virtual void static_delete(void**) { }
  56. virtual void copy_from_value(void const* src, void** dest)
  57. {
  58. new (dest) T(* reinterpret_cast<T const*>(src));
  59. }
  60. virtual void clone(void* const* src, void** dest) { *dest = *src; }
  61. virtual void move(void* const* src, void** dest) { *dest = *src; }
  62. virtual void* get_value(void** src) { return reinterpret_cast<void*>(src); }
  63. virtual const void* get_value(void* const * src) { return reinterpret_cast<const void*>(src); }
  64. virtual void print(std::ostream& out, void* const* src) { out << *reinterpret_cast<T const*>(src); }
  65. };
  66. template<typename T>
  67. struct big_any_policy : typed_base_any_policy<T>
  68. {
  69. virtual void static_delete(void** x)
  70. {
  71. if (* x) delete (* reinterpret_cast<T**>(x)); *x = NULL;
  72. }
  73. virtual void copy_from_value(void const* src, void** dest)
  74. {
  75. *dest = new T(*reinterpret_cast<T const*>(src));
  76. }
  77. virtual void clone(void* const* src, void** dest)
  78. {
  79. *dest = new T(**reinterpret_cast<T* const*>(src));
  80. }
  81. virtual void move(void* const* src, void** dest)
  82. {
  83. (*reinterpret_cast<T**>(dest))->~T();
  84. **reinterpret_cast<T**>(dest) = **reinterpret_cast<T* const*>(src);
  85. }
  86. virtual void* get_value(void** src) { return *src; }
  87. virtual const void* get_value(void* const * src) { return *src; }
  88. virtual void print(std::ostream& out, void* const* src) { out << *reinterpret_cast<T const*>(*src); }
  89. };
  90. template<> inline void big_any_policy<flann_centers_init_t>::print(std::ostream& out, void* const* src)
  91. {
  92. out << int(*reinterpret_cast<flann_centers_init_t const*>(*src));
  93. }
  94. template<> inline void big_any_policy<flann_algorithm_t>::print(std::ostream& out, void* const* src)
  95. {
  96. out << int(*reinterpret_cast<flann_algorithm_t const*>(*src));
  97. }
  98. template<> inline void big_any_policy<cv::String>::print(std::ostream& out, void* const* src)
  99. {
  100. out << (*reinterpret_cast<cv::String const*>(*src)).c_str();
  101. }
  102. template<typename T>
  103. struct choose_policy
  104. {
  105. typedef big_any_policy<T> type;
  106. };
  107. template<typename T>
  108. struct choose_policy<T*>
  109. {
  110. typedef small_any_policy<T*> type;
  111. };
  112. struct any;
  113. /// Choosing the policy for an any type is illegal, but should never happen.
  114. /// This is designed to throw a compiler error.
  115. template<>
  116. struct choose_policy<any>
  117. {
  118. typedef void type;
  119. };
  120. /// Specializations for small types.
  121. #define SMALL_POLICY(TYPE) \
  122. template<> \
  123. struct choose_policy<TYPE> { typedef small_any_policy<TYPE> type; \
  124. }
  125. SMALL_POLICY(signed char);
  126. SMALL_POLICY(unsigned char);
  127. SMALL_POLICY(signed short);
  128. SMALL_POLICY(unsigned short);
  129. SMALL_POLICY(signed int);
  130. SMALL_POLICY(unsigned int);
  131. SMALL_POLICY(signed long);
  132. SMALL_POLICY(unsigned long);
  133. SMALL_POLICY(float);
  134. SMALL_POLICY(bool);
  135. #undef SMALL_POLICY
  136. template <typename T>
  137. class SinglePolicy
  138. {
  139. SinglePolicy();
  140. SinglePolicy(const SinglePolicy& other);
  141. SinglePolicy& operator=(const SinglePolicy& other);
  142. public:
  143. static base_any_policy* get_policy();
  144. private:
  145. static typename choose_policy<T>::type policy;
  146. };
  147. template <typename T>
  148. typename choose_policy<T>::type SinglePolicy<T>::policy;
  149. /// This function will return a different policy for each type.
  150. template <typename T>
  151. inline base_any_policy* SinglePolicy<T>::get_policy() { return &policy; }
  152. } // namespace anyimpl
  153. struct any
  154. {
  155. private:
  156. // fields
  157. anyimpl::base_any_policy* policy;
  158. void* object;
  159. public:
  160. /// Initializing constructor.
  161. template <typename T>
  162. any(const T& x)
  163. : policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL)
  164. {
  165. assign(x);
  166. }
  167. /// Empty constructor.
  168. any()
  169. : policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL)
  170. { }
  171. /// Special initializing constructor for string literals.
  172. any(const char* x)
  173. : policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL)
  174. {
  175. assign(x);
  176. }
  177. /// Copy constructor.
  178. any(const any& x)
  179. : policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL)
  180. {
  181. assign(x);
  182. }
  183. /// Destructor.
  184. ~any()
  185. {
  186. policy->static_delete(&object);
  187. }
  188. /// Assignment function from another any.
  189. any& assign(const any& x)
  190. {
  191. reset();
  192. policy = x.policy;
  193. policy->clone(&x.object, &object);
  194. return *this;
  195. }
  196. /// Assignment function.
  197. template <typename T>
  198. any& assign(const T& x)
  199. {
  200. reset();
  201. policy = anyimpl::SinglePolicy<T>::get_policy();
  202. policy->copy_from_value(&x, &object);
  203. return *this;
  204. }
  205. /// Assignment operator.
  206. template<typename T>
  207. any& operator=(const T& x)
  208. {
  209. return assign(x);
  210. }
  211. /// Assignment operator, specialed for literal strings.
  212. /// They have types like const char [6] which don't work as expected.
  213. any& operator=(const char* x)
  214. {
  215. return assign(x);
  216. }
  217. /// Utility functions
  218. any& swap(any& x)
  219. {
  220. std::swap(policy, x.policy);
  221. std::swap(object, x.object);
  222. return *this;
  223. }
  224. /// Cast operator. You can only cast to the original type.
  225. template<typename T>
  226. T& cast()
  227. {
  228. if (policy->type() != typeid(T)) throw anyimpl::bad_any_cast();
  229. T* r = reinterpret_cast<T*>(policy->get_value(&object));
  230. return *r;
  231. }
  232. /// Cast operator. You can only cast to the original type.
  233. template<typename T>
  234. const T& cast() const
  235. {
  236. if (policy->type() != typeid(T)) throw anyimpl::bad_any_cast();
  237. const T* r = reinterpret_cast<const T*>(policy->get_value(&object));
  238. return *r;
  239. }
  240. /// Returns true if the any contains no value.
  241. bool empty() const
  242. {
  243. return policy->type() == typeid(anyimpl::empty_any);
  244. }
  245. /// Frees any allocated memory, and sets the value to NULL.
  246. void reset()
  247. {
  248. policy->static_delete(&object);
  249. policy = anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy();
  250. }
  251. /// Returns true if the two types are the same.
  252. bool compatible(const any& x) const
  253. {
  254. return policy->type() == x.policy->type();
  255. }
  256. /// Returns if the type is compatible with the policy
  257. template<typename T>
  258. bool has_type()
  259. {
  260. return policy->type() == typeid(T);
  261. }
  262. const std::type_info& type() const
  263. {
  264. return policy->type();
  265. }
  266. friend std::ostream& operator <<(std::ostream& out, const any& any_val);
  267. };
  268. inline std::ostream& operator <<(std::ostream& out, const any& any_val)
  269. {
  270. any_val.policy->print(out,&any_val.object);
  271. return out;
  272. }
  273. }
  274. #endif // OPENCV_FLANN_ANY_H_