1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_ANY
11#define _LIBCPP_ANY
12
13/*
14 any synopsis
15
16namespace std {
17
18 class bad_any_cast : public bad_cast
19 {
20 public:
21 virtual const char* what() const noexcept;
22 };
23
24 class any
25 {
26 public:
27
28 // 6.3.1 any construct/destruct
29 any() noexcept;
30
31 any(const any& other);
32 any(any&& other) noexcept;
33
34 template <class ValueType>
35 any(ValueType&& value);
36
37 ~any();
38
39 // 6.3.2 any assignments
40 any& operator=(const any& rhs);
41 any& operator=(any&& rhs) noexcept;
42
43 template <class ValueType>
44 any& operator=(ValueType&& rhs);
45
46 // 6.3.3 any modifiers
47 template <class ValueType, class... Args>
48 decay_t<ValueType>& emplace(Args&&... args);
49 template <class ValueType, class U, class... Args>
50 decay_t<ValueType>& emplace(initializer_list<U>, Args&&...);
51 void reset() noexcept;
52 void swap(any& rhs) noexcept;
53
54 // 6.3.4 any observers
55 bool has_value() const noexcept;
56 const type_info& type() const noexcept;
57 };
58
59 // 6.4 Non-member functions
60 void swap(any& x, any& y) noexcept;
61
62 template <class T, class ...Args>
63 any make_any(Args&& ...args);
64 template <class T, class U, class ...Args>
65 any make_any(initializer_list<U>, Args&& ...args);
66
67 template<class ValueType>
68 ValueType any_cast(const any& operand);
69 template<class ValueType>
70 ValueType any_cast(any& operand);
71 template<class ValueType>
72 ValueType any_cast(any&& operand);
73
74 template<class ValueType>
75 const ValueType* any_cast(const any* operand) noexcept;
76 template<class ValueType>
77 ValueType* any_cast(any* operand) noexcept;
78
79} // namespace std
80
81*/
82
83#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
84# include <__cxx03/__config>
85#else
86# include <__config>
87# include <__memory/construct_at.h>
88# include <__new/allocate.h>
89# include <__type_traits/add_cv_quals.h>
90# include <__type_traits/add_pointer.h>
91# include <__type_traits/conditional.h>
92# include <__type_traits/conjunction.h>
93# include <__type_traits/decay.h>
94# include <__type_traits/enable_if.h>
95# include <__type_traits/is_constructible.h>
96# include <__type_traits/is_function.h>
97# include <__type_traits/is_nothrow_constructible.h>
98# include <__type_traits/is_reference.h>
99# include <__type_traits/is_same.h>
100# include <__type_traits/is_void.h>
101# include <__type_traits/negation.h>
102# include <__type_traits/remove_cv.h>
103# include <__type_traits/remove_cvref.h>
104# include <__type_traits/remove_reference.h>
105# include <__utility/exception_guard.h>
106# include <__utility/forward.h>
107# include <__utility/in_place.h>
108# include <__utility/move.h>
109# include <__utility/unreachable.h>
110# include <__verbose_abort>
111# include <initializer_list>
112# include <typeinfo>
113# include <version>
114
115# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
116# pragma GCC system_header
117# endif
118
119_LIBCPP_PUSH_MACROS
120# include <__undef_macros>
121
122_LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD
123_LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS
124
125class _LIBCPP_EXPORTED_FROM_ABI bad_any_cast : public bad_cast {
126public:
127 const char* what() const _NOEXCEPT override;
128};
129
130_LIBCPP_END_EXPLICIT_ABI_ANNOTATIONS
131_LIBCPP_END_UNVERSIONED_NAMESPACE_STD
132
133# if _LIBCPP_STD_VER >= 17
134
135_LIBCPP_BEGIN_NAMESPACE_STD
136
137[[noreturn]] inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_any_cast() {
138# if _LIBCPP_HAS_EXCEPTIONS
139 throw bad_any_cast();
140# else
141 _LIBCPP_VERBOSE_ABORT("bad_any_cast was thrown in -fno-exceptions mode");
142# endif
143}
144
145// Forward declarations
146class any;
147
148template <class _ValueType>
149_LIBCPP_HIDE_FROM_ABI add_pointer_t<add_const_t<_ValueType>> any_cast(any const*) noexcept;
150
151template <class _ValueType>
152_LIBCPP_HIDE_FROM_ABI add_pointer_t<_ValueType> any_cast(any*) noexcept;
153
154namespace __any_imp {
155inline constexpr size_t __small_buffer_size = 3 * sizeof(void*);
156inline constexpr size_t __small_buffer_alignment = alignof(void*);
157
158template <class _Tp>
159using _IsSmallObject _LIBCPP_NODEBUG =
160 integral_constant<bool,
161 sizeof(_Tp) <= __small_buffer_size && alignof(_Tp) <= __small_buffer_alignment &&
162 is_nothrow_move_constructible_v<_Tp>>;
163
164enum class _Action { _Destroy, _Copy, _Move, _Get, _TypeInfo };
165
166template <class _Tp>
167struct _SmallHandler;
168template <class _Tp>
169struct _LargeHandler;
170
171template <class _Tp>
172struct __unique_typeinfo {
173 static constexpr int __id = 0;
174};
175
176template <class _Tp>
177inline _LIBCPP_HIDE_FROM_ABI constexpr const void* __get_fallback_typeid() {
178 return &__unique_typeinfo<remove_cv_t<remove_reference_t<_Tp>>>::__id;
179}
180
181template <class _Tp>
182inline _LIBCPP_HIDE_FROM_ABI bool __compare_typeid(type_info const* __id, const void* __fallback_id) {
183# if _LIBCPP_HAS_RTTI
184 if (__id && *__id == typeid(_Tp))
185 return true;
186# endif
187 return !__id && __fallback_id == __any_imp::__get_fallback_typeid<_Tp>();
188}
189
190template <class _Tp>
191using _Handler _LIBCPP_NODEBUG = conditional_t< _IsSmallObject<_Tp>::value, _SmallHandler<_Tp>, _LargeHandler<_Tp>>;
192
193} // namespace __any_imp
194
195class any {
196public:
197 // construct/destruct
198 _LIBCPP_HIDE_FROM_ABI constexpr any() noexcept : __h_(nullptr) {}
199
200 _LIBCPP_HIDE_FROM_ABI any(any const& __other) : __h_(nullptr) {
201 if (__other.__h_)
202 __other.__call(a: _Action::_Copy, other: this);
203 }
204
205 _LIBCPP_HIDE_FROM_ABI any(any&& __other) noexcept : __h_(nullptr) {
206 if (__other.__h_)
207 __other.__call(a: _Action::_Move, other: this);
208 }
209
210 template <
211 class _ValueType,
212 class _Tp = decay_t<_ValueType>,
213 enable_if_t<_And<_Not<is_same<_Tp, any>>, _Not<__is_inplace_type<_ValueType>>, is_copy_constructible<_Tp>>::value,
214 int> = 0>
215 _LIBCPP_HIDE_FROM_ABI any(_ValueType&& __value) : __h_(nullptr) {
216 __any_imp::_Handler<_Tp>::__create(*this, std::forward<_ValueType>(__value));
217 }
218
219 template <class _ValueType,
220 class... _Args,
221 class _Tp = decay_t<_ValueType>,
222 enable_if_t<is_constructible_v<_Tp, _Args...> && is_copy_constructible_v<_Tp>, int> = 0>
223 _LIBCPP_HIDE_FROM_ABI explicit any(in_place_type_t<_ValueType>, _Args&&... __args) {
224 __any_imp::_Handler<_Tp>::__create(*this, std::forward<_Args>(__args)...);
225 }
226
227 template <
228 class _ValueType,
229 class _Up,
230 class... _Args,
231 class _Tp = decay_t<_ValueType>,
232 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...> && is_copy_constructible_v<_Tp>, int> = 0>
233 _LIBCPP_HIDE_FROM_ABI explicit any(in_place_type_t<_ValueType>, initializer_list<_Up> __il, _Args&&... __args) {
234 __any_imp::_Handler<_Tp>::__create(*this, __il, std::forward<_Args>(__args)...);
235 }
236
237 _LIBCPP_HIDE_FROM_ABI ~any() { this->reset(); }
238
239 // assignments
240 _LIBCPP_HIDE_FROM_ABI any& operator=(any const& __rhs) {
241 any(__rhs).swap(rhs&: *this);
242 return *this;
243 }
244
245 _LIBCPP_HIDE_FROM_ABI any& operator=(any&& __rhs) noexcept {
246 any(std::move(__rhs)).swap(rhs&: *this);
247 return *this;
248 }
249
250 template <class _ValueType,
251 class _Tp = decay_t<_ValueType>,
252 enable_if_t<!is_same_v<_Tp, any> && is_copy_constructible_v<_Tp>, int> = 0>
253 _LIBCPP_HIDE_FROM_ABI any& operator=(_ValueType&& __rhs) {
254 any(std::forward<_ValueType>(__rhs)).swap(rhs&: *this);
255 return *this;
256 }
257
258 template <class _ValueType,
259 class... _Args,
260 class _Tp = decay_t<_ValueType>,
261 enable_if_t<is_constructible_v<_Tp, _Args...> && is_copy_constructible_v<_Tp>, int> = 0>
262 _LIBCPP_HIDE_FROM_ABI _Tp& emplace(_Args&&... __args) {
263 reset();
264 return __any_imp::_Handler<_Tp>::__create(*this, std::forward<_Args>(__args)...);
265 }
266
267 template <
268 class _ValueType,
269 class _Up,
270 class... _Args,
271 class _Tp = decay_t<_ValueType>,
272 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...> && is_copy_constructible_v<_Tp>, int> = 0>
273 _LIBCPP_HIDE_FROM_ABI _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
274 reset();
275 return __any_imp::_Handler<_Tp>::__create(*this, __il, std::forward<_Args>(__args)...);
276 }
277
278 // 6.3.3 any modifiers
279 _LIBCPP_HIDE_FROM_ABI void reset() noexcept {
280 if (__h_)
281 this->__call(a: _Action::_Destroy);
282 }
283
284 _LIBCPP_HIDE_FROM_ABI void swap(any& __rhs) noexcept {
285 if (this == &__rhs)
286 return;
287 if (__h_ && __rhs.__h_) {
288 any __tmp;
289 __rhs.__call(a: _Action::_Move, other: &__tmp);
290 this->__call(a: _Action::_Move, other: &__rhs);
291 __tmp.__call(a: _Action::_Move, other: this);
292 } else if (__h_) {
293 this->__call(a: _Action::_Move, other: &__rhs);
294 } else if (__rhs.__h_) {
295 __rhs.__call(a: _Action::_Move, other: this);
296 }
297 }
298
299 // 6.3.4 any observers
300 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool has_value() const noexcept { return __h_ != nullptr; }
301
302# if _LIBCPP_HAS_RTTI
303 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const type_info& type() const noexcept {
304 if (__h_) {
305 return *static_cast<type_info const*>(this->__call(a: _Action::_TypeInfo));
306 } else {
307 return typeid(void);
308 }
309 }
310# endif
311
312private:
313 using _Action _LIBCPP_NODEBUG = __any_imp::_Action;
314 using _HandleFuncPtr
315 _LIBCPP_NODEBUG = void* (*)(_Action, any const*, any*, const type_info*, const void* __fallback_info);
316
317 union _Storage {
318 _LIBCPP_HIDE_FROM_ABI constexpr _Storage() : __ptr(nullptr) {}
319 void* __ptr;
320 alignas(__any_imp::__small_buffer_alignment) char __buf[__any_imp::__small_buffer_size];
321 };
322
323 _LIBCPP_HIDE_FROM_ABI void*
324 __call(_Action __a, any* __other = nullptr, type_info const* __info = nullptr, const void* __fallback_info = nullptr)
325 const {
326 return __h_(__a, this, __other, __info, __fallback_info);
327 }
328
329 _LIBCPP_HIDE_FROM_ABI void* __call(
330 _Action __a, any* __other = nullptr, type_info const* __info = nullptr, const void* __fallback_info = nullptr) {
331 return __h_(__a, this, __other, __info, __fallback_info);
332 }
333
334 template <class>
335 friend struct __any_imp::_SmallHandler;
336 template <class>
337 friend struct __any_imp::_LargeHandler;
338
339 template <class _ValueType>
340 friend add_pointer_t<add_const_t<_ValueType>> any_cast(any const*) noexcept;
341
342 template <class _ValueType>
343 friend add_pointer_t<_ValueType> any_cast(any*) noexcept;
344
345 _HandleFuncPtr __h_ = nullptr;
346 _Storage __s_;
347};
348
349namespace __any_imp {
350template <class _Tp>
351struct _SmallHandler {
352 _LIBCPP_HIDE_FROM_ABI static void*
353 __handle(_Action __act, any const* __this, any* __other, type_info const* __info, const void* __fallback_info) {
354 switch (__act) {
355 case _Action::_Destroy:
356 __destroy(this&: const_cast<any&>(*__this));
357 return nullptr;
358 case _Action::_Copy:
359 __copy(this: *__this, dest&: *__other);
360 return nullptr;
361 case _Action::_Move:
362 __move(this&: const_cast<any&>(*__this), dest&: *__other);
363 return nullptr;
364 case _Action::_Get:
365 return __get(this&: const_cast<any&>(*__this), __info, fallback_id: __fallback_info);
366 case _Action::_TypeInfo:
367 return __type_info();
368 }
369 __libcpp_unreachable();
370 }
371
372 template <class... _Args>
373 _LIBCPP_HIDE_FROM_ABI static _Tp& __create(any& __dest, _Args&&... __args) {
374 auto __ret = std::__construct_at(reinterpret_cast<_Tp*>(&__dest.__s_.__buf), std::forward<_Args>(__args)...);
375 __dest.__h_ = &_SmallHandler::__handle;
376 return *__ret;
377 }
378
379private:
380 _LIBCPP_HIDE_FROM_ABI static void __destroy(any& __this) {
381 std::__destroy_at(reinterpret_cast<_Tp*>(&__this.__s_.__buf));
382 __this.__h_ = nullptr;
383 }
384
385 _LIBCPP_HIDE_FROM_ABI static void __copy(any const& __this, any& __dest) {
386 _SmallHandler::__create(__dest, *static_cast<_Tp const*>(static_cast<void const*>(&__this.__s_.__buf)));
387 }
388
389 _LIBCPP_HIDE_FROM_ABI static void __move(any& __this, any& __dest) {
390 _SmallHandler::__create(__dest, std::move(*static_cast<_Tp*>(static_cast<void*>(&__this.__s_.__buf))));
391 __destroy(__this);
392 }
393
394 _LIBCPP_HIDE_FROM_ABI static void* __get(any& __this, type_info const* __info, const void* __fallback_id) {
395 if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_id))
396 return static_cast<void*>(&__this.__s_.__buf);
397 return nullptr;
398 }
399
400 _LIBCPP_HIDE_FROM_ABI static void* __type_info() {
401# if _LIBCPP_HAS_RTTI
402 return const_cast<void*>(static_cast<void const*>(&typeid(_Tp)));
403# else
404 return nullptr;
405# endif
406 }
407};
408
409template <class _Tp>
410struct _LargeHandler {
411 _LIBCPP_HIDE_FROM_ABI static void*
412 __handle(_Action __act, any const* __this, any* __other, type_info const* __info, void const* __fallback_info) {
413 switch (__act) {
414 case _Action::_Destroy:
415 __destroy(this&: const_cast<any&>(*__this));
416 return nullptr;
417 case _Action::_Copy:
418 __copy(this: *__this, dest&: *__other);
419 return nullptr;
420 case _Action::_Move:
421 __move(this&: const_cast<any&>(*__this), dest&: *__other);
422 return nullptr;
423 case _Action::_Get:
424 return __get(this&: const_cast<any&>(*__this), __info, __fallback_info);
425 case _Action::_TypeInfo:
426 return __type_info();
427 }
428 __libcpp_unreachable();
429 }
430
431 template <class... _Args>
432 _LIBCPP_HIDE_FROM_ABI static _Tp& __create(any& __dest, _Args&&... __args) {
433 _Tp* __ptr = static_cast<_Tp*>(std::__libcpp_allocate<_Tp>(__element_count(1)));
434 std::__exception_guard __guard([&] { std::__libcpp_deallocate<_Tp>(__ptr, __element_count(1)); });
435 std::__construct_at(__ptr, std::forward<_Args>(__args)...);
436 __guard.__complete();
437 __dest.__s_.__ptr = __ptr;
438 __dest.__h_ = &_LargeHandler::__handle;
439 return *__ptr;
440 }
441
442private:
443 _LIBCPP_HIDE_FROM_ABI static void __destroy(any& __this) {
444 _Tp* __p = static_cast<_Tp*>(__this.__s_.__ptr);
445 std::__destroy_at(__p);
446 std::__libcpp_deallocate<_Tp>(__p, __element_count(1));
447 __this.__h_ = nullptr;
448 }
449
450 _LIBCPP_HIDE_FROM_ABI static void __copy(any const& __this, any& __dest) {
451 _LargeHandler::__create(__dest, *static_cast<_Tp const*>(__this.__s_.__ptr));
452 }
453
454 _LIBCPP_HIDE_FROM_ABI static void __move(any& __this, any& __dest) {
455 __dest.__s_.__ptr = __this.__s_.__ptr;
456 __dest.__h_ = &_LargeHandler::__handle;
457 __this.__h_ = nullptr;
458 }
459
460 _LIBCPP_HIDE_FROM_ABI static void* __get(any& __this, type_info const* __info, void const* __fallback_info) {
461 if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_info))
462 return static_cast<void*>(__this.__s_.__ptr);
463 return nullptr;
464 }
465
466 _LIBCPP_HIDE_FROM_ABI static void* __type_info() {
467# if _LIBCPP_HAS_RTTI
468 return const_cast<void*>(static_cast<void const*>(&typeid(_Tp)));
469# else
470 return nullptr;
471# endif
472 }
473};
474
475} // namespace __any_imp
476
477// 6.4 Non-member functions
478
479inline _LIBCPP_HIDE_FROM_ABI void swap(any& __lhs, any& __rhs) noexcept { __lhs.swap(__rhs); }
480
481template <class _Tp, class... _Args>
482[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI any make_any(_Args&&... __args) {
483 return any(in_place_type<_Tp>, std::forward<_Args>(__args)...);
484}
485
486template <class _Tp, class _Up, class... _Args>
487[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI any make_any(initializer_list<_Up> __il, _Args&&... __args) {
488 return any(in_place_type<_Tp>, __il, std::forward<_Args>(__args)...);
489}
490
491template <class _ValueType>
492[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any const& __v) {
493 using _RawValueType = __remove_cvref_t<_ValueType>;
494 static_assert(is_constructible_v<_ValueType, _RawValueType const&>,
495 "ValueType is required to be a const lvalue reference "
496 "or a CopyConstructible type");
497 auto __tmp = std::any_cast<add_const_t<_RawValueType>>(&__v);
498 if (__tmp == nullptr)
499 std::__throw_bad_any_cast();
500 return static_cast<_ValueType>(*__tmp);
501}
502
503template <class _ValueType>
504[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any& __v) {
505 using _RawValueType = __remove_cvref_t<_ValueType>;
506 static_assert(is_constructible_v<_ValueType, _RawValueType&>,
507 "ValueType is required to be an lvalue reference "
508 "or a CopyConstructible type");
509 auto __tmp = std::any_cast<_RawValueType>(&__v);
510 if (__tmp == nullptr)
511 std::__throw_bad_any_cast();
512 return static_cast<_ValueType>(*__tmp);
513}
514
515template <class _ValueType>
516[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any&& __v) {
517 using _RawValueType = __remove_cvref_t<_ValueType>;
518 static_assert(is_constructible_v<_ValueType, _RawValueType>,
519 "ValueType is required to be an rvalue reference "
520 "or a CopyConstructible type");
521 auto __tmp = std::any_cast<_RawValueType>(&__v);
522 if (__tmp == nullptr)
523 std::__throw_bad_any_cast();
524 return static_cast<_ValueType>(std::move(*__tmp));
525}
526
527template <class _ValueType>
528[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI add_pointer_t<add_const_t<_ValueType>> any_cast(any const* __any) noexcept {
529 return std::any_cast<_ValueType>(const_cast<any*>(__any));
530}
531
532template <class _ValueType>
533[[nodiscard]] _LIBCPP_HIDE_FROM_ABI add_pointer_t<_ValueType> any_cast(any* __any) noexcept {
534 using __any_imp::_Action;
535 static_assert(!is_void_v<_ValueType>, "_ValueType may not be void.");
536 static_assert(!is_reference_v<_ValueType>, "_ValueType may not be a reference.");
537 if constexpr (!is_function_v<_ValueType>) {
538 using _ReturnType = add_pointer_t<_ValueType>;
539 if (__any && __any->__h_) {
540 void* __p = __any->__call(
541 _Action::_Get,
542 nullptr,
543# if _LIBCPP_HAS_RTTI
544 &typeid(_ValueType),
545# else
546 nullptr,
547# endif
548 __any_imp::__get_fallback_typeid<_ValueType>());
549 return static_cast<_ReturnType>(__p);
550 }
551 }
552 return nullptr;
553}
554
555_LIBCPP_END_NAMESPACE_STD
556
557# endif // _LIBCPP_STD_VER >= 17
558
559_LIBCPP_POP_MACROS
560
561# if defined(_LIBCPP_KEEP_TRANSITIVE_INCLUDES_LLVM23) && _LIBCPP_STD_VER <= 17
562# include <chrono>
563# endif
564
565# if defined(_LIBCPP_KEEP_TRANSITIVE_INCLUDES_LLVM23) && _LIBCPP_STD_VER <= 20
566# include <atomic>
567# include <concepts>
568# include <cstdlib>
569# include <iosfwd>
570# include <iterator>
571# include <memory>
572# include <stdexcept>
573# include <type_traits>
574# include <variant>
575# endif
576
577# if defined(_LIBCPP_KEEP_TRANSITIVE_INCLUDES_LLVM23) && _LIBCPP_STD_VER <= 23
578# include <cstring>
579# include <limits>
580# endif
581#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
582
583#endif // _LIBCPP_ANY
584