13ad841b2Smrg// <any> -*- C++ -*- 23ad841b2Smrg 34c3eb207Smrg// Copyright (C) 2014-2020 Free Software Foundation, Inc. 43ad841b2Smrg// 53ad841b2Smrg// This file is part of the GNU ISO C++ Library. This library is free 63ad841b2Smrg// software; you can redistribute it and/or modify it under the 73ad841b2Smrg// terms of the GNU General Public License as published by the 83ad841b2Smrg// Free Software Foundation; either version 3, or (at your option) 93ad841b2Smrg// any later version. 103ad841b2Smrg 113ad841b2Smrg// This library is distributed in the hope that it will be useful, 123ad841b2Smrg// but WITHOUT ANY WARRANTY; without even the implied warranty of 133ad841b2Smrg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 143ad841b2Smrg// GNU General Public License for more details. 153ad841b2Smrg 163ad841b2Smrg// Under Section 7 of GPL version 3, you are granted additional 173ad841b2Smrg// permissions described in the GCC Runtime Library Exception, version 183ad841b2Smrg// 3.1, as published by the Free Software Foundation. 193ad841b2Smrg 203ad841b2Smrg// You should have received a copy of the GNU General Public License and 213ad841b2Smrg// a copy of the GCC Runtime Library Exception along with this program; 223ad841b2Smrg// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 233ad841b2Smrg// <http://www.gnu.org/licenses/>. 243ad841b2Smrg 253ad841b2Smrg/** @file include/any 263ad841b2Smrg * This is a Standard C++ Library header. 273ad841b2Smrg */ 283ad841b2Smrg 293ad841b2Smrg#ifndef _GLIBCXX_ANY 303ad841b2Smrg#define _GLIBCXX_ANY 1 313ad841b2Smrg 323ad841b2Smrg#pragma GCC system_header 333ad841b2Smrg 343ad841b2Smrg#if __cplusplus >= 201703L 353ad841b2Smrg 363ad841b2Smrg#include <typeinfo> 373ad841b2Smrg#include <new> 383ad841b2Smrg#include <utility> 393ad841b2Smrg#include <type_traits> 403ad841b2Smrg 413ad841b2Smrgnamespace std _GLIBCXX_VISIBILITY(default) 423ad841b2Smrg{ 433ad841b2Smrg_GLIBCXX_BEGIN_NAMESPACE_VERSION 443ad841b2Smrg 453ad841b2Smrg /** 463ad841b2Smrg * @addtogroup utilities 473ad841b2Smrg * @{ 483ad841b2Smrg */ 493ad841b2Smrg 503ad841b2Smrg /** 513ad841b2Smrg * @brief Exception class thrown by a failed @c any_cast 523ad841b2Smrg * @ingroup exceptions 533ad841b2Smrg */ 543ad841b2Smrg class bad_any_cast : public bad_cast 553ad841b2Smrg { 563ad841b2Smrg public: 573ad841b2Smrg virtual const char* what() const noexcept { return "bad any_cast"; } 583ad841b2Smrg }; 593ad841b2Smrg 603ad841b2Smrg [[gnu::noreturn]] inline void __throw_bad_any_cast() 613ad841b2Smrg { 623ad841b2Smrg#if __cpp_exceptions 633ad841b2Smrg throw bad_any_cast{}; 643ad841b2Smrg#else 653ad841b2Smrg __builtin_abort(); 663ad841b2Smrg#endif 673ad841b2Smrg } 683ad841b2Smrg 69cef8759bSmrg#define __cpp_lib_any 201606L 703ad841b2Smrg 713ad841b2Smrg /** 723ad841b2Smrg * @brief A type-safe container of any type. 733ad841b2Smrg * 743ad841b2Smrg * An @c any object's state is either empty or it stores a contained object 753ad841b2Smrg * of CopyConstructible type. 763ad841b2Smrg */ 773ad841b2Smrg class any 783ad841b2Smrg { 793ad841b2Smrg // Holds either pointer to a heap object or the contained object itself. 803ad841b2Smrg union _Storage 813ad841b2Smrg { 823ad841b2Smrg constexpr _Storage() : _M_ptr{nullptr} {} 833ad841b2Smrg 843ad841b2Smrg // Prevent trivial copies of this type, buffer might hold a non-POD. 853ad841b2Smrg _Storage(const _Storage&) = delete; 863ad841b2Smrg _Storage& operator=(const _Storage&) = delete; 873ad841b2Smrg 883ad841b2Smrg void* _M_ptr; 893ad841b2Smrg aligned_storage<sizeof(_M_ptr), alignof(void*)>::type _M_buffer; 903ad841b2Smrg }; 913ad841b2Smrg 923ad841b2Smrg template<typename _Tp, typename _Safe = is_nothrow_move_constructible<_Tp>, 933ad841b2Smrg bool _Fits = (sizeof(_Tp) <= sizeof(_Storage)) 943ad841b2Smrg && (alignof(_Tp) <= alignof(_Storage))> 953ad841b2Smrg using _Internal = std::integral_constant<bool, _Safe::value && _Fits>; 963ad841b2Smrg 973ad841b2Smrg template<typename _Tp> 983ad841b2Smrg struct _Manager_internal; // uses small-object optimization 993ad841b2Smrg 1003ad841b2Smrg template<typename _Tp> 1013ad841b2Smrg struct _Manager_external; // creates contained object on the heap 1023ad841b2Smrg 1033ad841b2Smrg template<typename _Tp> 1043ad841b2Smrg using _Manager = conditional_t<_Internal<_Tp>::value, 1053ad841b2Smrg _Manager_internal<_Tp>, 1063ad841b2Smrg _Manager_external<_Tp>>; 1073ad841b2Smrg 1084c3eb207Smrg template<typename _Tp, typename _VTp = decay_t<_Tp>> 1094c3eb207Smrg using _Decay_if_not_any = enable_if_t<!is_same_v<_VTp, any>, _VTp>; 1103ad841b2Smrg 1113ad841b2Smrg /// Emplace with an object created from @p __args as the contained object. 1123ad841b2Smrg template <typename _Tp, typename... _Args, 1133ad841b2Smrg typename _Mgr = _Manager<_Tp>> 1143ad841b2Smrg void __do_emplace(_Args&&... __args) 1153ad841b2Smrg { 1163ad841b2Smrg reset(); 1173ad841b2Smrg _Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...); 1183ad841b2Smrg _M_manager = &_Mgr::_S_manage; 1193ad841b2Smrg } 1203ad841b2Smrg 1213ad841b2Smrg /// Emplace with an object created from @p __il and @p __args as 1223ad841b2Smrg /// the contained object. 1233ad841b2Smrg template <typename _Tp, typename _Up, typename... _Args, 1243ad841b2Smrg typename _Mgr = _Manager<_Tp>> 1253ad841b2Smrg void __do_emplace(initializer_list<_Up> __il, _Args&&... __args) 1263ad841b2Smrg { 1273ad841b2Smrg reset(); 1283ad841b2Smrg _Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...); 1293ad841b2Smrg _M_manager = &_Mgr::_S_manage; 1303ad841b2Smrg } 1313ad841b2Smrg 1324c3eb207Smrg template <typename _Res, typename _Tp, typename... _Args> 1334c3eb207Smrg using __any_constructible 1344c3eb207Smrg = enable_if<__and_<is_copy_constructible<_Tp>, 1354c3eb207Smrg is_constructible<_Tp, _Args...>>::value, 1364c3eb207Smrg _Res>; 1374c3eb207Smrg 1384c3eb207Smrg template <typename _Tp, typename... _Args> 1394c3eb207Smrg using __any_constructible_t 1404c3eb207Smrg = typename __any_constructible<bool, _Tp, _Args...>::type; 1414c3eb207Smrg 1424c3eb207Smrg template<typename _VTp, typename... _Args> 1434c3eb207Smrg using __emplace_t 1444c3eb207Smrg = typename __any_constructible<_VTp&, _VTp, _Args...>::type; 1454c3eb207Smrg 1463ad841b2Smrg public: 1473ad841b2Smrg // construct/destruct 1483ad841b2Smrg 1493ad841b2Smrg /// Default constructor, creates an empty object. 1503ad841b2Smrg constexpr any() noexcept : _M_manager(nullptr) { } 1513ad841b2Smrg 1523ad841b2Smrg /// Copy constructor, copies the state of @p __other 1533ad841b2Smrg any(const any& __other) 1543ad841b2Smrg { 1553ad841b2Smrg if (!__other.has_value()) 1563ad841b2Smrg _M_manager = nullptr; 1573ad841b2Smrg else 1583ad841b2Smrg { 1593ad841b2Smrg _Arg __arg; 1603ad841b2Smrg __arg._M_any = this; 1613ad841b2Smrg __other._M_manager(_Op_clone, &__other, &__arg); 1623ad841b2Smrg } 1633ad841b2Smrg } 1643ad841b2Smrg 1653ad841b2Smrg /** 1663ad841b2Smrg * @brief Move constructor, transfer the state from @p __other 1673ad841b2Smrg * 1683ad841b2Smrg * @post @c !__other.has_value() (this postcondition is a GNU extension) 1693ad841b2Smrg */ 1703ad841b2Smrg any(any&& __other) noexcept 1713ad841b2Smrg { 1723ad841b2Smrg if (!__other.has_value()) 1733ad841b2Smrg _M_manager = nullptr; 1743ad841b2Smrg else 1753ad841b2Smrg { 1763ad841b2Smrg _Arg __arg; 1773ad841b2Smrg __arg._M_any = this; 1783ad841b2Smrg __other._M_manager(_Op_xfer, &__other, &__arg); 1793ad841b2Smrg } 1803ad841b2Smrg } 1813ad841b2Smrg 1823ad841b2Smrg /// Construct with a copy of @p __value as the contained object. 1834c3eb207Smrg template <typename _Tp, typename _VTp = _Decay_if_not_any<_Tp>, 1844c3eb207Smrg typename _Mgr = _Manager<_VTp>, 1854c3eb207Smrg enable_if_t<is_copy_constructible<_VTp>::value 1864c3eb207Smrg && !__is_in_place_type<_VTp>::value, bool> = true> 1874c3eb207Smrg any(_Tp&& __value) 1883ad841b2Smrg : _M_manager(&_Mgr::_S_manage) 1893ad841b2Smrg { 1904c3eb207Smrg _Mgr::_S_create(_M_storage, std::forward<_Tp>(__value)); 1913ad841b2Smrg } 1923ad841b2Smrg 1933ad841b2Smrg /// Construct with an object created from @p __args as the contained object. 1944c3eb207Smrg template <typename _Tp, typename... _Args, typename _VTp = decay_t<_Tp>, 1954c3eb207Smrg typename _Mgr = _Manager<_VTp>, 1964c3eb207Smrg __any_constructible_t<_VTp, _Args&&...> = false> 1973ad841b2Smrg explicit 1984c3eb207Smrg any(in_place_type_t<_Tp>, _Args&&... __args) 1993ad841b2Smrg : _M_manager(&_Mgr::_S_manage) 2003ad841b2Smrg { 2013ad841b2Smrg _Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...); 2023ad841b2Smrg } 2033ad841b2Smrg 2043ad841b2Smrg /// Construct with an object created from @p __il and @p __args as 2053ad841b2Smrg /// the contained object. 2064c3eb207Smrg template <typename _Tp, typename _Up, typename... _Args, 2074c3eb207Smrg typename _VTp = decay_t<_Tp>, typename _Mgr = _Manager<_VTp>, 2084c3eb207Smrg __any_constructible_t<_VTp, initializer_list<_Up>&, 2093ad841b2Smrg _Args&&...> = false> 2103ad841b2Smrg explicit 2114c3eb207Smrg any(in_place_type_t<_Tp>, initializer_list<_Up> __il, _Args&&... __args) 2123ad841b2Smrg : _M_manager(&_Mgr::_S_manage) 2133ad841b2Smrg { 2143ad841b2Smrg _Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...); 2153ad841b2Smrg } 2163ad841b2Smrg 2173ad841b2Smrg /// Destructor, calls @c reset() 2183ad841b2Smrg ~any() { reset(); } 2193ad841b2Smrg 2203ad841b2Smrg // assignments 2213ad841b2Smrg 2223ad841b2Smrg /// Copy the state of another object. 2234c3eb207Smrg any& 2244c3eb207Smrg operator=(const any& __rhs) 2253ad841b2Smrg { 2263ad841b2Smrg *this = any(__rhs); 2273ad841b2Smrg return *this; 2283ad841b2Smrg } 2293ad841b2Smrg 2303ad841b2Smrg /** 2313ad841b2Smrg * @brief Move assignment operator 2323ad841b2Smrg * 2333ad841b2Smrg * @post @c !__rhs.has_value() (not guaranteed for other implementations) 2343ad841b2Smrg */ 2354c3eb207Smrg any& 2364c3eb207Smrg operator=(any&& __rhs) noexcept 2373ad841b2Smrg { 2383ad841b2Smrg if (!__rhs.has_value()) 2393ad841b2Smrg reset(); 2403ad841b2Smrg else if (this != &__rhs) 2413ad841b2Smrg { 2423ad841b2Smrg reset(); 2433ad841b2Smrg _Arg __arg; 2443ad841b2Smrg __arg._M_any = this; 2453ad841b2Smrg __rhs._M_manager(_Op_xfer, &__rhs, &__arg); 2463ad841b2Smrg } 2473ad841b2Smrg return *this; 2483ad841b2Smrg } 2493ad841b2Smrg 2503ad841b2Smrg /// Store a copy of @p __rhs as the contained object. 2514c3eb207Smrg template<typename _Tp> 2524c3eb207Smrg enable_if_t<is_copy_constructible<_Decay_if_not_any<_Tp>>::value, any&> 2534c3eb207Smrg operator=(_Tp&& __rhs) 2543ad841b2Smrg { 2554c3eb207Smrg *this = any(std::forward<_Tp>(__rhs)); 2563ad841b2Smrg return *this; 2573ad841b2Smrg } 2583ad841b2Smrg 2593ad841b2Smrg /// Emplace with an object created from @p __args as the contained object. 2604c3eb207Smrg template <typename _Tp, typename... _Args> 2614c3eb207Smrg __emplace_t<decay_t<_Tp>, _Args...> 2623ad841b2Smrg emplace(_Args&&... __args) 2633ad841b2Smrg { 2644c3eb207Smrg using _VTp = decay_t<_Tp>; 2654c3eb207Smrg __do_emplace<_VTp>(std::forward<_Args>(__args)...); 266*4ac76180Smrg return *any::_Manager<_VTp>::_S_access(_M_storage); 2673ad841b2Smrg } 2683ad841b2Smrg 2693ad841b2Smrg /// Emplace with an object created from @p __il and @p __args as 2703ad841b2Smrg /// the contained object. 2714c3eb207Smrg template <typename _Tp, typename _Up, typename... _Args> 2724c3eb207Smrg __emplace_t<decay_t<_Tp>, initializer_list<_Up>&, _Args&&...> 2733ad841b2Smrg emplace(initializer_list<_Up> __il, _Args&&... __args) 2743ad841b2Smrg { 2754c3eb207Smrg using _VTp = decay_t<_Tp>; 2764c3eb207Smrg __do_emplace<_VTp, _Up>(__il, std::forward<_Args>(__args)...); 277*4ac76180Smrg return *any::_Manager<_VTp>::_S_access(_M_storage); 2783ad841b2Smrg } 2793ad841b2Smrg 2803ad841b2Smrg // modifiers 2813ad841b2Smrg 2823ad841b2Smrg /// If not empty, destroy the contained object. 2833ad841b2Smrg void reset() noexcept 2843ad841b2Smrg { 2853ad841b2Smrg if (has_value()) 2863ad841b2Smrg { 2873ad841b2Smrg _M_manager(_Op_destroy, this, nullptr); 2883ad841b2Smrg _M_manager = nullptr; 2893ad841b2Smrg } 2903ad841b2Smrg } 2913ad841b2Smrg 2923ad841b2Smrg /// Exchange state with another object. 2933ad841b2Smrg void swap(any& __rhs) noexcept 2943ad841b2Smrg { 2953ad841b2Smrg if (!has_value() && !__rhs.has_value()) 2963ad841b2Smrg return; 2973ad841b2Smrg 2983ad841b2Smrg if (has_value() && __rhs.has_value()) 2993ad841b2Smrg { 3003ad841b2Smrg if (this == &__rhs) 3013ad841b2Smrg return; 3023ad841b2Smrg 3033ad841b2Smrg any __tmp; 3043ad841b2Smrg _Arg __arg; 3053ad841b2Smrg __arg._M_any = &__tmp; 3063ad841b2Smrg __rhs._M_manager(_Op_xfer, &__rhs, &__arg); 3073ad841b2Smrg __arg._M_any = &__rhs; 3083ad841b2Smrg _M_manager(_Op_xfer, this, &__arg); 3093ad841b2Smrg __arg._M_any = this; 3103ad841b2Smrg __tmp._M_manager(_Op_xfer, &__tmp, &__arg); 3113ad841b2Smrg } 3123ad841b2Smrg else 3133ad841b2Smrg { 3143ad841b2Smrg any* __empty = !has_value() ? this : &__rhs; 3153ad841b2Smrg any* __full = !has_value() ? &__rhs : this; 3163ad841b2Smrg _Arg __arg; 3173ad841b2Smrg __arg._M_any = __empty; 3183ad841b2Smrg __full->_M_manager(_Op_xfer, __full, &__arg); 3193ad841b2Smrg } 3203ad841b2Smrg } 3213ad841b2Smrg 3223ad841b2Smrg // observers 3233ad841b2Smrg 3243ad841b2Smrg /// Reports whether there is a contained object or not. 3253ad841b2Smrg bool has_value() const noexcept { return _M_manager != nullptr; } 3263ad841b2Smrg 3273ad841b2Smrg#if __cpp_rtti 3283ad841b2Smrg /// The @c typeid of the contained object, or @c typeid(void) if empty. 3293ad841b2Smrg const type_info& type() const noexcept 3303ad841b2Smrg { 3313ad841b2Smrg if (!has_value()) 3323ad841b2Smrg return typeid(void); 3333ad841b2Smrg _Arg __arg; 3343ad841b2Smrg _M_manager(_Op_get_type_info, this, &__arg); 3353ad841b2Smrg return *__arg._M_typeinfo; 3363ad841b2Smrg } 3373ad841b2Smrg#endif 3383ad841b2Smrg 3393ad841b2Smrg template<typename _Tp> 3403ad841b2Smrg static constexpr bool __is_valid_cast() 3413ad841b2Smrg { return __or_<is_reference<_Tp>, is_copy_constructible<_Tp>>::value; } 3423ad841b2Smrg 3433ad841b2Smrg private: 3443ad841b2Smrg enum _Op { 3453ad841b2Smrg _Op_access, _Op_get_type_info, _Op_clone, _Op_destroy, _Op_xfer 3463ad841b2Smrg }; 3473ad841b2Smrg 3483ad841b2Smrg union _Arg 3493ad841b2Smrg { 3503ad841b2Smrg void* _M_obj; 3513ad841b2Smrg const std::type_info* _M_typeinfo; 3523ad841b2Smrg any* _M_any; 3533ad841b2Smrg }; 3543ad841b2Smrg 3553ad841b2Smrg void (*_M_manager)(_Op, const any*, _Arg*); 3563ad841b2Smrg _Storage _M_storage; 3573ad841b2Smrg 3583ad841b2Smrg template<typename _Tp> 3593ad841b2Smrg friend void* __any_caster(const any* __any); 3603ad841b2Smrg 3613ad841b2Smrg // Manage in-place contained object. 3623ad841b2Smrg template<typename _Tp> 3633ad841b2Smrg struct _Manager_internal 3643ad841b2Smrg { 3653ad841b2Smrg static void 3663ad841b2Smrg _S_manage(_Op __which, const any* __anyp, _Arg* __arg); 3673ad841b2Smrg 3683ad841b2Smrg template<typename _Up> 3693ad841b2Smrg static void 3703ad841b2Smrg _S_create(_Storage& __storage, _Up&& __value) 3713ad841b2Smrg { 3723ad841b2Smrg void* __addr = &__storage._M_buffer; 3733ad841b2Smrg ::new (__addr) _Tp(std::forward<_Up>(__value)); 3743ad841b2Smrg } 3753ad841b2Smrg 3763ad841b2Smrg template<typename... _Args> 3773ad841b2Smrg static void 3783ad841b2Smrg _S_create(_Storage& __storage, _Args&&... __args) 3793ad841b2Smrg { 3803ad841b2Smrg void* __addr = &__storage._M_buffer; 3813ad841b2Smrg ::new (__addr) _Tp(std::forward<_Args>(__args)...); 3823ad841b2Smrg } 383*4ac76180Smrg 384*4ac76180Smrg static _Tp* 385*4ac76180Smrg _S_access(const _Storage& __storage) 386*4ac76180Smrg { 387*4ac76180Smrg // The contained object is in __storage._M_buffer 388*4ac76180Smrg const void* __addr = &__storage._M_buffer; 389*4ac76180Smrg return static_cast<_Tp*>(const_cast<void*>(__addr)); 390*4ac76180Smrg } 3913ad841b2Smrg }; 3923ad841b2Smrg 3933ad841b2Smrg // Manage external contained object. 3943ad841b2Smrg template<typename _Tp> 3953ad841b2Smrg struct _Manager_external 3963ad841b2Smrg { 3973ad841b2Smrg static void 3983ad841b2Smrg _S_manage(_Op __which, const any* __anyp, _Arg* __arg); 3993ad841b2Smrg 4003ad841b2Smrg template<typename _Up> 4013ad841b2Smrg static void 4023ad841b2Smrg _S_create(_Storage& __storage, _Up&& __value) 4033ad841b2Smrg { 4043ad841b2Smrg __storage._M_ptr = new _Tp(std::forward<_Up>(__value)); 4053ad841b2Smrg } 4063ad841b2Smrg template<typename... _Args> 4073ad841b2Smrg static void 4083ad841b2Smrg _S_create(_Storage& __storage, _Args&&... __args) 4093ad841b2Smrg { 4103ad841b2Smrg __storage._M_ptr = new _Tp(std::forward<_Args>(__args)...); 4113ad841b2Smrg } 412*4ac76180Smrg static _Tp* 413*4ac76180Smrg _S_access(const _Storage& __storage) 414*4ac76180Smrg { 415*4ac76180Smrg // The contained object is in *__storage._M_ptr 416*4ac76180Smrg return static_cast<_Tp*>(__storage._M_ptr); 417*4ac76180Smrg } 4183ad841b2Smrg }; 4193ad841b2Smrg }; 4203ad841b2Smrg 4213ad841b2Smrg /// Exchange the states of two @c any objects. 4223ad841b2Smrg inline void swap(any& __x, any& __y) noexcept { __x.swap(__y); } 4233ad841b2Smrg 4244c3eb207Smrg /// Create an `any` holding a `_Tp` constructed from `__args...`. 4253ad841b2Smrg template <typename _Tp, typename... _Args> 4264c3eb207Smrg inline 4274c3eb207Smrg enable_if_t<is_constructible_v<any, in_place_type_t<_Tp>, _Args...>, any> 4284c3eb207Smrg make_any(_Args&&... __args) 4293ad841b2Smrg { 4303ad841b2Smrg return any(in_place_type<_Tp>, std::forward<_Args>(__args)...); 4313ad841b2Smrg } 4323ad841b2Smrg 4334c3eb207Smrg /// Create an `any` holding a `_Tp` constructed from `__il` and `__args...`. 4343ad841b2Smrg template <typename _Tp, typename _Up, typename... _Args> 4354c3eb207Smrg inline 4364c3eb207Smrg enable_if_t<is_constructible_v<any, in_place_type_t<_Tp>, 4374c3eb207Smrg initializer_list<_Up>&, _Args...>, any> 4384c3eb207Smrg make_any(initializer_list<_Up> __il, _Args&&... __args) 4393ad841b2Smrg { 4403ad841b2Smrg return any(in_place_type<_Tp>, __il, std::forward<_Args>(__args)...); 4413ad841b2Smrg } 4423ad841b2Smrg 4433ad841b2Smrg /** 4443ad841b2Smrg * @brief Access the contained object. 4453ad841b2Smrg * 4463ad841b2Smrg * @tparam _ValueType A const-reference or CopyConstructible type. 4473ad841b2Smrg * @param __any The object to access. 4483ad841b2Smrg * @return The contained object. 4493ad841b2Smrg * @throw bad_any_cast If <code> 4503ad841b2Smrg * __any.type() != typeid(remove_reference_t<_ValueType>) 4513ad841b2Smrg * </code> 4523ad841b2Smrg */ 4533ad841b2Smrg template<typename _ValueType> 4543ad841b2Smrg inline _ValueType any_cast(const any& __any) 4553ad841b2Smrg { 456627f7eb2Smrg using _Up = __remove_cvref_t<_ValueType>; 4573ad841b2Smrg static_assert(any::__is_valid_cast<_ValueType>(), 4583ad841b2Smrg "Template argument must be a reference or CopyConstructible type"); 459cef8759bSmrg static_assert(is_constructible_v<_ValueType, const _Up&>, 460cef8759bSmrg "Template argument must be constructible from a const value."); 461cef8759bSmrg auto __p = any_cast<_Up>(&__any); 4623ad841b2Smrg if (__p) 4633ad841b2Smrg return static_cast<_ValueType>(*__p); 4643ad841b2Smrg __throw_bad_any_cast(); 4653ad841b2Smrg } 4663ad841b2Smrg 4673ad841b2Smrg /** 4683ad841b2Smrg * @brief Access the contained object. 4693ad841b2Smrg * 4703ad841b2Smrg * @tparam _ValueType A reference or CopyConstructible type. 4713ad841b2Smrg * @param __any The object to access. 4723ad841b2Smrg * @return The contained object. 4733ad841b2Smrg * @throw bad_any_cast If <code> 4743ad841b2Smrg * __any.type() != typeid(remove_reference_t<_ValueType>) 4753ad841b2Smrg * </code> 4763ad841b2Smrg * 4773ad841b2Smrg * @{ 4783ad841b2Smrg */ 4793ad841b2Smrg template<typename _ValueType> 4803ad841b2Smrg inline _ValueType any_cast(any& __any) 4813ad841b2Smrg { 482627f7eb2Smrg using _Up = __remove_cvref_t<_ValueType>; 4833ad841b2Smrg static_assert(any::__is_valid_cast<_ValueType>(), 4843ad841b2Smrg "Template argument must be a reference or CopyConstructible type"); 485cef8759bSmrg static_assert(is_constructible_v<_ValueType, _Up&>, 486cef8759bSmrg "Template argument must be constructible from an lvalue."); 487cef8759bSmrg auto __p = any_cast<_Up>(&__any); 4883ad841b2Smrg if (__p) 4893ad841b2Smrg return static_cast<_ValueType>(*__p); 4903ad841b2Smrg __throw_bad_any_cast(); 4913ad841b2Smrg } 4923ad841b2Smrg 493cef8759bSmrg template<typename _ValueType> 4943ad841b2Smrg inline _ValueType any_cast(any&& __any) 4953ad841b2Smrg { 496627f7eb2Smrg using _Up = __remove_cvref_t<_ValueType>; 4973ad841b2Smrg static_assert(any::__is_valid_cast<_ValueType>(), 4983ad841b2Smrg "Template argument must be a reference or CopyConstructible type"); 499cef8759bSmrg static_assert(is_constructible_v<_ValueType, _Up>, 500cef8759bSmrg "Template argument must be constructible from an rvalue."); 501cef8759bSmrg auto __p = any_cast<_Up>(&__any); 5023ad841b2Smrg if (__p) 5033ad841b2Smrg return static_cast<_ValueType>(std::move(*__p)); 5043ad841b2Smrg __throw_bad_any_cast(); 5053ad841b2Smrg } 5064c3eb207Smrg /// @} 5073ad841b2Smrg 508cef8759bSmrg /// @cond undocumented 5093ad841b2Smrg template<typename _Tp> 5103ad841b2Smrg void* __any_caster(const any* __any) 5113ad841b2Smrg { 512cef8759bSmrg // any_cast<T> returns non-null if __any->type() == typeid(T) and 513cef8759bSmrg // typeid(T) ignores cv-qualifiers so remove them: 514cef8759bSmrg using _Up = remove_cv_t<_Tp>; 515cef8759bSmrg // The contained value has a decayed type, so if decay_t<U> is not U, 516cef8759bSmrg // then it's not possible to have a contained value of type U: 517cef8759bSmrg if constexpr (!is_same_v<decay_t<_Up>, _Up>) 518cef8759bSmrg return nullptr; 519cef8759bSmrg // Only copy constructible types can be used for contained values: 520cef8759bSmrg else if constexpr (!is_copy_constructible_v<_Up>) 521cef8759bSmrg return nullptr; 522cef8759bSmrg // First try comparing function addresses, which works without RTTI 523cef8759bSmrg else if (__any->_M_manager == &any::_Manager<_Up>::_S_manage 524cef8759bSmrg#if __cpp_rtti 525cef8759bSmrg || __any->type() == typeid(_Tp) 526cef8759bSmrg#endif 527cef8759bSmrg ) 5283ad841b2Smrg { 529*4ac76180Smrg return any::_Manager<_Up>::_S_access(__any->_M_storage); 5303ad841b2Smrg } 5313ad841b2Smrg return nullptr; 5323ad841b2Smrg } 533cef8759bSmrg /// @endcond 5343ad841b2Smrg 5353ad841b2Smrg /** 5363ad841b2Smrg * @brief Access the contained object. 5373ad841b2Smrg * 5383ad841b2Smrg * @tparam _ValueType The type of the contained object. 5393ad841b2Smrg * @param __any A pointer to the object to access. 5403ad841b2Smrg * @return The address of the contained object if <code> 5413ad841b2Smrg * __any != nullptr && __any.type() == typeid(_ValueType) 5423ad841b2Smrg * </code>, otherwise a null pointer. 5433ad841b2Smrg * 5443ad841b2Smrg * @{ 5453ad841b2Smrg */ 5463ad841b2Smrg template<typename _ValueType> 5473ad841b2Smrg inline const _ValueType* any_cast(const any* __any) noexcept 5483ad841b2Smrg { 549cef8759bSmrg if constexpr (is_object_v<_ValueType>) 5503ad841b2Smrg if (__any) 5513ad841b2Smrg return static_cast<_ValueType*>(__any_caster<_ValueType>(__any)); 5523ad841b2Smrg return nullptr; 5533ad841b2Smrg } 5543ad841b2Smrg 5553ad841b2Smrg template<typename _ValueType> 5563ad841b2Smrg inline _ValueType* any_cast(any* __any) noexcept 5573ad841b2Smrg { 558cef8759bSmrg if constexpr (is_object_v<_ValueType>) 5593ad841b2Smrg if (__any) 5603ad841b2Smrg return static_cast<_ValueType*>(__any_caster<_ValueType>(__any)); 5613ad841b2Smrg return nullptr; 5623ad841b2Smrg } 5634c3eb207Smrg /// @} 5643ad841b2Smrg 5653ad841b2Smrg template<typename _Tp> 5663ad841b2Smrg void 5673ad841b2Smrg any::_Manager_internal<_Tp>:: 5683ad841b2Smrg _S_manage(_Op __which, const any* __any, _Arg* __arg) 5693ad841b2Smrg { 5703ad841b2Smrg // The contained object is in _M_storage._M_buffer 5713ad841b2Smrg auto __ptr = reinterpret_cast<const _Tp*>(&__any->_M_storage._M_buffer); 5723ad841b2Smrg switch (__which) 5733ad841b2Smrg { 5743ad841b2Smrg case _Op_access: 5753ad841b2Smrg __arg->_M_obj = const_cast<_Tp*>(__ptr); 5763ad841b2Smrg break; 5773ad841b2Smrg case _Op_get_type_info: 5783ad841b2Smrg#if __cpp_rtti 5793ad841b2Smrg __arg->_M_typeinfo = &typeid(_Tp); 5803ad841b2Smrg#endif 5813ad841b2Smrg break; 5823ad841b2Smrg case _Op_clone: 5833ad841b2Smrg ::new(&__arg->_M_any->_M_storage._M_buffer) _Tp(*__ptr); 5843ad841b2Smrg __arg->_M_any->_M_manager = __any->_M_manager; 5853ad841b2Smrg break; 5863ad841b2Smrg case _Op_destroy: 5873ad841b2Smrg __ptr->~_Tp(); 5883ad841b2Smrg break; 5893ad841b2Smrg case _Op_xfer: 5903ad841b2Smrg ::new(&__arg->_M_any->_M_storage._M_buffer) _Tp 5913ad841b2Smrg (std::move(*const_cast<_Tp*>(__ptr))); 5923ad841b2Smrg __ptr->~_Tp(); 5933ad841b2Smrg __arg->_M_any->_M_manager = __any->_M_manager; 5943ad841b2Smrg const_cast<any*>(__any)->_M_manager = nullptr; 5953ad841b2Smrg break; 5963ad841b2Smrg } 5973ad841b2Smrg } 5983ad841b2Smrg 5993ad841b2Smrg template<typename _Tp> 6003ad841b2Smrg void 6013ad841b2Smrg any::_Manager_external<_Tp>:: 6023ad841b2Smrg _S_manage(_Op __which, const any* __any, _Arg* __arg) 6033ad841b2Smrg { 6043ad841b2Smrg // The contained object is *_M_storage._M_ptr 6053ad841b2Smrg auto __ptr = static_cast<const _Tp*>(__any->_M_storage._M_ptr); 6063ad841b2Smrg switch (__which) 6073ad841b2Smrg { 6083ad841b2Smrg case _Op_access: 6093ad841b2Smrg __arg->_M_obj = const_cast<_Tp*>(__ptr); 6103ad841b2Smrg break; 6113ad841b2Smrg case _Op_get_type_info: 6123ad841b2Smrg#if __cpp_rtti 6133ad841b2Smrg __arg->_M_typeinfo = &typeid(_Tp); 6143ad841b2Smrg#endif 6153ad841b2Smrg break; 6163ad841b2Smrg case _Op_clone: 6173ad841b2Smrg __arg->_M_any->_M_storage._M_ptr = new _Tp(*__ptr); 6183ad841b2Smrg __arg->_M_any->_M_manager = __any->_M_manager; 6193ad841b2Smrg break; 6203ad841b2Smrg case _Op_destroy: 6213ad841b2Smrg delete __ptr; 6223ad841b2Smrg break; 6233ad841b2Smrg case _Op_xfer: 6243ad841b2Smrg __arg->_M_any->_M_storage._M_ptr = __any->_M_storage._M_ptr; 6253ad841b2Smrg __arg->_M_any->_M_manager = __any->_M_manager; 6263ad841b2Smrg const_cast<any*>(__any)->_M_manager = nullptr; 6273ad841b2Smrg break; 6283ad841b2Smrg } 6293ad841b2Smrg } 6303ad841b2Smrg 6313ad841b2Smrg /// @} 6323ad841b2Smrg 633627f7eb2Smrg namespace __detail::__variant 634627f7eb2Smrg { 635627f7eb2Smrg template<typename> struct _Never_valueless_alt; // see <variant> 636627f7eb2Smrg 637627f7eb2Smrg // Provide the strong exception-safety guarantee when emplacing an 638627f7eb2Smrg // any into a variant. 639627f7eb2Smrg template<> 640627f7eb2Smrg struct _Never_valueless_alt<std::any> 641627f7eb2Smrg : std::true_type 642627f7eb2Smrg { }; 643627f7eb2Smrg } // namespace __detail::__variant 644627f7eb2Smrg 6453ad841b2Smrg_GLIBCXX_END_NAMESPACE_VERSION 6463ad841b2Smrg} // namespace std 6473ad841b2Smrg 648627f7eb2Smrg#endif // C++17 6493ad841b2Smrg#endif // _GLIBCXX_ANY 650