]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | ////////////////////////////////////////////////////////////////////////////// |
2 | // | |
3 | // (C) Copyright Ion Gaztanaga 2012-2012. | |
4 | // Distributed under the Boost Software License, Version 1.0. | |
5 | // (See accompanying file LICENSE_1_0.txt or copy at | |
6 | // http://www.boost.org/LICENSE_1_0.txt) | |
7 | // | |
8 | // See http://www.boost.org/libs/move for documentation. | |
9 | // | |
10 | ////////////////////////////////////////////////////////////////////////////// | |
11 | ||
12 | //! \file | |
13 | ||
14 | #ifndef BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP | |
15 | #define BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP | |
16 | ||
17 | #ifndef BOOST_CONFIG_HPP | |
18 | # include <boost/config.hpp> | |
19 | #endif | |
20 | # | |
21 | #if defined(BOOST_HAS_PRAGMA_ONCE) | |
22 | # pragma once | |
23 | #endif | |
24 | ||
25 | #include <cstddef> //for std::size_t | |
26 | ||
27 | //Small meta-typetraits to support move | |
28 | ||
29 | namespace boost { | |
30 | ||
31 | namespace movelib { | |
32 | ||
33 | template <class T> | |
34 | struct default_delete; | |
35 | ||
36 | } //namespace movelib { | |
37 | ||
38 | #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES | |
39 | //Forward declare boost::rv | |
40 | template <class T> class rv; | |
41 | #endif | |
42 | ||
43 | namespace move_upmu { | |
44 | ||
45 | ////////////////////////////////////// | |
46 | // nat | |
47 | ////////////////////////////////////// | |
48 | struct nat{}; | |
49 | ||
50 | ////////////////////////////////////// | |
51 | // natify | |
52 | ////////////////////////////////////// | |
53 | template <class T> struct natify{}; | |
54 | ||
55 | ////////////////////////////////////// | |
56 | // if_c | |
57 | ////////////////////////////////////// | |
58 | template<bool C, typename T1, typename T2> | |
59 | struct if_c | |
60 | { | |
61 | typedef T1 type; | |
62 | }; | |
63 | ||
64 | template<typename T1, typename T2> | |
65 | struct if_c<false,T1,T2> | |
66 | { | |
67 | typedef T2 type; | |
68 | }; | |
69 | ||
70 | ////////////////////////////////////// | |
71 | // if_ | |
72 | ////////////////////////////////////// | |
73 | template<typename T1, typename T2, typename T3> | |
74 | struct if_ : if_c<0 != T1::value, T2, T3> | |
75 | {}; | |
76 | ||
77 | //enable_if_ | |
78 | template <bool B, class T = nat> | |
79 | struct enable_if_c | |
80 | { | |
81 | typedef T type; | |
82 | }; | |
83 | ||
84 | ////////////////////////////////////// | |
85 | // enable_if_c | |
86 | ////////////////////////////////////// | |
87 | template <class T> | |
88 | struct enable_if_c<false, T> {}; | |
89 | ||
90 | ////////////////////////////////////// | |
91 | // enable_if | |
92 | ////////////////////////////////////// | |
93 | template <class Cond, class T = nat> | |
94 | struct enable_if : public enable_if_c<Cond::value, T> {}; | |
95 | ||
96 | ////////////////////////////////////// | |
97 | // remove_reference | |
98 | ////////////////////////////////////// | |
99 | template<class T> | |
100 | struct remove_reference | |
101 | { | |
102 | typedef T type; | |
103 | }; | |
104 | ||
105 | template<class T> | |
106 | struct remove_reference<T&> | |
107 | { | |
108 | typedef T type; | |
109 | }; | |
110 | ||
111 | #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES | |
112 | ||
113 | template<class T> | |
114 | struct remove_reference<T&&> | |
115 | { | |
116 | typedef T type; | |
117 | }; | |
118 | ||
119 | #else | |
120 | ||
121 | template<class T> | |
122 | struct remove_reference< rv<T> > | |
123 | { | |
124 | typedef T type; | |
125 | }; | |
126 | ||
127 | template<class T> | |
128 | struct remove_reference< rv<T> &> | |
129 | { | |
130 | typedef T type; | |
131 | }; | |
132 | ||
133 | template<class T> | |
134 | struct remove_reference< const rv<T> &> | |
135 | { | |
136 | typedef T type; | |
137 | }; | |
138 | ||
139 | ||
140 | #endif | |
141 | ||
142 | ////////////////////////////////////// | |
143 | // remove_const | |
144 | ////////////////////////////////////// | |
145 | template< class T > | |
146 | struct remove_const | |
147 | { | |
148 | typedef T type; | |
149 | }; | |
150 | ||
151 | template< class T > | |
152 | struct remove_const<const T> | |
153 | { | |
154 | typedef T type; | |
155 | }; | |
156 | ||
157 | ////////////////////////////////////// | |
158 | // remove_volatile | |
159 | ////////////////////////////////////// | |
160 | template< class T > | |
161 | struct remove_volatile | |
162 | { | |
163 | typedef T type; | |
164 | }; | |
165 | ||
166 | template< class T > | |
167 | struct remove_volatile<volatile T> | |
168 | { | |
169 | typedef T type; | |
170 | }; | |
171 | ||
172 | ////////////////////////////////////// | |
173 | // remove_cv | |
174 | ////////////////////////////////////// | |
175 | template< class T > | |
176 | struct remove_cv | |
177 | { | |
178 | typedef typename remove_volatile | |
179 | <typename remove_const<T>::type>::type type; | |
180 | }; | |
181 | ||
182 | ////////////////////////////////////// | |
183 | // remove_extent | |
184 | ////////////////////////////////////// | |
185 | template<class T> | |
186 | struct remove_extent | |
187 | { | |
188 | typedef T type; | |
189 | }; | |
190 | ||
191 | template<class T> | |
192 | struct remove_extent<T[]> | |
193 | { | |
194 | typedef T type; | |
195 | }; | |
196 | ||
197 | template<class T, std::size_t N> | |
198 | struct remove_extent<T[N]> | |
199 | { | |
200 | typedef T type; | |
201 | }; | |
202 | ||
203 | ////////////////////////////////////// | |
204 | // extent | |
205 | ////////////////////////////////////// | |
206 | ||
207 | template<class T, unsigned N = 0> | |
208 | struct extent | |
209 | { | |
210 | static const std::size_t value = 0; | |
211 | }; | |
212 | ||
213 | template<class T> | |
214 | struct extent<T[], 0> | |
215 | { | |
216 | static const std::size_t value = 0; | |
217 | }; | |
218 | ||
219 | template<class T, unsigned N> | |
220 | struct extent<T[], N> | |
221 | { | |
222 | static const std::size_t value = extent<T, N-1>::value; | |
223 | }; | |
224 | ||
225 | template<class T, std::size_t N> | |
226 | struct extent<T[N], 0> | |
227 | { | |
228 | static const std::size_t value = N; | |
229 | }; | |
230 | ||
231 | template<class T, std::size_t I, unsigned N> | |
232 | struct extent<T[I], N> | |
233 | { | |
234 | static const std::size_t value = extent<T, N-1>::value; | |
235 | }; | |
236 | ||
237 | ////////////////////////////////////// | |
238 | // add_lvalue_reference | |
239 | ////////////////////////////////////// | |
240 | template<class T> | |
241 | struct add_lvalue_reference | |
242 | { | |
243 | typedef T& type; | |
244 | }; | |
245 | ||
246 | template<class T> | |
247 | struct add_lvalue_reference<T&> | |
248 | { | |
249 | typedef T& type; | |
250 | }; | |
251 | ||
252 | template<> | |
253 | struct add_lvalue_reference<void> | |
254 | { | |
255 | typedef void type; | |
256 | }; | |
257 | ||
258 | template<> | |
259 | struct add_lvalue_reference<const void> | |
260 | { | |
261 | typedef const void type; | |
262 | }; | |
263 | ||
264 | template<> | |
265 | struct add_lvalue_reference<volatile void> | |
266 | { | |
267 | typedef volatile void type; | |
268 | }; | |
269 | ||
270 | template<> | |
271 | struct add_lvalue_reference<const volatile void> | |
272 | { | |
273 | typedef const volatile void type; | |
274 | }; | |
275 | ||
276 | template<class T> | |
277 | struct add_const_lvalue_reference | |
278 | { | |
279 | typedef typename remove_reference<T>::type t_unreferenced; | |
280 | typedef const t_unreferenced t_unreferenced_const; | |
281 | typedef typename add_lvalue_reference | |
282 | <t_unreferenced_const>::type type; | |
283 | }; | |
284 | ||
285 | ////////////////////////////////////// | |
286 | // is_same | |
287 | ////////////////////////////////////// | |
288 | template<class T, class U> | |
289 | struct is_same | |
290 | { | |
291 | static const bool value = false; | |
292 | }; | |
293 | ||
294 | template<class T> | |
295 | struct is_same<T, T> | |
296 | { | |
297 | static const bool value = true; | |
298 | }; | |
299 | ||
300 | ////////////////////////////////////// | |
301 | // is_pointer | |
302 | ////////////////////////////////////// | |
303 | template< class T > | |
304 | struct is_pointer | |
305 | { | |
306 | static const bool value = false; | |
307 | }; | |
308 | ||
309 | template< class T > | |
310 | struct is_pointer<T*> | |
311 | { | |
312 | static const bool value = true; | |
313 | }; | |
314 | ||
315 | ////////////////////////////////////// | |
316 | // is_reference | |
317 | ////////////////////////////////////// | |
318 | template< class T > | |
319 | struct is_reference | |
320 | { | |
321 | static const bool value = false; | |
322 | }; | |
323 | ||
324 | template< class T > | |
325 | struct is_reference<T&> | |
326 | { | |
327 | static const bool value = true; | |
328 | }; | |
329 | ||
330 | #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES | |
331 | ||
332 | template< class T > | |
333 | struct is_reference<T&&> | |
334 | { | |
335 | static const bool value = true; | |
336 | }; | |
337 | ||
338 | #endif | |
339 | ||
340 | ////////////////////////////////////// | |
341 | // is_lvalue_reference | |
342 | ////////////////////////////////////// | |
343 | template<class T> | |
344 | struct is_lvalue_reference | |
345 | { | |
346 | static const bool value = false; | |
347 | }; | |
348 | ||
349 | template<class T> | |
350 | struct is_lvalue_reference<T&> | |
351 | { | |
352 | static const bool value = true; | |
353 | }; | |
354 | ||
355 | ////////////////////////////////////// | |
356 | // is_array | |
357 | ////////////////////////////////////// | |
358 | template<class T> | |
359 | struct is_array | |
360 | { | |
361 | static const bool value = false; | |
362 | }; | |
363 | ||
364 | template<class T> | |
365 | struct is_array<T[]> | |
366 | { | |
367 | static const bool value = true; | |
368 | }; | |
369 | ||
370 | template<class T, std::size_t N> | |
371 | struct is_array<T[N]> | |
372 | { | |
373 | static const bool value = true; | |
374 | }; | |
375 | ||
376 | ////////////////////////////////////// | |
377 | // has_pointer_type | |
378 | ////////////////////////////////////// | |
379 | template <class T> | |
380 | struct has_pointer_type | |
381 | { | |
382 | struct two { char c[2]; }; | |
383 | template <class U> static two test(...); | |
384 | template <class U> static char test(typename U::pointer* = 0); | |
385 | static const bool value = sizeof(test<T>(0)) == 1; | |
386 | }; | |
387 | ||
388 | ////////////////////////////////////// | |
389 | // pointer_type | |
390 | ////////////////////////////////////// | |
391 | template <class T, class D, bool = has_pointer_type<D>::value> | |
392 | struct pointer_type_imp | |
393 | { | |
394 | typedef typename D::pointer type; | |
395 | }; | |
396 | ||
397 | template <class T, class D> | |
398 | struct pointer_type_imp<T, D, false> | |
399 | { | |
400 | typedef typename remove_extent<T>::type* type; | |
401 | }; | |
402 | ||
403 | template <class T, class D> | |
404 | struct pointer_type | |
405 | { | |
406 | typedef typename pointer_type_imp | |
407 | <typename remove_extent<T>::type, typename remove_reference<D>::type>::type type; | |
408 | }; | |
409 | ||
410 | ////////////////////////////////////// | |
411 | // is_convertible | |
412 | ////////////////////////////////////// | |
413 | #if defined(_MSC_VER) && (_MSC_VER >= 1400) | |
414 | ||
415 | //use intrinsic since in MSVC | |
416 | //overaligned types can't go through ellipsis | |
417 | template <class T, class U> | |
418 | struct is_convertible | |
419 | { | |
420 | static const bool value = __is_convertible_to(T, U); | |
421 | }; | |
422 | ||
423 | #else | |
424 | ||
425 | template <class T, class U> | |
426 | class is_convertible | |
427 | { | |
428 | typedef typename add_lvalue_reference<T>::type t_reference; | |
429 | typedef char true_t; | |
430 | class false_t { char dummy[2]; }; | |
431 | static false_t dispatch(...); | |
432 | static true_t dispatch(U); | |
433 | static t_reference trigger(); | |
434 | public: | |
435 | static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t); | |
436 | }; | |
437 | ||
438 | #endif | |
439 | ||
440 | ////////////////////////////////////// | |
441 | // is_unary_function | |
442 | ////////////////////////////////////// | |
443 | #if defined(BOOST_MSVC) || defined(__BORLANDC_) | |
444 | #define BOOST_MOVE_TT_DECL __cdecl | |
445 | #else | |
446 | #define BOOST_MOVE_TT_DECL | |
447 | #endif | |
448 | ||
449 | #if defined(_MSC_EXTENSIONS) && !defined(__BORLAND__) && !defined(_WIN64) && !defined(_M_ARM) && !defined(UNDER_CE) | |
450 | #define BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS | |
451 | #endif | |
452 | ||
453 | template <typename T> | |
454 | struct is_unary_function_impl | |
455 | { static const bool value = false; }; | |
456 | ||
457 | // avoid duplicate definitions of is_unary_function_impl | |
458 | #ifndef BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS | |
459 | ||
460 | template <typename R> | |
461 | struct is_unary_function_impl<R (*)()> | |
462 | { static const bool value = true; }; | |
463 | ||
464 | template <typename R> | |
465 | struct is_unary_function_impl<R (*)(...)> | |
466 | { static const bool value = true; }; | |
467 | ||
468 | #else // BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS | |
469 | ||
470 | template <typename R> | |
471 | struct is_unary_function_impl<R (__stdcall*)()> | |
472 | { static const bool value = true; }; | |
473 | ||
474 | #ifndef _MANAGED | |
475 | ||
476 | template <typename R> | |
477 | struct is_unary_function_impl<R (__fastcall*)()> | |
478 | { static const bool value = true; }; | |
479 | ||
480 | #endif | |
481 | ||
482 | template <typename R> | |
483 | struct is_unary_function_impl<R (__cdecl*)()> | |
484 | { static const bool value = true; }; | |
485 | ||
486 | template <typename R> | |
487 | struct is_unary_function_impl<R (__cdecl*)(...)> | |
488 | { static const bool value = true; }; | |
489 | ||
490 | #endif | |
491 | ||
492 | // avoid duplicate definitions of is_unary_function_impl | |
493 | #ifndef BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS | |
494 | ||
495 | template <typename R, class T0> | |
496 | struct is_unary_function_impl<R (*)(T0)> | |
497 | { static const bool value = true; }; | |
498 | ||
499 | template <typename R, class T0> | |
500 | struct is_unary_function_impl<R (*)(T0...)> | |
501 | { static const bool value = true; }; | |
502 | ||
503 | #else // BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS | |
504 | ||
505 | template <typename R, class T0> | |
506 | struct is_unary_function_impl<R (__stdcall*)(T0)> | |
507 | { static const bool value = true; }; | |
508 | ||
509 | #ifndef _MANAGED | |
510 | ||
511 | template <typename R, class T0> | |
512 | struct is_unary_function_impl<R (__fastcall*)(T0)> | |
513 | { static const bool value = true; }; | |
514 | ||
515 | #endif | |
516 | ||
517 | template <typename R, class T0> | |
518 | struct is_unary_function_impl<R (__cdecl*)(T0)> | |
519 | { static const bool value = true; }; | |
520 | ||
521 | template <typename R, class T0> | |
522 | struct is_unary_function_impl<R (__cdecl*)(T0...)> | |
523 | { static const bool value = true; }; | |
524 | ||
525 | #endif | |
526 | ||
527 | template <typename T> | |
528 | struct is_unary_function_impl<T&> | |
529 | { static const bool value = false; }; | |
530 | ||
531 | template<typename T> | |
532 | struct is_unary_function | |
533 | { static const bool value = is_unary_function_impl<T>::value; }; | |
534 | ||
535 | ////////////////////////////////////// | |
536 | // has_virtual_destructor | |
537 | ////////////////////////////////////// | |
538 | #if (defined(BOOST_MSVC) && defined(BOOST_MSVC_FULL_VER) && (BOOST_MSVC_FULL_VER >=140050215))\ | |
539 | || (defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1500)) | |
540 | # define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T) | |
541 | #elif defined(BOOST_CLANG) && defined(__has_feature) | |
542 | # if __has_feature(has_virtual_destructor) | |
543 | # define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T) | |
544 | # endif | |
545 | #elif defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3) && !defined(__GCCXML__))) && !defined(BOOST_CLANG) | |
546 | # define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T) | |
547 | #elif defined(__ghs__) && (__GHS_VERSION_NUMBER >= 600) | |
548 | # define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T) | |
549 | #elif defined(__CODEGEARC__) | |
550 | # define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T) | |
551 | #endif | |
552 | ||
553 | #ifdef BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR | |
554 | template<class T> | |
555 | struct has_virtual_destructor{ static const bool value = BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T); }; | |
556 | #else | |
557 | //If no intrinsic is available you trust the programmer knows what is doing | |
558 | template<class T> | |
559 | struct has_virtual_destructor{ static const bool value = true; }; | |
560 | #endif | |
561 | ||
562 | ////////////////////////////////////// | |
563 | // missing_virtual_destructor | |
564 | ////////////////////////////////////// | |
565 | ||
566 | template< class T, class U | |
567 | , bool enable = is_convertible< U*, T*>::value && | |
568 | !is_array<T>::value && | |
569 | !is_same<typename remove_cv<T>::type, void>::value && | |
570 | !is_same<typename remove_cv<U>::type, typename remove_cv<T>::type>::value | |
571 | > | |
572 | struct missing_virtual_destructor_default_delete | |
573 | { static const bool value = !has_virtual_destructor<T>::value; }; | |
574 | ||
575 | template<class T, class U> | |
576 | struct missing_virtual_destructor_default_delete<T, U, false> | |
577 | { static const bool value = false; }; | |
578 | ||
579 | template<class Deleter, class U> | |
580 | struct missing_virtual_destructor | |
581 | { static const bool value = false; }; | |
582 | ||
583 | template<class T, class U> | |
584 | struct missing_virtual_destructor< ::boost::movelib::default_delete<T>, U > | |
585 | : missing_virtual_destructor_default_delete<T, U> | |
586 | {}; | |
587 | ||
588 | } //namespace move_upmu { | |
589 | } //namespace boost { | |
590 | ||
591 | #endif //#ifndef BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP |