]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libc++/include/any
Update to ELF Tool Chain r3668
[FreeBSD/FreeBSD.git] / contrib / libc++ / include / any
1 // -*- C++ -*-
2 //===------------------------------ any -----------------------------------===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10
11 #ifndef _LIBCPP_ANY
12 #define _LIBCPP_ANY
13
14 /*
15    any synopsis
16
17 namespace std {
18
19   class bad_any_cast : public bad_cast
20   {
21   public:
22     virtual const char* what() const noexcept;
23   };
24
25   class any
26   {
27   public:
28
29     // 6.3.1 any construct/destruct
30     any() noexcept;
31
32     any(const any& other);
33     any(any&& other) noexcept;
34
35     template <class ValueType>
36       any(ValueType&& value);
37
38     ~any();
39
40     // 6.3.2 any assignments
41     any& operator=(const any& rhs);
42     any& operator=(any&& rhs) noexcept;
43
44     template <class ValueType>
45       any& operator=(ValueType&& rhs);
46
47     // 6.3.3 any modifiers
48     template <class ValueType, class... Args>
49       decay_t<ValueType>& emplace(Args&&... args);
50     template <class ValueType, class U, class... Args>
51       decay_t<ValueType>& emplace(initializer_list<U>, Args&&...);
52     void reset() noexcept;
53     void swap(any& rhs) noexcept;
54
55     // 6.3.4 any observers
56     bool has_value() const noexcept;
57     const type_info& type() const noexcept;
58   };
59
60    // 6.4 Non-member functions
61   void swap(any& x, any& y) noexcept;
62
63   template <class T, class ...Args>
64     any make_any(Args&& ...args);
65   template <class T, class U, class ...Args>
66     any make_any(initializer_list<U>, Args&& ...args);
67
68   template<class ValueType>
69     ValueType any_cast(const any& operand);
70   template<class ValueType>
71     ValueType any_cast(any& operand);
72   template<class ValueType>
73     ValueType any_cast(any&& operand);
74
75   template<class ValueType>
76     const ValueType* any_cast(const any* operand) noexcept;
77   template<class ValueType>
78     ValueType* any_cast(any* operand) noexcept;
79
80 } // namespace std
81
82 */
83
84 #include <experimental/__config>
85 #include <memory>
86 #include <new>
87 #include <typeinfo>
88 #include <type_traits>
89 #include <cstdlib>
90
91 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
92 #pragma GCC system_header
93 #endif
94
95 namespace std {
96 class _LIBCPP_EXCEPTION_ABI bad_any_cast : public bad_cast
97 {
98 public:
99     virtual const char* what() const _NOEXCEPT;
100 };
101 } // namespace std
102
103 _LIBCPP_BEGIN_NAMESPACE_STD
104
105 #if _LIBCPP_STD_VER > 14
106
107 _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
108 void __throw_bad_any_cast()
109 {
110 #ifndef _LIBCPP_NO_EXCEPTIONS
111     throw bad_any_cast();
112 #else
113         _VSTD::abort();
114 #endif
115 }
116
117 // Forward declarations
118 class _LIBCPP_TEMPLATE_VIS any;
119
120 template <class _ValueType>
121 _LIBCPP_INLINE_VISIBILITY
122 add_pointer_t<add_const_t<_ValueType>>
123 any_cast(any const *) _NOEXCEPT;
124
125 template <class _ValueType>
126 _LIBCPP_INLINE_VISIBILITY
127 add_pointer_t<_ValueType> any_cast(any *) _NOEXCEPT;
128
129 namespace __any_imp
130 {
131   using _Buffer = aligned_storage_t<3*sizeof(void*), alignment_of<void*>::value>;
132
133   template <class _Tp>
134   using _IsSmallObject = integral_constant<bool
135         , sizeof(_Tp) <= sizeof(_Buffer)
136           && alignment_of<_Buffer>::value
137              % alignment_of<_Tp>::value == 0
138           && is_nothrow_move_constructible<_Tp>::value
139         >;
140
141   enum class _Action {
142     _Destroy,
143     _Copy,
144     _Move,
145     _Get,
146     _TypeInfo
147   };
148
149   template <class _Tp> struct _SmallHandler;
150   template <class _Tp> struct _LargeHandler;
151
152   template <class _Tp>
153   struct  _LIBCPP_TEMPLATE_VIS __unique_typeinfo { static constexpr int __id = 0; };
154   template <class _Tp> constexpr int __unique_typeinfo<_Tp>::__id;
155
156   template <class _Tp>
157   inline _LIBCPP_INLINE_VISIBILITY
158   constexpr const void* __get_fallback_typeid() {
159       return &__unique_typeinfo<decay_t<_Tp>>::__id;
160   }
161
162   template <class _Tp>
163   inline _LIBCPP_INLINE_VISIBILITY
164   bool __compare_typeid(type_info const* __id, const void* __fallback_id)
165   {
166 #if !defined(_LIBCPP_NO_RTTI)
167       if (__id && *__id == typeid(_Tp))
168           return true;
169 #endif
170       if (!__id && __fallback_id == __any_imp::__get_fallback_typeid<_Tp>())
171           return true;
172       return false;
173   }
174
175   template <class _Tp>
176   using _Handler = conditional_t<
177     _IsSmallObject<_Tp>::value, _SmallHandler<_Tp>, _LargeHandler<_Tp>>;
178
179 } // namespace __any_imp
180
181 class _LIBCPP_TEMPLATE_VIS any
182 {
183 public:
184   // construct/destruct
185   _LIBCPP_INLINE_VISIBILITY
186   constexpr any() _NOEXCEPT : __h(nullptr) {}
187
188   _LIBCPP_INLINE_VISIBILITY
189   any(any const & __other) : __h(nullptr)
190   {
191     if (__other.__h) __other.__call(_Action::_Copy, this);
192   }
193
194   _LIBCPP_INLINE_VISIBILITY
195   any(any && __other) _NOEXCEPT : __h(nullptr)
196   {
197     if (__other.__h) __other.__call(_Action::_Move, this);
198   }
199
200   template <
201       class _ValueType
202     , class _Tp = decay_t<_ValueType>
203     , class = enable_if_t<
204         !is_same<_Tp, any>::value &&
205         !__is_inplace_type<_ValueType>::value &&
206         is_copy_constructible<_Tp>::value>
207     >
208   _LIBCPP_INLINE_VISIBILITY
209   any(_ValueType && __value);
210
211   template <class _ValueType, class ..._Args,
212     class _Tp = decay_t<_ValueType>,
213     class = enable_if_t<
214         is_constructible<_Tp, _Args...>::value &&
215         is_copy_constructible<_Tp>::value
216     >
217   >
218   _LIBCPP_INLINE_VISIBILITY
219   explicit any(in_place_type_t<_ValueType>, _Args&&... __args);
220
221   template <class _ValueType, class _Up, class ..._Args,
222     class _Tp = decay_t<_ValueType>,
223     class = enable_if_t<
224         is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
225         is_copy_constructible<_Tp>::value>
226   >
227   _LIBCPP_INLINE_VISIBILITY
228   explicit any(in_place_type_t<_ValueType>, initializer_list<_Up>, _Args&&... __args);
229
230   _LIBCPP_INLINE_VISIBILITY
231   ~any() { this->reset(); }
232
233   // assignments
234   _LIBCPP_INLINE_VISIBILITY
235   any & operator=(any const & __rhs) {
236     any(__rhs).swap(*this);
237     return *this;
238   }
239
240   _LIBCPP_INLINE_VISIBILITY
241   any & operator=(any && __rhs) _NOEXCEPT {
242     any(_VSTD::move(__rhs)).swap(*this);
243     return *this;
244   }
245
246   template <
247       class _ValueType
248     , class _Tp = decay_t<_ValueType>
249     , class = enable_if_t<
250           !is_same<_Tp, any>::value
251           && is_copy_constructible<_Tp>::value>
252     >
253   _LIBCPP_INLINE_VISIBILITY
254   any & operator=(_ValueType && __rhs);
255
256   template <class _ValueType, class ..._Args,
257     class _Tp = decay_t<_ValueType>,
258     class = enable_if_t<
259         is_constructible<_Tp, _Args...>::value &&
260         is_copy_constructible<_Tp>::value>
261     >
262   _LIBCPP_INLINE_VISIBILITY
263   _Tp& emplace(_Args&&... args);
264
265   template <class _ValueType, class _Up, class ..._Args,
266     class _Tp = decay_t<_ValueType>,
267     class = enable_if_t<
268         is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
269         is_copy_constructible<_Tp>::value>
270   >
271   _LIBCPP_INLINE_VISIBILITY
272   _Tp& emplace(initializer_list<_Up>, _Args&&...);
273
274   // 6.3.3 any modifiers
275   _LIBCPP_INLINE_VISIBILITY
276   void reset() _NOEXCEPT { if (__h) this->__call(_Action::_Destroy); }
277
278   _LIBCPP_INLINE_VISIBILITY
279   void swap(any & __rhs) _NOEXCEPT;
280
281   // 6.3.4 any observers
282   _LIBCPP_INLINE_VISIBILITY
283   bool has_value() const _NOEXCEPT { return __h != nullptr; }
284
285 #if !defined(_LIBCPP_NO_RTTI)
286   _LIBCPP_INLINE_VISIBILITY
287   const type_info & type() const _NOEXCEPT {
288     if (__h) {
289         return *static_cast<type_info const *>(this->__call(_Action::_TypeInfo));
290     } else {
291         return typeid(void);
292     }
293   }
294 #endif
295
296 private:
297     typedef __any_imp::_Action _Action;
298     using _HandleFuncPtr =  void* (*)(_Action, any const *, any *, const type_info *,
299       const void* __fallback_info);
300
301     union _Storage {
302         constexpr _Storage() : __ptr(nullptr) {}
303         void *  __ptr;
304         __any_imp::_Buffer __buf;
305     };
306
307     _LIBCPP_INLINE_VISIBILITY
308     void * __call(_Action __a, any * __other = nullptr,
309                   type_info const * __info = nullptr,
310                    const void* __fallback_info = nullptr) const
311     {
312         return __h(__a, this, __other, __info, __fallback_info);
313     }
314
315     _LIBCPP_INLINE_VISIBILITY
316     void * __call(_Action __a, any * __other = nullptr,
317                   type_info const * __info = nullptr,
318                   const void* __fallback_info = nullptr)
319     {
320         return __h(__a, this, __other, __info, __fallback_info);
321     }
322
323     template <class>
324     friend struct __any_imp::_SmallHandler;
325     template <class>
326     friend struct __any_imp::_LargeHandler;
327
328     template <class _ValueType>
329     friend add_pointer_t<add_const_t<_ValueType>>
330     any_cast(any const *) _NOEXCEPT;
331
332     template <class _ValueType>
333     friend add_pointer_t<_ValueType>
334     any_cast(any *) _NOEXCEPT;
335
336     _HandleFuncPtr __h = nullptr;
337     _Storage __s;
338 };
339
340 namespace __any_imp
341 {
342   template <class _Tp>
343   struct _LIBCPP_TEMPLATE_VIS _SmallHandler
344   {
345      _LIBCPP_INLINE_VISIBILITY
346      static void* __handle(_Action __act, any const * __this, any * __other,
347                            type_info const * __info, const void* __fallback_info)
348      {
349         switch (__act)
350         {
351         case _Action::_Destroy:
352           __destroy(const_cast<any &>(*__this));
353           return nullptr;
354         case _Action::_Copy:
355             __copy(*__this, *__other);
356             return nullptr;
357         case _Action::_Move:
358           __move(const_cast<any &>(*__this), *__other);
359           return nullptr;
360         case _Action::_Get:
361             return __get(const_cast<any &>(*__this), __info, __fallback_info);
362         case _Action::_TypeInfo:
363           return __type_info();
364         }
365     }
366
367     template <class ..._Args>
368     _LIBCPP_INLINE_VISIBILITY
369     static _Tp& __create(any & __dest, _Args&&... __args) {
370         _Tp* __ret = ::new (static_cast<void*>(&__dest.__s.__buf)) _Tp(_VSTD::forward<_Args>(__args)...);
371         __dest.__h = &_SmallHandler::__handle;
372         return *__ret;
373     }
374
375   private:
376     _LIBCPP_INLINE_VISIBILITY
377     static void __destroy(any & __this) {
378         _Tp & __value = *static_cast<_Tp *>(static_cast<void*>(&__this.__s.__buf));
379         __value.~_Tp();
380         __this.__h = nullptr;
381     }
382
383     _LIBCPP_INLINE_VISIBILITY
384     static void __copy(any const & __this, any & __dest) {
385         _SmallHandler::__create(__dest, *static_cast<_Tp const *>(
386             static_cast<void const *>(&__this.__s.__buf)));
387     }
388
389     _LIBCPP_INLINE_VISIBILITY
390     static void __move(any & __this, any & __dest) {
391         _SmallHandler::__create(__dest, _VSTD::move(
392             *static_cast<_Tp*>(static_cast<void*>(&__this.__s.__buf))));
393         __destroy(__this);
394     }
395
396     _LIBCPP_INLINE_VISIBILITY
397     static void* __get(any & __this,
398                        type_info const * __info,
399                        const void* __fallback_id)
400     {
401         if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_id))
402             return static_cast<void*>(&__this.__s.__buf);
403         return nullptr;
404     }
405
406     _LIBCPP_INLINE_VISIBILITY
407     static void* __type_info()
408     {
409 #if !defined(_LIBCPP_NO_RTTI)
410         return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));
411 #else
412         return nullptr;
413 #endif
414     }
415   };
416
417   template <class _Tp>
418   struct _LIBCPP_TEMPLATE_VIS _LargeHandler
419   {
420     _LIBCPP_INLINE_VISIBILITY
421     static void* __handle(_Action __act, any const * __this,
422                           any * __other, type_info const * __info,
423                           void const* __fallback_info)
424     {
425         switch (__act)
426         {
427         case _Action::_Destroy:
428           __destroy(const_cast<any &>(*__this));
429           return nullptr;
430         case _Action::_Copy:
431           __copy(*__this, *__other);
432           return nullptr;
433         case _Action::_Move:
434           __move(const_cast<any &>(*__this), *__other);
435           return nullptr;
436         case _Action::_Get:
437             return __get(const_cast<any &>(*__this), __info, __fallback_info);
438         case _Action::_TypeInfo:
439           return __type_info();
440         }
441     }
442
443     template <class ..._Args>
444     _LIBCPP_INLINE_VISIBILITY
445     static _Tp& __create(any & __dest, _Args&&... __args) {
446         typedef allocator<_Tp> _Alloc;
447         typedef __allocator_destructor<_Alloc> _Dp;
448         _Alloc __a;
449         unique_ptr<_Tp, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
450         _Tp* __ret = ::new ((void*)__hold.get()) _Tp(_VSTD::forward<_Args>(__args)...);
451         __dest.__s.__ptr = __hold.release();
452         __dest.__h = &_LargeHandler::__handle;
453         return *__ret;
454     }
455
456   private:
457
458     _LIBCPP_INLINE_VISIBILITY
459     static void __destroy(any & __this){
460         delete static_cast<_Tp*>(__this.__s.__ptr);
461         __this.__h = nullptr;
462     }
463
464     _LIBCPP_INLINE_VISIBILITY
465     static void __copy(any const & __this, any & __dest) {
466         _LargeHandler::__create(__dest, *static_cast<_Tp const *>(__this.__s.__ptr));
467     }
468
469     _LIBCPP_INLINE_VISIBILITY
470     static void __move(any & __this, any & __dest) {
471       __dest.__s.__ptr = __this.__s.__ptr;
472       __dest.__h = &_LargeHandler::__handle;
473       __this.__h = nullptr;
474     }
475
476     _LIBCPP_INLINE_VISIBILITY
477     static void* __get(any & __this, type_info const * __info,
478                        void const* __fallback_info)
479     {
480         if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_info))
481             return static_cast<void*>(__this.__s.__ptr);
482         return nullptr;
483
484     }
485
486     _LIBCPP_INLINE_VISIBILITY
487     static void* __type_info()
488     {
489 #if !defined(_LIBCPP_NO_RTTI)
490         return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));
491 #else
492         return nullptr;
493 #endif
494     }
495   };
496
497 } // namespace __any_imp
498
499
500 template <class _ValueType, class _Tp, class>
501 any::any(_ValueType && __v) : __h(nullptr)
502 {
503   __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_ValueType>(__v));
504 }
505
506 template <class _ValueType, class ..._Args, class _Tp, class>
507 any::any(in_place_type_t<_ValueType>, _Args&&... __args) {
508   __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...);
509 };
510
511 template <class _ValueType, class _Up, class ..._Args, class _Tp, class>
512 any::any(in_place_type_t<_ValueType>, initializer_list<_Up> __il, _Args&&... __args) {
513   __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...);
514 }
515
516 template <class _ValueType, class, class>
517 inline _LIBCPP_INLINE_VISIBILITY
518 any & any::operator=(_ValueType && __v)
519 {
520   any(_VSTD::forward<_ValueType>(__v)).swap(*this);
521   return *this;
522 }
523
524 template <class _ValueType, class ..._Args, class _Tp, class>
525 inline _LIBCPP_INLINE_VISIBILITY
526 _Tp& any::emplace(_Args&&... __args) {
527   reset();
528   return __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...);
529 }
530
531 template <class _ValueType, class _Up, class ..._Args, class _Tp, class>
532 inline _LIBCPP_INLINE_VISIBILITY
533 _Tp& any::emplace(initializer_list<_Up> __il, _Args&&... __args) {
534   reset();
535   return __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...);
536 }
537
538 inline _LIBCPP_INLINE_VISIBILITY
539 void any::swap(any & __rhs) _NOEXCEPT
540 {
541     if (this == &__rhs)
542       return;
543     if (__h && __rhs.__h) {
544         any __tmp;
545         __rhs.__call(_Action::_Move, &__tmp);
546         this->__call(_Action::_Move, &__rhs);
547         __tmp.__call(_Action::_Move, this);
548     }
549     else if (__h) {
550         this->__call(_Action::_Move, &__rhs);
551     }
552     else if (__rhs.__h) {
553         __rhs.__call(_Action::_Move, this);
554     }
555 }
556
557 // 6.4 Non-member functions
558
559 inline _LIBCPP_INLINE_VISIBILITY
560 void swap(any & __lhs, any & __rhs) _NOEXCEPT
561 {
562     __lhs.swap(__rhs);
563 }
564
565 template <class _Tp, class ..._Args>
566 inline _LIBCPP_INLINE_VISIBILITY
567 any make_any(_Args&&... __args) {
568     return any(in_place_type<_Tp>, _VSTD::forward<_Args>(__args)...);
569 }
570
571 template <class _Tp, class _Up, class ..._Args>
572 inline _LIBCPP_INLINE_VISIBILITY
573 any make_any(initializer_list<_Up> __il, _Args&&... __args) {
574     return any(in_place_type<_Tp>, __il, _VSTD::forward<_Args>(__args)...);
575 }
576
577 template <class _ValueType>
578 inline _LIBCPP_INLINE_VISIBILITY
579 _ValueType any_cast(any const & __v)
580 {
581     using _RawValueType = __uncvref_t<_ValueType>;
582     static_assert(is_constructible<_ValueType, _RawValueType const &>::value,
583                   "ValueType is required to be a const lvalue reference "
584                   "or a CopyConstructible type");
585     auto __tmp = _VSTD::any_cast<add_const_t<_RawValueType>>(&__v);
586     if (__tmp == nullptr)
587         __throw_bad_any_cast();
588     return static_cast<_ValueType>(*__tmp);
589 }
590
591 template <class _ValueType>
592 inline _LIBCPP_INLINE_VISIBILITY
593 _ValueType any_cast(any & __v)
594 {
595     using _RawValueType = __uncvref_t<_ValueType>;
596     static_assert(is_constructible<_ValueType, _RawValueType &>::value,
597                   "ValueType is required to be an lvalue reference "
598                   "or a CopyConstructible type");
599     auto __tmp = _VSTD::any_cast<_RawValueType>(&__v);
600     if (__tmp == nullptr)
601         __throw_bad_any_cast();
602     return static_cast<_ValueType>(*__tmp);
603 }
604
605 template <class _ValueType>
606 inline _LIBCPP_INLINE_VISIBILITY
607 _ValueType any_cast(any && __v)
608 {
609     using _RawValueType = __uncvref_t<_ValueType>;
610     static_assert(is_constructible<_ValueType, _RawValueType>::value,
611                   "ValueType is required to be an rvalue reference "
612                   "or a CopyConstructible type");
613     auto __tmp = _VSTD::any_cast<_RawValueType>(&__v);
614     if (__tmp == nullptr)
615         __throw_bad_any_cast();
616     return static_cast<_ValueType>(_VSTD::move(*__tmp));
617 }
618
619 template <class _ValueType>
620 inline _LIBCPP_INLINE_VISIBILITY
621 add_pointer_t<add_const_t<_ValueType>>
622 any_cast(any const * __any) _NOEXCEPT
623 {
624     static_assert(!is_reference<_ValueType>::value,
625                   "_ValueType may not be a reference.");
626     return _VSTD::any_cast<_ValueType>(const_cast<any *>(__any));
627 }
628
629 template <class _RetType>
630 inline _LIBCPP_INLINE_VISIBILITY
631 _RetType __pointer_or_func_cast(void* __p, /*IsFunction*/false_type) noexcept {
632   return static_cast<_RetType>(__p);
633 }
634
635 template <class _RetType>
636 inline _LIBCPP_INLINE_VISIBILITY
637 _RetType __pointer_or_func_cast(void*, /*IsFunction*/true_type) noexcept {
638   return nullptr;
639 }
640
641 template <class _ValueType>
642 add_pointer_t<_ValueType>
643 any_cast(any * __any) _NOEXCEPT
644 {
645     using __any_imp::_Action;
646     static_assert(!is_reference<_ValueType>::value,
647                   "_ValueType may not be a reference.");
648     typedef typename add_pointer<_ValueType>::type _ReturnType;
649     if (__any && __any->__h) {
650       void *__p = __any->__call(_Action::_Get, nullptr,
651 #if !defined(_LIBCPP_NO_RTTI)
652                           &typeid(_ValueType),
653 #else
654                           nullptr,
655 #endif
656                           __any_imp::__get_fallback_typeid<_ValueType>());
657         return _VSTD::__pointer_or_func_cast<_ReturnType>(
658             __p, is_function<_ValueType>{});
659     }
660     return nullptr;
661 }
662
663 #endif // _LIBCPP_STD_VER > 14
664
665 _LIBCPP_END_NAMESPACE_STD
666
667 #endif // _LIBCPP_ANY