1 | // <any> -*- C++ -*- |
2 | |
3 | // Copyright (C) 2014-2021 Free Software Foundation, Inc. |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free |
6 | // software; you can redistribute it and/or modify it under the |
7 | // terms of the GNU General Public License as published by the |
8 | // Free Software Foundation; either version 3, or (at your option) |
9 | // any later version. |
10 | |
11 | // This library is distributed in the hope that it will be useful, |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | // GNU General Public License for more details. |
15 | |
16 | // Under Section 7 of GPL version 3, you are granted additional |
17 | // permissions described in the GCC Runtime Library Exception, version |
18 | // 3.1, as published by the Free Software Foundation. |
19 | |
20 | // You should have received a copy of the GNU General Public License and |
21 | // a copy of the GCC Runtime Library Exception along with this program; |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
23 | // <http://www.gnu.org/licenses/>. |
24 | |
25 | /** @file include/any |
26 | * This is a Standard C++ Library header. |
27 | */ |
28 | |
29 | #ifndef _GLIBCXX_ANY |
30 | #define _GLIBCXX_ANY 1 |
31 | |
32 | #pragma GCC system_header |
33 | |
34 | #if __cplusplus >= 201703L |
35 | |
36 | #include <typeinfo> |
37 | #include <new> |
38 | #include <utility> |
39 | #include <type_traits> |
40 | |
41 | namespace std _GLIBCXX_VISIBILITY(default) |
42 | { |
43 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
44 | |
45 | /** |
46 | * @addtogroup utilities |
47 | * @{ |
48 | */ |
49 | |
50 | /** |
51 | * @brief Exception class thrown by a failed @c any_cast |
52 | * @ingroup exceptions |
53 | */ |
54 | class bad_any_cast : public bad_cast |
55 | { |
56 | public: |
57 | virtual const char* what() const noexcept { return "bad any_cast" ; } |
58 | }; |
59 | |
60 | [[gnu::noreturn]] inline void __throw_bad_any_cast() |
61 | { |
62 | #if __cpp_exceptions |
63 | throw bad_any_cast{}; |
64 | #else |
65 | __builtin_abort(); |
66 | #endif |
67 | } |
68 | |
69 | #define __cpp_lib_any 201606L |
70 | |
71 | /** |
72 | * @brief A type-safe container of any type. |
73 | * |
74 | * An `any` object's state is either empty or it stores a contained object |
75 | * of CopyConstructible type. |
76 | * |
77 | * @since C++17 |
78 | */ |
79 | class any |
80 | { |
81 | // Holds either pointer to a heap object or the contained object itself. |
82 | union _Storage |
83 | { |
84 | constexpr _Storage() : _M_ptr{nullptr} {} |
85 | |
86 | // Prevent trivial copies of this type, buffer might hold a non-POD. |
87 | _Storage(const _Storage&) = delete; |
88 | _Storage& operator=(const _Storage&) = delete; |
89 | |
90 | void* _M_ptr; |
91 | aligned_storage<sizeof(_M_ptr), alignof(void*)>::type _M_buffer; |
92 | }; |
93 | |
94 | template<typename _Tp, typename _Safe = is_nothrow_move_constructible<_Tp>, |
95 | bool _Fits = (sizeof(_Tp) <= sizeof(_Storage)) |
96 | && (alignof(_Tp) <= alignof(_Storage))> |
97 | using _Internal = std::integral_constant<bool, _Safe::value && _Fits>; |
98 | |
99 | template<typename _Tp> |
100 | struct _Manager_internal; // uses small-object optimization |
101 | |
102 | template<typename _Tp> |
103 | struct _Manager_external; // creates contained object on the heap |
104 | |
105 | template<typename _Tp> |
106 | using _Manager = conditional_t<_Internal<_Tp>::value, |
107 | _Manager_internal<_Tp>, |
108 | _Manager_external<_Tp>>; |
109 | |
110 | template<typename _Tp, typename _VTp = decay_t<_Tp>> |
111 | using _Decay_if_not_any = enable_if_t<!is_same_v<_VTp, any>, _VTp>; |
112 | |
113 | /// Emplace with an object created from @p __args as the contained object. |
114 | template <typename _Tp, typename... _Args, |
115 | typename _Mgr = _Manager<_Tp>> |
116 | void __do_emplace(_Args&&... __args) |
117 | { |
118 | reset(); |
119 | _Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...); |
120 | _M_manager = &_Mgr::_S_manage; |
121 | } |
122 | |
123 | /// Emplace with an object created from @p __il and @p __args as |
124 | /// the contained object. |
125 | template <typename _Tp, typename _Up, typename... _Args, |
126 | typename _Mgr = _Manager<_Tp>> |
127 | void __do_emplace(initializer_list<_Up> __il, _Args&&... __args) |
128 | { |
129 | reset(); |
130 | _Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...); |
131 | _M_manager = &_Mgr::_S_manage; |
132 | } |
133 | |
134 | template <typename _Res, typename _Tp, typename... _Args> |
135 | using __any_constructible |
136 | = enable_if<__and_<is_copy_constructible<_Tp>, |
137 | is_constructible<_Tp, _Args...>>::value, |
138 | _Res>; |
139 | |
140 | template <typename _Tp, typename... _Args> |
141 | using __any_constructible_t |
142 | = typename __any_constructible<bool, _Tp, _Args...>::type; |
143 | |
144 | template<typename _VTp, typename... _Args> |
145 | using __emplace_t |
146 | = typename __any_constructible<_VTp&, _VTp, _Args...>::type; |
147 | |
148 | public: |
149 | // construct/destruct |
150 | |
151 | /// Default constructor, creates an empty object. |
152 | constexpr any() noexcept : _M_manager(nullptr) { } |
153 | |
154 | /// Copy constructor, copies the state of @p __other |
155 | any(const any& __other) |
156 | { |
157 | if (!__other.has_value()) |
158 | _M_manager = nullptr; |
159 | else |
160 | { |
161 | _Arg __arg; |
162 | __arg._M_any = this; |
163 | __other._M_manager(_Op_clone, &__other, &__arg); |
164 | } |
165 | } |
166 | |
167 | /** |
168 | * @brief Move constructor, transfer the state from @p __other |
169 | * |
170 | * @post @c !__other.has_value() (this postcondition is a GNU extension) |
171 | */ |
172 | any(any&& __other) noexcept |
173 | { |
174 | if (!__other.has_value()) |
175 | _M_manager = nullptr; |
176 | else |
177 | { |
178 | _Arg __arg; |
179 | __arg._M_any = this; |
180 | __other._M_manager(_Op_xfer, &__other, &__arg); |
181 | } |
182 | } |
183 | |
184 | /// Construct with a copy of @p __value as the contained object. |
185 | template <typename _Tp, typename _VTp = _Decay_if_not_any<_Tp>, |
186 | typename _Mgr = _Manager<_VTp>, |
187 | typename = _Require<__not_<__is_in_place_type<_VTp>>, |
188 | is_copy_constructible<_VTp>>> |
189 | any(_Tp&& __value) |
190 | : _M_manager(&_Mgr::_S_manage) |
191 | { |
192 | _Mgr::_S_create(_M_storage, std::forward<_Tp>(__value)); |
193 | } |
194 | |
195 | /// Construct with an object created from @p __args as the contained object. |
196 | template <typename _Tp, typename... _Args, typename _VTp = decay_t<_Tp>, |
197 | typename _Mgr = _Manager<_VTp>, |
198 | __any_constructible_t<_VTp, _Args&&...> = false> |
199 | explicit |
200 | any(in_place_type_t<_Tp>, _Args&&... __args) |
201 | : _M_manager(&_Mgr::_S_manage) |
202 | { |
203 | _Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...); |
204 | } |
205 | |
206 | /// Construct with an object created from @p __il and @p __args as |
207 | /// the contained object. |
208 | template <typename _Tp, typename _Up, typename... _Args, |
209 | typename _VTp = decay_t<_Tp>, typename _Mgr = _Manager<_VTp>, |
210 | __any_constructible_t<_VTp, initializer_list<_Up>&, |
211 | _Args&&...> = false> |
212 | explicit |
213 | any(in_place_type_t<_Tp>, initializer_list<_Up> __il, _Args&&... __args) |
214 | : _M_manager(&_Mgr::_S_manage) |
215 | { |
216 | _Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...); |
217 | } |
218 | |
219 | /// Destructor, calls @c reset() |
220 | ~any() { reset(); } |
221 | |
222 | // assignments |
223 | |
224 | /// Copy the state of another object. |
225 | any& |
226 | operator=(const any& __rhs) |
227 | { |
228 | *this = any(__rhs); |
229 | return *this; |
230 | } |
231 | |
232 | /** |
233 | * @brief Move assignment operator |
234 | * |
235 | * @post @c !__rhs.has_value() (not guaranteed for other implementations) |
236 | */ |
237 | any& |
238 | operator=(any&& __rhs) noexcept |
239 | { |
240 | if (!__rhs.has_value()) |
241 | reset(); |
242 | else if (this != &__rhs) |
243 | { |
244 | reset(); |
245 | _Arg __arg; |
246 | __arg._M_any = this; |
247 | __rhs._M_manager(_Op_xfer, &__rhs, &__arg); |
248 | } |
249 | return *this; |
250 | } |
251 | |
252 | /// Store a copy of @p __rhs as the contained object. |
253 | template<typename _Tp> |
254 | enable_if_t<is_copy_constructible<_Decay_if_not_any<_Tp>>::value, any&> |
255 | operator=(_Tp&& __rhs) |
256 | { |
257 | *this = any(std::forward<_Tp>(__rhs)); |
258 | return *this; |
259 | } |
260 | |
261 | /// Emplace with an object created from @p __args as the contained object. |
262 | template <typename _Tp, typename... _Args> |
263 | __emplace_t<decay_t<_Tp>, _Args...> |
264 | emplace(_Args&&... __args) |
265 | { |
266 | using _VTp = decay_t<_Tp>; |
267 | __do_emplace<_VTp>(std::forward<_Args>(__args)...); |
268 | return *any::_Manager<_VTp>::_S_access(_M_storage); |
269 | } |
270 | |
271 | /// Emplace with an object created from @p __il and @p __args as |
272 | /// the contained object. |
273 | template <typename _Tp, typename _Up, typename... _Args> |
274 | __emplace_t<decay_t<_Tp>, initializer_list<_Up>&, _Args&&...> |
275 | emplace(initializer_list<_Up> __il, _Args&&... __args) |
276 | { |
277 | using _VTp = decay_t<_Tp>; |
278 | __do_emplace<_VTp, _Up>(__il, std::forward<_Args>(__args)...); |
279 | return *any::_Manager<_VTp>::_S_access(_M_storage); |
280 | } |
281 | |
282 | // modifiers |
283 | |
284 | /// If not empty, destroy the contained object. |
285 | void reset() noexcept |
286 | { |
287 | if (has_value()) |
288 | { |
289 | _M_manager(_Op_destroy, this, nullptr); |
290 | _M_manager = nullptr; |
291 | } |
292 | } |
293 | |
294 | /// Exchange state with another object. |
295 | void swap(any& __rhs) noexcept |
296 | { |
297 | if (!has_value() && !__rhs.has_value()) |
298 | return; |
299 | |
300 | if (has_value() && __rhs.has_value()) |
301 | { |
302 | if (this == &__rhs) |
303 | return; |
304 | |
305 | any __tmp; |
306 | _Arg __arg; |
307 | __arg._M_any = &__tmp; |
308 | __rhs._M_manager(_Op_xfer, &__rhs, &__arg); |
309 | __arg._M_any = &__rhs; |
310 | _M_manager(_Op_xfer, this, &__arg); |
311 | __arg._M_any = this; |
312 | __tmp._M_manager(_Op_xfer, &__tmp, &__arg); |
313 | } |
314 | else |
315 | { |
316 | any* __empty = !has_value() ? this : &__rhs; |
317 | any* __full = !has_value() ? &__rhs : this; |
318 | _Arg __arg; |
319 | __arg._M_any = __empty; |
320 | __full->_M_manager(_Op_xfer, __full, &__arg); |
321 | } |
322 | } |
323 | |
324 | // observers |
325 | |
326 | /// Reports whether there is a contained object or not. |
327 | bool has_value() const noexcept { return _M_manager != nullptr; } |
328 | |
329 | #if __cpp_rtti |
330 | /// The @c typeid of the contained object, or @c typeid(void) if empty. |
331 | const type_info& type() const noexcept |
332 | { |
333 | if (!has_value()) |
334 | return typeid(void); |
335 | _Arg __arg; |
336 | _M_manager(_Op_get_type_info, this, &__arg); |
337 | return *__arg._M_typeinfo; |
338 | } |
339 | #endif |
340 | |
341 | /// @cond undocumented |
342 | template<typename _Tp> |
343 | static constexpr bool __is_valid_cast() |
344 | { return __or_<is_reference<_Tp>, is_copy_constructible<_Tp>>::value; } |
345 | /// @endcond |
346 | |
347 | private: |
348 | enum _Op { |
349 | _Op_access, _Op_get_type_info, _Op_clone, _Op_destroy, _Op_xfer |
350 | }; |
351 | |
352 | union _Arg |
353 | { |
354 | void* _M_obj; |
355 | const std::type_info* _M_typeinfo; |
356 | any* _M_any; |
357 | }; |
358 | |
359 | void (*_M_manager)(_Op, const any*, _Arg*); |
360 | _Storage _M_storage; |
361 | |
362 | /// @cond undocumented |
363 | template<typename _Tp> |
364 | friend void* __any_caster(const any* __any); |
365 | /// @endcond |
366 | |
367 | // Manage in-place contained object. |
368 | template<typename _Tp> |
369 | struct _Manager_internal |
370 | { |
371 | static void |
372 | _S_manage(_Op __which, const any* __anyp, _Arg* __arg); |
373 | |
374 | template<typename _Up> |
375 | static void |
376 | _S_create(_Storage& __storage, _Up&& __value) |
377 | { |
378 | void* __addr = &__storage._M_buffer; |
379 | ::new (__addr) _Tp(std::forward<_Up>(__value)); |
380 | } |
381 | |
382 | template<typename... _Args> |
383 | static void |
384 | _S_create(_Storage& __storage, _Args&&... __args) |
385 | { |
386 | void* __addr = &__storage._M_buffer; |
387 | ::new (__addr) _Tp(std::forward<_Args>(__args)...); |
388 | } |
389 | |
390 | static _Tp* |
391 | _S_access(const _Storage& __storage) |
392 | { |
393 | // The contained object is in __storage._M_buffer |
394 | const void* __addr = &__storage._M_buffer; |
395 | return static_cast<_Tp*>(const_cast<void*>(__addr)); |
396 | } |
397 | }; |
398 | |
399 | // Manage external contained object. |
400 | template<typename _Tp> |
401 | struct _Manager_external |
402 | { |
403 | static void |
404 | _S_manage(_Op __which, const any* __anyp, _Arg* __arg); |
405 | |
406 | template<typename _Up> |
407 | static void |
408 | _S_create(_Storage& __storage, _Up&& __value) |
409 | { |
410 | __storage._M_ptr = new _Tp(std::forward<_Up>(__value)); |
411 | } |
412 | template<typename... _Args> |
413 | static void |
414 | _S_create(_Storage& __storage, _Args&&... __args) |
415 | { |
416 | __storage._M_ptr = new _Tp(std::forward<_Args>(__args)...); |
417 | } |
418 | static _Tp* |
419 | _S_access(const _Storage& __storage) |
420 | { |
421 | // The contained object is in *__storage._M_ptr |
422 | return static_cast<_Tp*>(__storage._M_ptr); |
423 | } |
424 | }; |
425 | }; |
426 | |
427 | /// Exchange the states of two @c any objects. |
428 | inline void swap(any& __x, any& __y) noexcept { __x.swap(rhs&: __y); } |
429 | |
430 | /// Create an `any` holding a `_Tp` constructed from `__args...`. |
431 | template <typename _Tp, typename... _Args> |
432 | inline |
433 | enable_if_t<is_constructible_v<any, in_place_type_t<_Tp>, _Args...>, any> |
434 | make_any(_Args&&... __args) |
435 | { |
436 | return any(in_place_type<_Tp>, std::forward<_Args>(__args)...); |
437 | } |
438 | |
439 | /// Create an `any` holding a `_Tp` constructed from `__il` and `__args...`. |
440 | template <typename _Tp, typename _Up, typename... _Args> |
441 | inline |
442 | enable_if_t<is_constructible_v<any, in_place_type_t<_Tp>, |
443 | initializer_list<_Up>&, _Args...>, any> |
444 | make_any(initializer_list<_Up> __il, _Args&&... __args) |
445 | { |
446 | return any(in_place_type<_Tp>, __il, std::forward<_Args>(__args)...); |
447 | } |
448 | |
449 | /** |
450 | * @brief Access the contained object. |
451 | * |
452 | * @tparam _ValueType A const-reference or CopyConstructible type. |
453 | * @param __any The object to access. |
454 | * @return The contained object. |
455 | * @throw bad_any_cast If <code> |
456 | * __any.type() != typeid(remove_reference_t<_ValueType>) |
457 | * </code> |
458 | */ |
459 | template<typename _ValueType> |
460 | inline _ValueType any_cast(const any& __any) |
461 | { |
462 | using _Up = __remove_cvref_t<_ValueType>; |
463 | static_assert(any::__is_valid_cast<_ValueType>(), |
464 | "Template argument must be a reference or CopyConstructible type" ); |
465 | static_assert(is_constructible_v<_ValueType, const _Up&>, |
466 | "Template argument must be constructible from a const value." ); |
467 | auto __p = any_cast<_Up>(&__any); |
468 | if (__p) |
469 | return static_cast<_ValueType>(*__p); |
470 | __throw_bad_any_cast(); |
471 | } |
472 | |
473 | /** |
474 | * @brief Access the contained object. |
475 | * |
476 | * @tparam _ValueType A reference or CopyConstructible type. |
477 | * @param __any The object to access. |
478 | * @return The contained object. |
479 | * @throw bad_any_cast If <code> |
480 | * __any.type() != typeid(remove_reference_t<_ValueType>) |
481 | * </code> |
482 | * |
483 | * @{ |
484 | */ |
485 | template<typename _ValueType> |
486 | inline _ValueType any_cast(any& __any) |
487 | { |
488 | using _Up = __remove_cvref_t<_ValueType>; |
489 | static_assert(any::__is_valid_cast<_ValueType>(), |
490 | "Template argument must be a reference or CopyConstructible type" ); |
491 | static_assert(is_constructible_v<_ValueType, _Up&>, |
492 | "Template argument must be constructible from an lvalue." ); |
493 | auto __p = any_cast<_Up>(&__any); |
494 | if (__p) |
495 | return static_cast<_ValueType>(*__p); |
496 | __throw_bad_any_cast(); |
497 | } |
498 | |
499 | template<typename _ValueType> |
500 | inline _ValueType any_cast(any&& __any) |
501 | { |
502 | using _Up = __remove_cvref_t<_ValueType>; |
503 | static_assert(any::__is_valid_cast<_ValueType>(), |
504 | "Template argument must be a reference or CopyConstructible type" ); |
505 | static_assert(is_constructible_v<_ValueType, _Up>, |
506 | "Template argument must be constructible from an rvalue." ); |
507 | auto __p = any_cast<_Up>(&__any); |
508 | if (__p) |
509 | return static_cast<_ValueType>(std::move(*__p)); |
510 | __throw_bad_any_cast(); |
511 | } |
512 | /// @} |
513 | |
514 | /// @cond undocumented |
515 | template<typename _Tp> |
516 | void* __any_caster(const any* __any) |
517 | { |
518 | // any_cast<T> returns non-null if __any->type() == typeid(T) and |
519 | // typeid(T) ignores cv-qualifiers so remove them: |
520 | using _Up = remove_cv_t<_Tp>; |
521 | // The contained value has a decayed type, so if decay_t<U> is not U, |
522 | // then it's not possible to have a contained value of type U: |
523 | if constexpr (!is_same_v<decay_t<_Up>, _Up>) |
524 | return nullptr; |
525 | // Only copy constructible types can be used for contained values: |
526 | else if constexpr (!is_copy_constructible_v<_Up>) |
527 | return nullptr; |
528 | // First try comparing function addresses, which works without RTTI |
529 | else if (__any->_M_manager == &any::_Manager<_Up>::_S_manage |
530 | #if __cpp_rtti |
531 | || __any->type() == typeid(_Tp) |
532 | #endif |
533 | ) |
534 | { |
535 | return any::_Manager<_Up>::_S_access(__any->_M_storage); |
536 | } |
537 | return nullptr; |
538 | } |
539 | /// @endcond |
540 | |
541 | /** |
542 | * @brief Access the contained object. |
543 | * |
544 | * @tparam _ValueType The type of the contained object. |
545 | * @param __any A pointer to the object to access. |
546 | * @return The address of the contained object if <code> |
547 | * __any != nullptr && __any.type() == typeid(_ValueType) |
548 | * </code>, otherwise a null pointer. |
549 | * |
550 | * @{ |
551 | */ |
552 | template<typename _ValueType> |
553 | inline const _ValueType* any_cast(const any* __any) noexcept |
554 | { |
555 | if constexpr (is_object_v<_ValueType>) |
556 | if (__any) |
557 | return static_cast<_ValueType*>(__any_caster<_ValueType>(__any)); |
558 | return nullptr; |
559 | } |
560 | |
561 | template<typename _ValueType> |
562 | inline _ValueType* any_cast(any* __any) noexcept |
563 | { |
564 | if constexpr (is_object_v<_ValueType>) |
565 | if (__any) |
566 | return static_cast<_ValueType*>(__any_caster<_ValueType>(__any)); |
567 | return nullptr; |
568 | } |
569 | /// @} |
570 | |
571 | template<typename _Tp> |
572 | void |
573 | any::_Manager_internal<_Tp>:: |
574 | _S_manage(_Op __which, const any* __any, _Arg* __arg) |
575 | { |
576 | // The contained object is in _M_storage._M_buffer |
577 | auto __ptr = reinterpret_cast<const _Tp*>(&__any->_M_storage._M_buffer); |
578 | switch (__which) |
579 | { |
580 | case _Op_access: |
581 | __arg->_M_obj = const_cast<_Tp*>(__ptr); |
582 | break; |
583 | case _Op_get_type_info: |
584 | #if __cpp_rtti |
585 | __arg->_M_typeinfo = &typeid(_Tp); |
586 | #endif |
587 | break; |
588 | case _Op_clone: |
589 | ::new(&__arg->_M_any->_M_storage._M_buffer) _Tp(*__ptr); |
590 | __arg->_M_any->_M_manager = __any->_M_manager; |
591 | break; |
592 | case _Op_destroy: |
593 | __ptr->~_Tp(); |
594 | break; |
595 | case _Op_xfer: |
596 | ::new(&__arg->_M_any->_M_storage._M_buffer) _Tp |
597 | (std::move(*const_cast<_Tp*>(__ptr))); |
598 | __ptr->~_Tp(); |
599 | __arg->_M_any->_M_manager = __any->_M_manager; |
600 | const_cast<any*>(__any)->_M_manager = nullptr; |
601 | break; |
602 | } |
603 | } |
604 | |
605 | template<typename _Tp> |
606 | void |
607 | any::_Manager_external<_Tp>:: |
608 | _S_manage(_Op __which, const any* __any, _Arg* __arg) |
609 | { |
610 | // The contained object is *_M_storage._M_ptr |
611 | auto __ptr = static_cast<const _Tp*>(__any->_M_storage._M_ptr); |
612 | switch (__which) |
613 | { |
614 | case _Op_access: |
615 | __arg->_M_obj = const_cast<_Tp*>(__ptr); |
616 | break; |
617 | case _Op_get_type_info: |
618 | #if __cpp_rtti |
619 | __arg->_M_typeinfo = &typeid(_Tp); |
620 | #endif |
621 | break; |
622 | case _Op_clone: |
623 | __arg->_M_any->_M_storage._M_ptr = new _Tp(*__ptr); |
624 | __arg->_M_any->_M_manager = __any->_M_manager; |
625 | break; |
626 | case _Op_destroy: |
627 | delete __ptr; |
628 | break; |
629 | case _Op_xfer: |
630 | __arg->_M_any->_M_storage._M_ptr = __any->_M_storage._M_ptr; |
631 | __arg->_M_any->_M_manager = __any->_M_manager; |
632 | const_cast<any*>(__any)->_M_manager = nullptr; |
633 | break; |
634 | } |
635 | } |
636 | |
637 | /// @} |
638 | |
639 | namespace __detail::__variant |
640 | { |
641 | template<typename> struct _Never_valueless_alt; // see <variant> |
642 | |
643 | // Provide the strong exception-safety guarantee when emplacing an |
644 | // any into a variant. |
645 | template<> |
646 | struct _Never_valueless_alt<std::any> |
647 | : std::true_type |
648 | { }; |
649 | } // namespace __detail::__variant |
650 | |
651 | _GLIBCXX_END_NAMESPACE_VERSION |
652 | } // namespace std |
653 | |
654 | #endif // C++17 |
655 | #endif // _GLIBCXX_ANY |
656 | |