any.h 9.1 KB

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