any.h 8.4 KB

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