any.h 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  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() CV_OVERRIDE { return sizeof(T); }
  50. virtual const std::type_info& type() CV_OVERRIDE { return typeid(T); }
  51. };
  52. template<typename T>
  53. struct small_any_policy CV_FINAL : typed_base_any_policy<T>
  54. {
  55. virtual void static_delete(void**) CV_OVERRIDE { }
  56. virtual void copy_from_value(void const* src, void** dest) CV_OVERRIDE
  57. {
  58. new (dest) T(* reinterpret_cast<T const*>(src));
  59. }
  60. virtual void clone(void* const* src, void** dest) CV_OVERRIDE { *dest = *src; }
  61. virtual void move(void* const* src, void** dest) CV_OVERRIDE { *dest = *src; }
  62. virtual void* get_value(void** src) CV_OVERRIDE { return reinterpret_cast<void*>(src); }
  63. virtual const void* get_value(void* const * src) CV_OVERRIDE { return reinterpret_cast<const void*>(src); }
  64. virtual void print(std::ostream& out, void* const* src) CV_OVERRIDE { out << *reinterpret_cast<T const*>(src); }
  65. };
  66. template<typename T>
  67. struct big_any_policy CV_FINAL : typed_base_any_policy<T>
  68. {
  69. virtual void static_delete(void** x) CV_OVERRIDE
  70. {
  71. if (* x) delete (* reinterpret_cast<T**>(x));
  72. *x = NULL;
  73. }
  74. virtual void copy_from_value(void const* src, void** dest) CV_OVERRIDE
  75. {
  76. *dest = new T(*reinterpret_cast<T const*>(src));
  77. }
  78. virtual void clone(void* const* src, void** dest) CV_OVERRIDE
  79. {
  80. *dest = new T(**reinterpret_cast<T* const*>(src));
  81. }
  82. virtual void move(void* const* src, void** dest) CV_OVERRIDE
  83. {
  84. (*reinterpret_cast<T**>(dest))->~T();
  85. **reinterpret_cast<T**>(dest) = **reinterpret_cast<T* const*>(src);
  86. }
  87. virtual void* get_value(void** src) CV_OVERRIDE { return *src; }
  88. virtual const void* get_value(void* const * src) CV_OVERRIDE { return *src; }
  89. virtual void print(std::ostream& out, void* const* src) CV_OVERRIDE { out << *reinterpret_cast<T const*>(*src); }
  90. };
  91. template<> inline void big_any_policy<flann_centers_init_t>::print(std::ostream& out, void* const* src)
  92. {
  93. out << int(*reinterpret_cast<flann_centers_init_t const*>(*src));
  94. }
  95. template<> inline void big_any_policy<flann_algorithm_t>::print(std::ostream& out, void* const* src)
  96. {
  97. out << int(*reinterpret_cast<flann_algorithm_t const*>(*src));
  98. }
  99. template<> inline void big_any_policy<cv::String>::print(std::ostream& out, void* const* src)
  100. {
  101. out << (*reinterpret_cast<cv::String const*>(*src)).c_str();
  102. }
  103. template<typename T>
  104. struct choose_policy
  105. {
  106. typedef big_any_policy<T> type;
  107. };
  108. template<typename T>
  109. struct choose_policy<T*>
  110. {
  111. typedef small_any_policy<T*> type;
  112. };
  113. struct any;
  114. /// Choosing the policy for an any type is illegal, but should never happen.
  115. /// This is designed to throw a compiler error.
  116. template<>
  117. struct choose_policy<any>
  118. {
  119. typedef void type;
  120. };
  121. /// Specializations for small types.
  122. #define SMALL_POLICY(TYPE) \
  123. template<> \
  124. struct choose_policy<TYPE> { typedef small_any_policy<TYPE> type; \
  125. }
  126. SMALL_POLICY(signed char);
  127. SMALL_POLICY(unsigned char);
  128. SMALL_POLICY(signed short);
  129. SMALL_POLICY(unsigned short);
  130. SMALL_POLICY(signed int);
  131. SMALL_POLICY(unsigned int);
  132. SMALL_POLICY(signed long);
  133. SMALL_POLICY(unsigned long);
  134. SMALL_POLICY(float);
  135. SMALL_POLICY(bool);
  136. #undef SMALL_POLICY
  137. template <typename T>
  138. class SinglePolicy
  139. {
  140. SinglePolicy();
  141. SinglePolicy(const SinglePolicy& other);
  142. SinglePolicy& operator=(const SinglePolicy& other);
  143. public:
  144. static base_any_policy* get_policy();
  145. private:
  146. static typename choose_policy<T>::type policy;
  147. };
  148. template <typename T>
  149. typename choose_policy<T>::type SinglePolicy<T>::policy;
  150. /// This function will return a different policy for each type.
  151. template <typename T>
  152. inline base_any_policy* SinglePolicy<T>::get_policy() { return &policy; }
  153. } // namespace anyimpl
  154. struct any
  155. {
  156. private:
  157. // fields
  158. anyimpl::base_any_policy* policy;
  159. void* object;
  160. public:
  161. /// Initializing constructor.
  162. template <typename T>
  163. any(const T& x)
  164. : policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL)
  165. {
  166. assign(x);
  167. }
  168. /// Empty constructor.
  169. any()
  170. : policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL)
  171. { }
  172. /// Special initializing constructor for string literals.
  173. any(const char* x)
  174. : policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL)
  175. {
  176. assign(x);
  177. }
  178. /// Copy constructor.
  179. any(const any& x)
  180. : policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL)
  181. {
  182. assign(x);
  183. }
  184. /// Destructor.
  185. ~any()
  186. {
  187. policy->static_delete(&object);
  188. }
  189. /// Assignment function from another any.
  190. any& assign(const any& x)
  191. {
  192. reset();
  193. policy = x.policy;
  194. policy->clone(&x.object, &object);
  195. return *this;
  196. }
  197. /// Assignment function.
  198. template <typename T>
  199. any& assign(const T& x)
  200. {
  201. reset();
  202. policy = anyimpl::SinglePolicy<T>::get_policy();
  203. policy->copy_from_value(&x, &object);
  204. return *this;
  205. }
  206. /// Assignment operator.
  207. template<typename T>
  208. any& operator=(const T& x)
  209. {
  210. return assign(x);
  211. }
  212. /// Assignment operator. Template-based version above doesn't work as expected. We need regular assignment operator here.
  213. any& operator=(const any& x)
  214. {
  215. return assign(x);
  216. }
  217. /// Assignment operator, specialed for literal strings.
  218. /// They have types like const char [6] which don't work as expected.
  219. any& operator=(const char* x)
  220. {
  221. return assign(x);
  222. }
  223. /// Utility functions
  224. any& swap(any& x)
  225. {
  226. std::swap(policy, x.policy);
  227. std::swap(object, x.object);
  228. return *this;
  229. }
  230. /// Cast operator. You can only cast to the original type.
  231. template<typename T>
  232. T& cast()
  233. {
  234. if (policy->type() != typeid(T)) throw anyimpl::bad_any_cast();
  235. T* r = reinterpret_cast<T*>(policy->get_value(&object));
  236. return *r;
  237. }
  238. /// Cast operator. You can only cast to the original type.
  239. template<typename T>
  240. const T& cast() const
  241. {
  242. if (policy->type() != typeid(T)) throw anyimpl::bad_any_cast();
  243. const T* r = reinterpret_cast<const T*>(policy->get_value(&object));
  244. return *r;
  245. }
  246. /// Returns true if the any contains no value.
  247. bool empty() const
  248. {
  249. return policy->type() == typeid(anyimpl::empty_any);
  250. }
  251. /// Frees any allocated memory, and sets the value to NULL.
  252. void reset()
  253. {
  254. policy->static_delete(&object);
  255. policy = anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy();
  256. }
  257. /// Returns true if the two types are the same.
  258. bool compatible(const any& x) const
  259. {
  260. return policy->type() == x.policy->type();
  261. }
  262. /// Returns if the type is compatible with the policy
  263. template<typename T>
  264. bool has_type()
  265. {
  266. return policy->type() == typeid(T);
  267. }
  268. const std::type_info& type() const
  269. {
  270. return policy->type();
  271. }
  272. friend std::ostream& operator <<(std::ostream& out, const any& any_val);
  273. };
  274. inline std::ostream& operator <<(std::ostream& out, const any& any_val)
  275. {
  276. any_val.policy->print(out,&any_val.object);
  277. return out;
  278. }
  279. }
  280. #endif // OPENCV_FLANN_ANY_H_