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