Imported Upstream version 1.64.0
[platform/upstream/boost.git] / boost / move / detail / unique_ptr_meta_utils.hpp
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 T* 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