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