1b17d1066Smrg// <variant> -*- C++ -*- 2b17d1066Smrg 3b1e83836Smrg// Copyright (C) 2016-2022 Free Software Foundation, Inc. 4b17d1066Smrg// 5b17d1066Smrg// This file is part of the GNU ISO C++ Library. This library is free 6b17d1066Smrg// software; you can redistribute it and/or modify it under the 7b17d1066Smrg// terms of the GNU General Public License as published by the 8b17d1066Smrg// Free Software Foundation; either version 3, or (at your option) 9b17d1066Smrg// any later version. 10b17d1066Smrg 11b17d1066Smrg// This library is distributed in the hope that it will be useful, 12b17d1066Smrg// but WITHOUT ANY WARRANTY; without even the implied warranty of 13b17d1066Smrg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14b17d1066Smrg// GNU General Public License for more details. 15b17d1066Smrg 16b17d1066Smrg// Under Section 7 of GPL version 3, you are granted additional 17b17d1066Smrg// permissions described in the GCC Runtime Library Exception, version 18b17d1066Smrg// 3.1, as published by the Free Software Foundation. 19b17d1066Smrg 20b17d1066Smrg// You should have received a copy of the GNU General Public License and 21b17d1066Smrg// a copy of the GCC Runtime Library Exception along with this program; 22b17d1066Smrg// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23b17d1066Smrg// <http://www.gnu.org/licenses/>. 24b17d1066Smrg 25b17d1066Smrg/** @file variant 26a448f87cSmrg * This is the `<variant>` C++ Library header. 27b17d1066Smrg */ 28b17d1066Smrg 29b17d1066Smrg#ifndef _GLIBCXX_VARIANT 30b17d1066Smrg#define _GLIBCXX_VARIANT 1 31b17d1066Smrg 32b17d1066Smrg#pragma GCC system_header 33b17d1066Smrg 34b17d1066Smrg#if __cplusplus >= 201703L 35b17d1066Smrg 36b1e83836Smrg#include <initializer_list> 37b17d1066Smrg#include <type_traits> 38b17d1066Smrg#include <bits/enable_special_members.h> 39b1e83836Smrg#include <bits/exception_defines.h> 40b17d1066Smrg#include <bits/functional_hash.h> 41b17d1066Smrg#include <bits/invoke.h> 42b17d1066Smrg#include <bits/parse_numbers.h> 43b17d1066Smrg#include <bits/stl_iterator_base_types.h> 44b17d1066Smrg#include <bits/stl_iterator_base_funcs.h> 45b17d1066Smrg#include <bits/stl_construct.h> 46b1e83836Smrg#include <bits/utility.h> // in_place_index_t 47b1e83836Smrg#if __cplusplus >= 202002L 48fb8a8121Smrg# include <compare> 49fb8a8121Smrg#endif 50b17d1066Smrg 51b1e83836Smrg#if __cpp_concepts >= 202002L && __cpp_constexpr >= 201811L 52b1e83836Smrg// P2231R1 constexpr needs constexpr unions and constrained destructors. 53b1e83836Smrg# define __cpp_lib_variant 202106L 54b1e83836Smrg#else 55b1e83836Smrg# include <ext/aligned_buffer.h> // Use __aligned_membuf instead of union. 56b1e83836Smrg# define __cpp_lib_variant 202102L 57b1e83836Smrg#endif 58b1e83836Smrg 59b17d1066Smrgnamespace std _GLIBCXX_VISIBILITY(default) 60b17d1066Smrg{ 61a3e9eb18Smrg_GLIBCXX_BEGIN_NAMESPACE_VERSION 62a3e9eb18Smrg 63b17d1066Smrg template<typename... _Types> class tuple; 64b17d1066Smrg template<typename... _Types> class variant; 65b17d1066Smrg template <typename> struct hash; 66b17d1066Smrg 67b17d1066Smrg template<typename _Variant> 68b17d1066Smrg struct variant_size; 69b17d1066Smrg 70b17d1066Smrg template<typename _Variant> 71b17d1066Smrg struct variant_size<const _Variant> : variant_size<_Variant> {}; 72b17d1066Smrg 73b17d1066Smrg template<typename _Variant> 74b17d1066Smrg struct variant_size<volatile _Variant> : variant_size<_Variant> {}; 75b17d1066Smrg 76b17d1066Smrg template<typename _Variant> 77b17d1066Smrg struct variant_size<const volatile _Variant> : variant_size<_Variant> {}; 78b17d1066Smrg 79b17d1066Smrg template<typename... _Types> 80b17d1066Smrg struct variant_size<variant<_Types...>> 81b17d1066Smrg : std::integral_constant<size_t, sizeof...(_Types)> {}; 82b17d1066Smrg 83b17d1066Smrg template<typename _Variant> 84b17d1066Smrg inline constexpr size_t variant_size_v = variant_size<_Variant>::value; 85b17d1066Smrg 86b1e83836Smrg template<typename... _Types> 87b1e83836Smrg inline constexpr size_t 88b1e83836Smrg variant_size_v<variant<_Types...>> = sizeof...(_Types); 89b1e83836Smrg 90b1e83836Smrg template<typename... _Types> 91b1e83836Smrg inline constexpr size_t 92b1e83836Smrg variant_size_v<const variant<_Types...>> = sizeof...(_Types); 93b1e83836Smrg 94b17d1066Smrg template<size_t _Np, typename _Variant> 95b17d1066Smrg struct variant_alternative; 96b17d1066Smrg 97b1e83836Smrg template<size_t _Np, typename... _Types> 98b1e83836Smrg struct variant_alternative<_Np, variant<_Types...>> 99b1e83836Smrg { 100b1e83836Smrg static_assert(_Np < sizeof...(_Types)); 101b17d1066Smrg 102b1e83836Smrg using type = typename _Nth_type<_Np, _Types...>::type; 103b1e83836Smrg }; 104b17d1066Smrg 105b17d1066Smrg template<size_t _Np, typename _Variant> 106b17d1066Smrg using variant_alternative_t = 107b17d1066Smrg typename variant_alternative<_Np, _Variant>::type; 108b17d1066Smrg 109b17d1066Smrg template<size_t _Np, typename _Variant> 110b17d1066Smrg struct variant_alternative<_Np, const _Variant> 111b17d1066Smrg { using type = add_const_t<variant_alternative_t<_Np, _Variant>>; }; 112b17d1066Smrg 113b17d1066Smrg template<size_t _Np, typename _Variant> 114b17d1066Smrg struct variant_alternative<_Np, volatile _Variant> 115b17d1066Smrg { using type = add_volatile_t<variant_alternative_t<_Np, _Variant>>; }; 116b17d1066Smrg 117b17d1066Smrg template<size_t _Np, typename _Variant> 118b17d1066Smrg struct variant_alternative<_Np, const volatile _Variant> 119b17d1066Smrg { using type = add_cv_t<variant_alternative_t<_Np, _Variant>>; }; 120b17d1066Smrg 121b17d1066Smrg inline constexpr size_t variant_npos = -1; 122b17d1066Smrg 123b17d1066Smrg template<size_t _Np, typename... _Types> 124b17d1066Smrg constexpr variant_alternative_t<_Np, variant<_Types...>>& 125b17d1066Smrg get(variant<_Types...>&); 126b17d1066Smrg 127b17d1066Smrg template<size_t _Np, typename... _Types> 128b17d1066Smrg constexpr variant_alternative_t<_Np, variant<_Types...>>&& 129b17d1066Smrg get(variant<_Types...>&&); 130b17d1066Smrg 131b17d1066Smrg template<size_t _Np, typename... _Types> 132b17d1066Smrg constexpr variant_alternative_t<_Np, variant<_Types...>> const& 133b17d1066Smrg get(const variant<_Types...>&); 134b17d1066Smrg 135b17d1066Smrg template<size_t _Np, typename... _Types> 136b17d1066Smrg constexpr variant_alternative_t<_Np, variant<_Types...>> const&& 137b17d1066Smrg get(const variant<_Types...>&&); 138b17d1066Smrg 139fb8a8121Smrg template<typename _Result_type, typename _Visitor, typename... _Variants> 140181254a7Smrg constexpr decltype(auto) 141181254a7Smrg __do_visit(_Visitor&& __visitor, _Variants&&... __variants); 142181254a7Smrg 143181254a7Smrg template <typename... _Types, typename _Tp> 144b1e83836Smrg _GLIBCXX20_CONSTEXPR 145181254a7Smrg decltype(auto) 146181254a7Smrg __variant_cast(_Tp&& __rhs) 147181254a7Smrg { 148181254a7Smrg if constexpr (is_lvalue_reference_v<_Tp>) 149181254a7Smrg { 150181254a7Smrg if constexpr (is_const_v<remove_reference_t<_Tp>>) 151181254a7Smrg return static_cast<const variant<_Types...>&>(__rhs); 152181254a7Smrg else 153181254a7Smrg return static_cast<variant<_Types...>&>(__rhs); 154181254a7Smrg } 155181254a7Smrg else 156181254a7Smrg return static_cast<variant<_Types...>&&>(__rhs); 157181254a7Smrg } 158181254a7Smrg 159b17d1066Smrgnamespace __detail 160b17d1066Smrg{ 161b17d1066Smrgnamespace __variant 162b17d1066Smrg{ 163181254a7Smrg // used for raw visitation 164181254a7Smrg struct __variant_cookie {}; 165181254a7Smrg // used for raw visitation with indices passed in 166181254a7Smrg struct __variant_idx_cookie { using type = __variant_idx_cookie; }; 167fb8a8121Smrg // Used to enable deduction (and same-type checking) for std::visit: 168b1e83836Smrg template<typename _Tp> struct __deduce_visit_result { using type = _Tp; }; 169181254a7Smrg 170fb8a8121Smrg // Visit variants that might be valueless. 171fb8a8121Smrg template<typename _Visitor, typename... _Variants> 172fb8a8121Smrg constexpr void 173fb8a8121Smrg __raw_visit(_Visitor&& __visitor, _Variants&&... __variants) 174fb8a8121Smrg { 175fb8a8121Smrg std::__do_visit<__variant_cookie>(std::forward<_Visitor>(__visitor), 176fb8a8121Smrg std::forward<_Variants>(__variants)...); 177fb8a8121Smrg } 178fb8a8121Smrg 179fb8a8121Smrg // Visit variants that might be valueless, passing indices to the visitor. 180fb8a8121Smrg template<typename _Visitor, typename... _Variants> 181fb8a8121Smrg constexpr void 182fb8a8121Smrg __raw_idx_visit(_Visitor&& __visitor, _Variants&&... __variants) 183fb8a8121Smrg { 184fb8a8121Smrg std::__do_visit<__variant_idx_cookie>(std::forward<_Visitor>(__visitor), 185fb8a8121Smrg std::forward<_Variants>(__variants)...); 186fb8a8121Smrg } 187fb8a8121Smrg 188b1e83836Smrg // The __as function templates implement the exposition-only "as-variant" 189b1e83836Smrg 190b1e83836Smrg template<typename... _Types> 191b1e83836Smrg constexpr std::variant<_Types...>& 192b1e83836Smrg __as(std::variant<_Types...>& __v) noexcept 193b1e83836Smrg { return __v; } 194b1e83836Smrg 195b1e83836Smrg template<typename... _Types> 196b1e83836Smrg constexpr const std::variant<_Types...>& 197b1e83836Smrg __as(const std::variant<_Types...>& __v) noexcept 198b1e83836Smrg { return __v; } 199b1e83836Smrg 200b1e83836Smrg template<typename... _Types> 201b1e83836Smrg constexpr std::variant<_Types...>&& 202b1e83836Smrg __as(std::variant<_Types...>&& __v) noexcept 203b1e83836Smrg { return std::move(__v); } 204b1e83836Smrg 205b1e83836Smrg template<typename... _Types> 206b1e83836Smrg constexpr const std::variant<_Types...>&& 207b1e83836Smrg __as(const std::variant<_Types...>&& __v) noexcept 208b1e83836Smrg { return std::move(__v); } 209b1e83836Smrg 210b1e83836Smrg // For C++17: 211fb8a8121Smrg // _Uninitialized<T> is guaranteed to be a trivially destructible type, 212fb8a8121Smrg // even if T is not. 213b1e83836Smrg // For C++20: 214b1e83836Smrg // _Uninitialized<T> is trivially destructible iff T is, so _Variant_union 215b1e83836Smrg // needs a constrained non-trivial destructor. 216fb8a8121Smrg template<typename _Type, bool = std::is_trivially_destructible_v<_Type>> 217b17d1066Smrg struct _Uninitialized; 218b17d1066Smrg 219b17d1066Smrg template<typename _Type> 220b17d1066Smrg struct _Uninitialized<_Type, true> 221b17d1066Smrg { 222b17d1066Smrg template<typename... _Args> 223181254a7Smrg constexpr 224181254a7Smrg _Uninitialized(in_place_index_t<0>, _Args&&... __args) 225b17d1066Smrg : _M_storage(std::forward<_Args>(__args)...) 226b17d1066Smrg { } 227b17d1066Smrg 228181254a7Smrg constexpr const _Type& _M_get() const & noexcept 229b17d1066Smrg { return _M_storage; } 230b17d1066Smrg 231181254a7Smrg constexpr _Type& _M_get() & noexcept 232b17d1066Smrg { return _M_storage; } 233b17d1066Smrg 234181254a7Smrg constexpr const _Type&& _M_get() const && noexcept 235b17d1066Smrg { return std::move(_M_storage); } 236b17d1066Smrg 237181254a7Smrg constexpr _Type&& _M_get() && noexcept 238b17d1066Smrg { return std::move(_M_storage); } 239b17d1066Smrg 240b17d1066Smrg _Type _M_storage; 241b17d1066Smrg }; 242b17d1066Smrg 243b17d1066Smrg template<typename _Type> 244b17d1066Smrg struct _Uninitialized<_Type, false> 245b17d1066Smrg { 246b1e83836Smrg#if __cpp_lib_variant >= 202106L 247b1e83836Smrg template<typename... _Args> 248b1e83836Smrg constexpr 249b1e83836Smrg _Uninitialized(in_place_index_t<0>, _Args&&... __args) 250b1e83836Smrg : _M_storage(std::forward<_Args>(__args)...) 251b1e83836Smrg { } 252b1e83836Smrg 253b1e83836Smrg constexpr ~_Uninitialized() { } 254b1e83836Smrg 255b1e83836Smrg _Uninitialized(const _Uninitialized&) = default; 256b1e83836Smrg _Uninitialized(_Uninitialized&&) = default; 257b1e83836Smrg _Uninitialized& operator=(const _Uninitialized&) = default; 258b1e83836Smrg _Uninitialized& operator=(_Uninitialized&&) = default; 259b1e83836Smrg 260b1e83836Smrg constexpr const _Type& _M_get() const & noexcept 261b1e83836Smrg { return _M_storage; } 262b1e83836Smrg 263b1e83836Smrg constexpr _Type& _M_get() & noexcept 264b1e83836Smrg { return _M_storage; } 265b1e83836Smrg 266b1e83836Smrg constexpr const _Type&& _M_get() const && noexcept 267b1e83836Smrg { return std::move(_M_storage); } 268b1e83836Smrg 269b1e83836Smrg constexpr _Type&& _M_get() && noexcept 270b1e83836Smrg { return std::move(_M_storage); } 271b1e83836Smrg 272b1e83836Smrg struct _Empty_byte { }; 273b1e83836Smrg 274b1e83836Smrg union { 275b1e83836Smrg _Empty_byte _M_empty; 276b1e83836Smrg _Type _M_storage; 277b1e83836Smrg }; 278b1e83836Smrg#else 279b17d1066Smrg template<typename... _Args> 280181254a7Smrg constexpr 281181254a7Smrg _Uninitialized(in_place_index_t<0>, _Args&&... __args) 282181254a7Smrg { 283181254a7Smrg ::new ((void*)std::addressof(_M_storage)) 284181254a7Smrg _Type(std::forward<_Args>(__args)...); 285181254a7Smrg } 286b17d1066Smrg 287181254a7Smrg const _Type& _M_get() const & noexcept 288b17d1066Smrg { return *_M_storage._M_ptr(); } 289b17d1066Smrg 290181254a7Smrg _Type& _M_get() & noexcept 291b17d1066Smrg { return *_M_storage._M_ptr(); } 292b17d1066Smrg 293181254a7Smrg const _Type&& _M_get() const && noexcept 294b17d1066Smrg { return std::move(*_M_storage._M_ptr()); } 295b17d1066Smrg 296181254a7Smrg _Type&& _M_get() && noexcept 297b17d1066Smrg { return std::move(*_M_storage._M_ptr()); } 298b17d1066Smrg 299b17d1066Smrg __gnu_cxx::__aligned_membuf<_Type> _M_storage; 300b1e83836Smrg#endif 301b17d1066Smrg }; 302b17d1066Smrg 303b17d1066Smrg template<size_t _Np, typename _Union> 304181254a7Smrg constexpr decltype(auto) 305b1e83836Smrg __get_n(_Union&& __u) noexcept 306b17d1066Smrg { 307b1e83836Smrg if constexpr (_Np == 0) 308b1e83836Smrg return std::forward<_Union>(__u)._M_first._M_get(); 309b1e83836Smrg else if constexpr (_Np == 1) 310b1e83836Smrg return std::forward<_Union>(__u)._M_rest._M_first._M_get(); 311b1e83836Smrg else if constexpr (_Np == 2) 312b1e83836Smrg return std::forward<_Union>(__u)._M_rest._M_rest._M_first._M_get(); 313b1e83836Smrg else 314b1e83836Smrg return __variant::__get_n<_Np - 3>( 315b1e83836Smrg std::forward<_Union>(__u)._M_rest._M_rest._M_rest); 316b17d1066Smrg } 317b17d1066Smrg 318b17d1066Smrg // Returns the typed storage for __v. 319b17d1066Smrg template<size_t _Np, typename _Variant> 320181254a7Smrg constexpr decltype(auto) 321181254a7Smrg __get(_Variant&& __v) noexcept 322b1e83836Smrg { return __variant::__get_n<_Np>(std::forward<_Variant>(__v)._M_u); } 323b17d1066Smrg 324*0a307195Smrg // Gets the _Uninitialized to construct into for __u. 325*0a307195Smrg template<size_t _Np, typename _Union> 326*0a307195Smrg constexpr decltype(auto) 327*0a307195Smrg __construct_n(_Union& __u) noexcept 328*0a307195Smrg { 329*0a307195Smrg if constexpr (_Np == 0) 330*0a307195Smrg return &__u._M_first; 331*0a307195Smrg else if constexpr (_Np == 1) 332*0a307195Smrg { 333*0a307195Smrg std::_Construct(&__u._M_rest); 334*0a307195Smrg return &__u._M_rest._M_first; 335*0a307195Smrg } 336*0a307195Smrg else if constexpr (_Np == 2) 337*0a307195Smrg { 338*0a307195Smrg std::_Construct(&__u._M_rest); 339*0a307195Smrg std::_Construct(&__u._M_rest._M_rest); 340*0a307195Smrg return &__u._M_rest._M_rest._M_first; 341*0a307195Smrg } 342*0a307195Smrg else 343*0a307195Smrg { 344*0a307195Smrg std::_Construct(&__u._M_rest); 345*0a307195Smrg std::_Construct(&__u._M_rest._M_rest); 346*0a307195Smrg std::_Construct(&__u._M_rest._M_rest._M_rest); 347*0a307195Smrg return __variant::__construct_n<_Np - 3>(__u._M_rest._M_rest._M_rest); 348*0a307195Smrg } 349*0a307195Smrg } 350*0a307195Smrg 351a3e9eb18Smrg template<typename... _Types> 352a3e9eb18Smrg struct _Traits 353a3e9eb18Smrg { 354a3e9eb18Smrg static constexpr bool _S_default_ctor = 355a3e9eb18Smrg is_default_constructible_v<typename _Nth_type<0, _Types...>::type>; 356a3e9eb18Smrg static constexpr bool _S_copy_ctor = 357a3e9eb18Smrg (is_copy_constructible_v<_Types> && ...); 358a3e9eb18Smrg static constexpr bool _S_move_ctor = 359a3e9eb18Smrg (is_move_constructible_v<_Types> && ...); 360a3e9eb18Smrg static constexpr bool _S_copy_assign = 361181254a7Smrg _S_copy_ctor 362a3e9eb18Smrg && (is_copy_assignable_v<_Types> && ...); 363a3e9eb18Smrg static constexpr bool _S_move_assign = 364a3e9eb18Smrg _S_move_ctor 365a3e9eb18Smrg && (is_move_assignable_v<_Types> && ...); 366a3e9eb18Smrg 367a3e9eb18Smrg static constexpr bool _S_trivial_dtor = 368a3e9eb18Smrg (is_trivially_destructible_v<_Types> && ...); 369a3e9eb18Smrg static constexpr bool _S_trivial_copy_ctor = 370a3e9eb18Smrg (is_trivially_copy_constructible_v<_Types> && ...); 371a3e9eb18Smrg static constexpr bool _S_trivial_move_ctor = 372a3e9eb18Smrg (is_trivially_move_constructible_v<_Types> && ...); 373a3e9eb18Smrg static constexpr bool _S_trivial_copy_assign = 374181254a7Smrg _S_trivial_dtor && _S_trivial_copy_ctor 375181254a7Smrg && (is_trivially_copy_assignable_v<_Types> && ...); 376a3e9eb18Smrg static constexpr bool _S_trivial_move_assign = 377181254a7Smrg _S_trivial_dtor && _S_trivial_move_ctor 378181254a7Smrg && (is_trivially_move_assignable_v<_Types> && ...); 379a3e9eb18Smrg 380a3e9eb18Smrg // The following nothrow traits are for non-trivial SMFs. Trivial SMFs 381a3e9eb18Smrg // are always nothrow. 382a3e9eb18Smrg static constexpr bool _S_nothrow_default_ctor = 383a3e9eb18Smrg is_nothrow_default_constructible_v< 384a3e9eb18Smrg typename _Nth_type<0, _Types...>::type>; 385a3e9eb18Smrg static constexpr bool _S_nothrow_copy_ctor = false; 386a3e9eb18Smrg static constexpr bool _S_nothrow_move_ctor = 387a3e9eb18Smrg (is_nothrow_move_constructible_v<_Types> && ...); 388a3e9eb18Smrg static constexpr bool _S_nothrow_copy_assign = false; 389a3e9eb18Smrg static constexpr bool _S_nothrow_move_assign = 390181254a7Smrg _S_nothrow_move_ctor 391181254a7Smrg && (is_nothrow_move_assignable_v<_Types> && ...); 392a3e9eb18Smrg }; 393a3e9eb18Smrg 394b17d1066Smrg // Defines members and ctors. 395b17d1066Smrg template<typename... _Types> 396b1e83836Smrg union _Variadic_union 397b1e83836Smrg { 398b1e83836Smrg _Variadic_union() = default; 399b1e83836Smrg 400b1e83836Smrg template<size_t _Np, typename... _Args> 401b1e83836Smrg _Variadic_union(in_place_index_t<_Np>, _Args&&...) = delete; 402b1e83836Smrg }; 403b17d1066Smrg 404b17d1066Smrg template<typename _First, typename... _Rest> 405b17d1066Smrg union _Variadic_union<_First, _Rest...> 406b17d1066Smrg { 407b17d1066Smrg constexpr _Variadic_union() : _M_rest() { } 408b17d1066Smrg 409b17d1066Smrg template<typename... _Args> 410b1e83836Smrg constexpr 411b1e83836Smrg _Variadic_union(in_place_index_t<0>, _Args&&... __args) 412b17d1066Smrg : _M_first(in_place_index<0>, std::forward<_Args>(__args)...) 413b17d1066Smrg { } 414b17d1066Smrg 415b17d1066Smrg template<size_t _Np, typename... _Args> 416b1e83836Smrg constexpr 417b1e83836Smrg _Variadic_union(in_place_index_t<_Np>, _Args&&... __args) 418b17d1066Smrg : _M_rest(in_place_index<_Np-1>, std::forward<_Args>(__args)...) 419b17d1066Smrg { } 420b17d1066Smrg 421b1e83836Smrg#if __cpp_lib_variant >= 202106L 422b1e83836Smrg _Variadic_union(const _Variadic_union&) = default; 423b1e83836Smrg _Variadic_union(_Variadic_union&&) = default; 424b1e83836Smrg _Variadic_union& operator=(const _Variadic_union&) = default; 425b1e83836Smrg _Variadic_union& operator=(_Variadic_union&&) = default; 426b1e83836Smrg 427b1e83836Smrg ~_Variadic_union() = default; 428b1e83836Smrg 429b1e83836Smrg constexpr ~_Variadic_union() 430b1e83836Smrg requires (!__has_trivial_destructor(_First)) 431b1e83836Smrg || (!__has_trivial_destructor(_Variadic_union<_Rest...>)) 432b1e83836Smrg { } 433b1e83836Smrg#endif 434b1e83836Smrg 435b17d1066Smrg _Uninitialized<_First> _M_first; 436b17d1066Smrg _Variadic_union<_Rest...> _M_rest; 437b17d1066Smrg }; 438b17d1066Smrg 439181254a7Smrg // _Never_valueless_alt is true for variant alternatives that can 440181254a7Smrg // always be placed in a variant without it becoming valueless. 441181254a7Smrg 442181254a7Smrg // For suitably-small, trivially copyable types we can create temporaries 443181254a7Smrg // on the stack and then memcpy them into place. 444181254a7Smrg template<typename _Tp> 445181254a7Smrg struct _Never_valueless_alt 446181254a7Smrg : __and_<bool_constant<sizeof(_Tp) <= 256>, is_trivially_copyable<_Tp>> 447181254a7Smrg { }; 448181254a7Smrg 449181254a7Smrg // Specialize _Never_valueless_alt for other types which have a 450181254a7Smrg // non-throwing and cheap move construction and move assignment operator, 451181254a7Smrg // so that emplacing the type will provide the strong exception-safety 452181254a7Smrg // guarantee, by creating and moving a temporary. 453181254a7Smrg // Whether _Never_valueless_alt<T> is true or not affects the ABI of a 454181254a7Smrg // variant using that alternative, so we can't change the value later! 455181254a7Smrg 456181254a7Smrg // True if every alternative in _Types... can be emplaced in a variant 457181254a7Smrg // without it becoming valueless. If this is true, variant<_Types...> 458181254a7Smrg // can never be valueless, which enables some minor optimizations. 459181254a7Smrg template <typename... _Types> 460181254a7Smrg constexpr bool __never_valueless() 461181254a7Smrg { 462181254a7Smrg return _Traits<_Types...>::_S_move_assign 463181254a7Smrg && (_Never_valueless_alt<_Types>::value && ...); 464181254a7Smrg } 465181254a7Smrg 466b17d1066Smrg // Defines index and the dtor, possibly trivial. 467b17d1066Smrg template<bool __trivially_destructible, typename... _Types> 468b17d1066Smrg struct _Variant_storage; 469b17d1066Smrg 470b17d1066Smrg template <typename... _Types> 471b17d1066Smrg using __select_index = 472181254a7Smrg typename __select_int::_Select_int_base<sizeof...(_Types), 473b17d1066Smrg unsigned char, 474b17d1066Smrg unsigned short>::type::value_type; 475b17d1066Smrg 476b17d1066Smrg template<typename... _Types> 477b17d1066Smrg struct _Variant_storage<false, _Types...> 478b17d1066Smrg { 479fb8a8121Smrg constexpr 480fb8a8121Smrg _Variant_storage() 481fb8a8121Smrg : _M_index(static_cast<__index_type>(variant_npos)) 482b17d1066Smrg { } 483b17d1066Smrg 484fb8a8121Smrg template<size_t _Np, typename... _Args> 485fb8a8121Smrg constexpr 486fb8a8121Smrg _Variant_storage(in_place_index_t<_Np>, _Args&&... __args) 487fb8a8121Smrg : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...), 488fb8a8121Smrg _M_index{_Np} 489fb8a8121Smrg { } 490b17d1066Smrg 491b1e83836Smrg constexpr void 492b1e83836Smrg _M_reset() 493b17d1066Smrg { 494fb8a8121Smrg if (!_M_valid()) [[unlikely]] 495fb8a8121Smrg return; 496fb8a8121Smrg 497fb8a8121Smrg std::__do_visit<void>([](auto&& __this_mem) mutable 498fb8a8121Smrg { 499fb8a8121Smrg std::_Destroy(std::__addressof(__this_mem)); 500fb8a8121Smrg }, __variant_cast<_Types...>(*this)); 501fb8a8121Smrg 502fb8a8121Smrg _M_index = static_cast<__index_type>(variant_npos); 503b17d1066Smrg } 504b17d1066Smrg 505b1e83836Smrg _GLIBCXX20_CONSTEXPR 506b17d1066Smrg ~_Variant_storage() 507b17d1066Smrg { _M_reset(); } 508b17d1066Smrg 509a3e9eb18Smrg constexpr bool 510a3e9eb18Smrg _M_valid() const noexcept 511a3e9eb18Smrg { 512fb8a8121Smrg if constexpr (__variant::__never_valueless<_Types...>()) 513181254a7Smrg return true; 514a3e9eb18Smrg return this->_M_index != __index_type(variant_npos); 515a3e9eb18Smrg } 516a3e9eb18Smrg 517b17d1066Smrg _Variadic_union<_Types...> _M_u; 518b17d1066Smrg using __index_type = __select_index<_Types...>; 519b17d1066Smrg __index_type _M_index; 520b17d1066Smrg }; 521b17d1066Smrg 522b17d1066Smrg template<typename... _Types> 523b17d1066Smrg struct _Variant_storage<true, _Types...> 524b17d1066Smrg { 525fb8a8121Smrg constexpr 526fb8a8121Smrg _Variant_storage() 527fb8a8121Smrg : _M_index(static_cast<__index_type>(variant_npos)) 528b17d1066Smrg { } 529b17d1066Smrg 530fb8a8121Smrg template<size_t _Np, typename... _Args> 531fb8a8121Smrg constexpr 532fb8a8121Smrg _Variant_storage(in_place_index_t<_Np>, _Args&&... __args) 533fb8a8121Smrg : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...), 534fb8a8121Smrg _M_index{_Np} 535fb8a8121Smrg { } 536fb8a8121Smrg 537b1e83836Smrg constexpr void 538b1e83836Smrg _M_reset() noexcept 539fb8a8121Smrg { _M_index = static_cast<__index_type>(variant_npos); } 540b17d1066Smrg 541a3e9eb18Smrg constexpr bool 542a3e9eb18Smrg _M_valid() const noexcept 543a3e9eb18Smrg { 544fb8a8121Smrg if constexpr (__variant::__never_valueless<_Types...>()) 545181254a7Smrg return true; 546b1e83836Smrg // It would be nice if we could just return true for -fno-exceptions. 547b1e83836Smrg // It's possible (but inadvisable) that a std::variant could become 548b1e83836Smrg // valueless in a translation unit compiled with -fexceptions and then 549b1e83836Smrg // be passed to functions compiled with -fno-exceptions. We would need 550b1e83836Smrg // some #ifdef _GLIBCXX_NO_EXCEPTIONS_GLOBALLY property to elide all 551b1e83836Smrg // checks for valueless_by_exception(). 552fb8a8121Smrg return this->_M_index != static_cast<__index_type>(variant_npos); 553a3e9eb18Smrg } 554a3e9eb18Smrg 555b17d1066Smrg _Variadic_union<_Types...> _M_u; 556b17d1066Smrg using __index_type = __select_index<_Types...>; 557b17d1066Smrg __index_type _M_index; 558b17d1066Smrg }; 559b17d1066Smrg 560b1e83836Smrg // Implementation of v.emplace<N>(args...). 561b1e83836Smrg template<size_t _Np, bool _Triv, typename... _Types, typename... _Args> 562b1e83836Smrg _GLIBCXX20_CONSTEXPR 563b1e83836Smrg inline void 564b1e83836Smrg __emplace(_Variant_storage<_Triv, _Types...>& __v, _Args&&... __args) 565b1e83836Smrg { 566b1e83836Smrg __v._M_reset(); 567*0a307195Smrg auto* __addr = __variant::__construct_n<_Np>(__v._M_u); 568*0a307195Smrg std::_Construct(__addr, in_place_index<0>, 569*0a307195Smrg std::forward<_Args>(__args)...); 570b1e83836Smrg // Construction didn't throw, so can set the new index now: 571b1e83836Smrg __v._M_index = _Np; 572b1e83836Smrg } 573b1e83836Smrg 574b17d1066Smrg template<typename... _Types> 575a3e9eb18Smrg using _Variant_storage_alias = 576a3e9eb18Smrg _Variant_storage<_Traits<_Types...>::_S_trivial_dtor, _Types...>; 577a3e9eb18Smrg 578a3e9eb18Smrg // The following are (Copy|Move) (ctor|assign) layers for forwarding 579a3e9eb18Smrg // triviality and handling non-trivial SMF behaviors. 580a3e9eb18Smrg 581a3e9eb18Smrg template<bool, typename... _Types> 582a3e9eb18Smrg struct _Copy_ctor_base : _Variant_storage_alias<_Types...> 583b17d1066Smrg { 584a3e9eb18Smrg using _Base = _Variant_storage_alias<_Types...>; 585a3e9eb18Smrg using _Base::_Base; 586b17d1066Smrg 587b1e83836Smrg _GLIBCXX20_CONSTEXPR 588a3e9eb18Smrg _Copy_ctor_base(const _Copy_ctor_base& __rhs) 589a3e9eb18Smrg noexcept(_Traits<_Types...>::_S_nothrow_copy_ctor) 590b17d1066Smrg { 591b1e83836Smrg __variant::__raw_idx_visit( 592b1e83836Smrg [this](auto&& __rhs_mem, auto __rhs_index) mutable 593b1e83836Smrg { 594b1e83836Smrg constexpr size_t __j = __rhs_index; 595b1e83836Smrg if constexpr (__j != variant_npos) 596b1e83836Smrg std::_Construct(std::__addressof(this->_M_u), 597b1e83836Smrg in_place_index<__j>, __rhs_mem); 598b1e83836Smrg }, __variant_cast<_Types...>(__rhs)); 599b1e83836Smrg this->_M_index = __rhs._M_index; 600b17d1066Smrg } 601b17d1066Smrg 602a3e9eb18Smrg _Copy_ctor_base(_Copy_ctor_base&&) = default; 603a3e9eb18Smrg _Copy_ctor_base& operator=(const _Copy_ctor_base&) = default; 604a3e9eb18Smrg _Copy_ctor_base& operator=(_Copy_ctor_base&&) = default; 605a3e9eb18Smrg }; 606a3e9eb18Smrg 607a3e9eb18Smrg template<typename... _Types> 608a3e9eb18Smrg struct _Copy_ctor_base<true, _Types...> : _Variant_storage_alias<_Types...> 609a3e9eb18Smrg { 610a3e9eb18Smrg using _Base = _Variant_storage_alias<_Types...>; 611a3e9eb18Smrg using _Base::_Base; 612a3e9eb18Smrg }; 613a3e9eb18Smrg 614a3e9eb18Smrg template<typename... _Types> 615a3e9eb18Smrg using _Copy_ctor_alias = 616a3e9eb18Smrg _Copy_ctor_base<_Traits<_Types...>::_S_trivial_copy_ctor, _Types...>; 617a3e9eb18Smrg 618a3e9eb18Smrg template<bool, typename... _Types> 619a3e9eb18Smrg struct _Move_ctor_base : _Copy_ctor_alias<_Types...> 620a3e9eb18Smrg { 621a3e9eb18Smrg using _Base = _Copy_ctor_alias<_Types...>; 622a3e9eb18Smrg using _Base::_Base; 623a3e9eb18Smrg 624b1e83836Smrg _GLIBCXX20_CONSTEXPR 625a3e9eb18Smrg _Move_ctor_base(_Move_ctor_base&& __rhs) 626a3e9eb18Smrg noexcept(_Traits<_Types...>::_S_nothrow_move_ctor) 627b17d1066Smrg { 628b1e83836Smrg __variant::__raw_idx_visit( 629b1e83836Smrg [this](auto&& __rhs_mem, auto __rhs_index) mutable 630a3e9eb18Smrg { 631b1e83836Smrg constexpr size_t __j = __rhs_index; 632b1e83836Smrg if constexpr (__j != variant_npos) 633b1e83836Smrg std::_Construct(std::__addressof(this->_M_u), 634b1e83836Smrg in_place_index<__j>, 635b1e83836Smrg std::forward<decltype(__rhs_mem)>(__rhs_mem)); 636b1e83836Smrg }, __variant_cast<_Types...>(std::move(__rhs))); 637b1e83836Smrg this->_M_index = __rhs._M_index; 638a3e9eb18Smrg } 6398b6133e5Smrg 640a3e9eb18Smrg _Move_ctor_base(const _Move_ctor_base&) = default; 641a3e9eb18Smrg _Move_ctor_base& operator=(const _Move_ctor_base&) = default; 642a3e9eb18Smrg _Move_ctor_base& operator=(_Move_ctor_base&&) = default; 643a3e9eb18Smrg }; 644a3e9eb18Smrg 645a3e9eb18Smrg template<typename... _Types> 646a3e9eb18Smrg struct _Move_ctor_base<true, _Types...> : _Copy_ctor_alias<_Types...> 647a3e9eb18Smrg { 648a3e9eb18Smrg using _Base = _Copy_ctor_alias<_Types...>; 649a3e9eb18Smrg using _Base::_Base; 650a3e9eb18Smrg }; 651a3e9eb18Smrg 652a3e9eb18Smrg template<typename... _Types> 653a3e9eb18Smrg using _Move_ctor_alias = 654a3e9eb18Smrg _Move_ctor_base<_Traits<_Types...>::_S_trivial_move_ctor, _Types...>; 655a3e9eb18Smrg 656a3e9eb18Smrg template<bool, typename... _Types> 657a3e9eb18Smrg struct _Copy_assign_base : _Move_ctor_alias<_Types...> 658a3e9eb18Smrg { 659a3e9eb18Smrg using _Base = _Move_ctor_alias<_Types...>; 660a3e9eb18Smrg using _Base::_Base; 661a3e9eb18Smrg 662b1e83836Smrg _GLIBCXX20_CONSTEXPR 663a3e9eb18Smrg _Copy_assign_base& 664a3e9eb18Smrg operator=(const _Copy_assign_base& __rhs) 665a3e9eb18Smrg noexcept(_Traits<_Types...>::_S_nothrow_copy_assign) 66614f5a3b0Smrg { 667fb8a8121Smrg __variant::__raw_idx_visit( 668fb8a8121Smrg [this](auto&& __rhs_mem, auto __rhs_index) mutable 6698b6133e5Smrg { 670b1e83836Smrg constexpr size_t __j = __rhs_index; 671b1e83836Smrg if constexpr (__j == variant_npos) 672b1e83836Smrg this->_M_reset(); // Make *this valueless. 673b1e83836Smrg else if (this->_M_index == __j) 674b1e83836Smrg __variant::__get<__j>(*this) = __rhs_mem; 675181254a7Smrg else 676181254a7Smrg { 677b1e83836Smrg using _Tj = typename _Nth_type<__j, _Types...>::type; 678b1e83836Smrg if constexpr (is_nothrow_copy_constructible_v<_Tj> 679b1e83836Smrg || !is_nothrow_move_constructible_v<_Tj>) 680b1e83836Smrg __variant::__emplace<__j>(*this, __rhs_mem); 681181254a7Smrg else 682b1e83836Smrg { 683b1e83836Smrg using _Variant = variant<_Types...>; 684b1e83836Smrg _Variant& __self = __variant_cast<_Types...>(*this); 685b1e83836Smrg __self = _Variant(in_place_index<__j>, __rhs_mem); 6868b6133e5Smrg } 6878b6133e5Smrg } 688181254a7Smrg }, __variant_cast<_Types...>(__rhs)); 6898b6133e5Smrg return *this; 6908b6133e5Smrg } 6918b6133e5Smrg 692a3e9eb18Smrg _Copy_assign_base(const _Copy_assign_base&) = default; 693a3e9eb18Smrg _Copy_assign_base(_Copy_assign_base&&) = default; 694a3e9eb18Smrg _Copy_assign_base& operator=(_Copy_assign_base&&) = default; 695a3e9eb18Smrg }; 696b17d1066Smrg 697a3e9eb18Smrg template<typename... _Types> 698a3e9eb18Smrg struct _Copy_assign_base<true, _Types...> : _Move_ctor_alias<_Types...> 699a3e9eb18Smrg { 700a3e9eb18Smrg using _Base = _Move_ctor_alias<_Types...>; 701a3e9eb18Smrg using _Base::_Base; 702a3e9eb18Smrg }; 703a3e9eb18Smrg 704a3e9eb18Smrg template<typename... _Types> 705a3e9eb18Smrg using _Copy_assign_alias = 706181254a7Smrg _Copy_assign_base<_Traits<_Types...>::_S_trivial_copy_assign, _Types...>; 707a3e9eb18Smrg 708a3e9eb18Smrg template<bool, typename... _Types> 709a3e9eb18Smrg struct _Move_assign_base : _Copy_assign_alias<_Types...> 710a3e9eb18Smrg { 711a3e9eb18Smrg using _Base = _Copy_assign_alias<_Types...>; 712a3e9eb18Smrg using _Base::_Base; 713a3e9eb18Smrg 714b1e83836Smrg _GLIBCXX20_CONSTEXPR 715a3e9eb18Smrg _Move_assign_base& 716a3e9eb18Smrg operator=(_Move_assign_base&& __rhs) 717a3e9eb18Smrg noexcept(_Traits<_Types...>::_S_nothrow_move_assign) 718b17d1066Smrg { 719fb8a8121Smrg __variant::__raw_idx_visit( 720fb8a8121Smrg [this](auto&& __rhs_mem, auto __rhs_index) mutable 721b17d1066Smrg { 722b1e83836Smrg constexpr size_t __j = __rhs_index; 723b1e83836Smrg if constexpr (__j != variant_npos) 724b17d1066Smrg { 725b1e83836Smrg if (this->_M_index == __j) 726b1e83836Smrg __variant::__get<__j>(*this) = std::move(__rhs_mem); 727181254a7Smrg else 728b1e83836Smrg { 729b1e83836Smrg using _Tj = typename _Nth_type<__j, _Types...>::type; 730b1e83836Smrg if constexpr (is_nothrow_move_constructible_v<_Tj>) 731b1e83836Smrg __variant::__emplace<__j>(*this, std::move(__rhs_mem)); 732b1e83836Smrg else 733b1e83836Smrg { 734b1e83836Smrg using _Variant = variant<_Types...>; 735b1e83836Smrg _Variant& __self = __variant_cast<_Types...>(*this); 736b1e83836Smrg __self.template emplace<__j>(std::move(__rhs_mem)); 737b1e83836Smrg } 738b1e83836Smrg } 739b17d1066Smrg } 740b17d1066Smrg else 741181254a7Smrg this->_M_reset(); 742181254a7Smrg }, __variant_cast<_Types...>(__rhs)); 743b17d1066Smrg return *this; 744b17d1066Smrg } 745b17d1066Smrg 746a3e9eb18Smrg _Move_assign_base(const _Move_assign_base&) = default; 747a3e9eb18Smrg _Move_assign_base(_Move_assign_base&&) = default; 748a3e9eb18Smrg _Move_assign_base& operator=(const _Move_assign_base&) = default; 749a3e9eb18Smrg }; 75014f5a3b0Smrg 751a3e9eb18Smrg template<typename... _Types> 752a3e9eb18Smrg struct _Move_assign_base<true, _Types...> : _Copy_assign_alias<_Types...> 75314f5a3b0Smrg { 754a3e9eb18Smrg using _Base = _Copy_assign_alias<_Types...>; 755a3e9eb18Smrg using _Base::_Base; 756a3e9eb18Smrg }; 757a3e9eb18Smrg 758a3e9eb18Smrg template<typename... _Types> 759a3e9eb18Smrg using _Move_assign_alias = 760181254a7Smrg _Move_assign_base<_Traits<_Types...>::_S_trivial_move_assign, _Types...>; 761a3e9eb18Smrg 762a3e9eb18Smrg template<typename... _Types> 763a3e9eb18Smrg struct _Variant_base : _Move_assign_alias<_Types...> 764a3e9eb18Smrg { 765a3e9eb18Smrg using _Base = _Move_assign_alias<_Types...>; 766a3e9eb18Smrg 767a3e9eb18Smrg constexpr 768b1e83836Smrg _Variant_base() noexcept(_Traits<_Types...>::_S_nothrow_default_ctor) 769a3e9eb18Smrg : _Variant_base(in_place_index<0>) { } 770a3e9eb18Smrg 771a3e9eb18Smrg template<size_t _Np, typename... _Args> 772a3e9eb18Smrg constexpr explicit 773a3e9eb18Smrg _Variant_base(in_place_index_t<_Np> __i, _Args&&... __args) 774a3e9eb18Smrg : _Base(__i, std::forward<_Args>(__args)...) 775a3e9eb18Smrg { } 776a3e9eb18Smrg 777a3e9eb18Smrg _Variant_base(const _Variant_base&) = default; 778a3e9eb18Smrg _Variant_base(_Variant_base&&) = default; 779a3e9eb18Smrg _Variant_base& operator=(const _Variant_base&) = default; 780a3e9eb18Smrg _Variant_base& operator=(_Variant_base&&) = default; 781b17d1066Smrg }; 782b17d1066Smrg 783b17d1066Smrg template<typename _Tp, typename... _Types> 784b1e83836Smrg inline constexpr bool __exactly_once 785b1e83836Smrg = std::__find_uniq_type_in_pack<_Tp, _Types...>() < sizeof...(_Types); 786b17d1066Smrg 787fb8a8121Smrg // Helper used to check for valid conversions that don't involve narrowing. 788fb8a8121Smrg template<typename _Ti> struct _Arr { _Ti _M_x[1]; }; 789b17d1066Smrg 790b1e83836Smrg // "Build an imaginary function FUN(Ti) for each alternative type Ti" 791b1e83836Smrg template<size_t _Ind, typename _Tp, typename _Ti, typename = void> 792fb8a8121Smrg struct _Build_FUN 793b17d1066Smrg { 794fb8a8121Smrg // This function means 'using _Build_FUN<I, T, Ti>::_S_fun;' is valid, 795fb8a8121Smrg // but only static functions will be considered in the call below. 796fb8a8121Smrg void _S_fun(); 797b17d1066Smrg }; 798b17d1066Smrg 799b1e83836Smrg // "... for which Ti x[] = {std::forward<T>(t)}; is well-formed." 800fb8a8121Smrg template<size_t _Ind, typename _Tp, typename _Ti> 801b1e83836Smrg struct _Build_FUN<_Ind, _Tp, _Ti, 802fb8a8121Smrg void_t<decltype(_Arr<_Ti>{{std::declval<_Tp>()}})>> 803b17d1066Smrg { 804fb8a8121Smrg // This is the FUN function for type _Ti, with index _Ind 805fb8a8121Smrg static integral_constant<size_t, _Ind> _S_fun(_Ti); 806b17d1066Smrg }; 807b17d1066Smrg 808fb8a8121Smrg template<typename _Tp, typename _Variant, 809fb8a8121Smrg typename = make_index_sequence<variant_size_v<_Variant>>> 810fb8a8121Smrg struct _Build_FUNs; 811fb8a8121Smrg 812fb8a8121Smrg template<typename _Tp, typename... _Ti, size_t... _Ind> 813fb8a8121Smrg struct _Build_FUNs<_Tp, variant<_Ti...>, index_sequence<_Ind...>> 814fb8a8121Smrg : _Build_FUN<_Ind, _Tp, _Ti>... 815fb8a8121Smrg { 816fb8a8121Smrg using _Build_FUN<_Ind, _Tp, _Ti>::_S_fun...; 817fb8a8121Smrg }; 818fb8a8121Smrg 819fb8a8121Smrg // The index j of the overload FUN(Tj) selected by overload resolution 820fb8a8121Smrg // for FUN(std::forward<_Tp>(t)) 821fb8a8121Smrg template<typename _Tp, typename _Variant> 822fb8a8121Smrg using _FUN_type 823fb8a8121Smrg = decltype(_Build_FUNs<_Tp, _Variant>::_S_fun(std::declval<_Tp>())); 824fb8a8121Smrg 825fb8a8121Smrg // The index selected for FUN(std::forward<T>(t)), or variant_npos if none. 826b17d1066Smrg template<typename _Tp, typename _Variant, typename = void> 827b17d1066Smrg struct __accepted_index 828fb8a8121Smrg : integral_constant<size_t, variant_npos> 829fb8a8121Smrg { }; 830b17d1066Smrg 831fb8a8121Smrg template<typename _Tp, typename _Variant> 832fb8a8121Smrg struct __accepted_index<_Tp, _Variant, void_t<_FUN_type<_Tp, _Variant>>> 833fb8a8121Smrg : _FUN_type<_Tp, _Variant> 834fb8a8121Smrg { }; 835b17d1066Smrg 836181254a7Smrg template <typename _Maybe_variant_cookie, typename _Variant> 837181254a7Smrg struct _Extra_visit_slot_needed 838181254a7Smrg { 839181254a7Smrg template <typename> struct _Variant_never_valueless; 840181254a7Smrg 841181254a7Smrg template <typename... _Types> 842181254a7Smrg struct _Variant_never_valueless<variant<_Types...>> 843fb8a8121Smrg : bool_constant<__variant::__never_valueless<_Types...>()> {}; 844181254a7Smrg 845181254a7Smrg static constexpr bool value = 846181254a7Smrg (is_same_v<_Maybe_variant_cookie, __variant_cookie> 847181254a7Smrg || is_same_v<_Maybe_variant_cookie, __variant_idx_cookie>) 848181254a7Smrg && !_Variant_never_valueless<__remove_cvref_t<_Variant>>::value; 849181254a7Smrg }; 850181254a7Smrg 851181254a7Smrg // Used for storing a multi-dimensional vtable. 852b17d1066Smrg template<typename _Tp, size_t... _Dimensions> 853181254a7Smrg struct _Multi_array; 854181254a7Smrg 855181254a7Smrg // Partial specialization with rank zero, stores a single _Tp element. 856181254a7Smrg template<typename _Tp> 857181254a7Smrg struct _Multi_array<_Tp> 858b17d1066Smrg { 859fb8a8121Smrg template<typename> 860fb8a8121Smrg struct __untag_result 861fb8a8121Smrg : false_type 862fb8a8121Smrg { using element_type = _Tp; }; 863fb8a8121Smrg 864fb8a8121Smrg template <typename... _Args> 865fb8a8121Smrg struct __untag_result<const void(*)(_Args...)> 866fb8a8121Smrg : false_type 867fb8a8121Smrg { using element_type = void(*)(_Args...); }; 868fb8a8121Smrg 869fb8a8121Smrg template <typename... _Args> 870fb8a8121Smrg struct __untag_result<__variant_cookie(*)(_Args...)> 871fb8a8121Smrg : false_type 872fb8a8121Smrg { using element_type = void(*)(_Args...); }; 873fb8a8121Smrg 874fb8a8121Smrg template <typename... _Args> 875fb8a8121Smrg struct __untag_result<__variant_idx_cookie(*)(_Args...)> 876fb8a8121Smrg : false_type 877fb8a8121Smrg { using element_type = void(*)(_Args...); }; 878fb8a8121Smrg 879fb8a8121Smrg template <typename _Res, typename... _Args> 880fb8a8121Smrg struct __untag_result<__deduce_visit_result<_Res>(*)(_Args...)> 881fb8a8121Smrg : true_type 882fb8a8121Smrg { using element_type = _Res(*)(_Args...); }; 883fb8a8121Smrg 884fb8a8121Smrg using __result_is_deduced = __untag_result<_Tp>; 885fb8a8121Smrg 886fb8a8121Smrg constexpr const typename __untag_result<_Tp>::element_type& 887b17d1066Smrg _M_access() const 888b17d1066Smrg { return _M_data; } 889b17d1066Smrg 890fb8a8121Smrg typename __untag_result<_Tp>::element_type _M_data; 891b17d1066Smrg }; 892b17d1066Smrg 893181254a7Smrg // Partial specialization with rank >= 1. 894181254a7Smrg template<typename _Ret, 895181254a7Smrg typename _Visitor, 896181254a7Smrg typename... _Variants, 897181254a7Smrg size_t __first, size_t... __rest> 898181254a7Smrg struct _Multi_array<_Ret(*)(_Visitor, _Variants...), __first, __rest...> 899b17d1066Smrg { 900181254a7Smrg static constexpr size_t __index = 901181254a7Smrg sizeof...(_Variants) - sizeof...(__rest) - 1; 902181254a7Smrg 903181254a7Smrg using _Variant = typename _Nth_type<__index, _Variants...>::type; 904181254a7Smrg 905181254a7Smrg static constexpr int __do_cookie = 906181254a7Smrg _Extra_visit_slot_needed<_Ret, _Variant>::value ? 1 : 0; 907181254a7Smrg 908181254a7Smrg using _Tp = _Ret(*)(_Visitor, _Variants...); 909181254a7Smrg 910b17d1066Smrg template<typename... _Args> 911fb8a8121Smrg constexpr decltype(auto) 912b17d1066Smrg _M_access(size_t __first_index, _Args... __rest_indices) const 913181254a7Smrg { 914181254a7Smrg return _M_arr[__first_index + __do_cookie] 915181254a7Smrg ._M_access(__rest_indices...); 916181254a7Smrg } 917b17d1066Smrg 918181254a7Smrg _Multi_array<_Tp, __rest...> _M_arr[__first + __do_cookie]; 919b17d1066Smrg }; 920b17d1066Smrg 921b17d1066Smrg // Creates a multi-dimensional vtable recursively. 922b17d1066Smrg // 923b17d1066Smrg // For example, 924b17d1066Smrg // visit([](auto, auto){}, 925b17d1066Smrg // variant<int, char>(), // typedef'ed as V1 926b17d1066Smrg // variant<float, double, long double>()) // typedef'ed as V2 927b17d1066Smrg // will trigger instantiations of: 928fb8a8121Smrg // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 2, 3>, 929b17d1066Smrg // tuple<V1&&, V2&&>, std::index_sequence<>> 930fb8a8121Smrg // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 3>, 931b17d1066Smrg // tuple<V1&&, V2&&>, std::index_sequence<0>> 932fb8a8121Smrg // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>, 933b17d1066Smrg // tuple<V1&&, V2&&>, std::index_sequence<0, 0>> 934fb8a8121Smrg // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>, 935b17d1066Smrg // tuple<V1&&, V2&&>, std::index_sequence<0, 1>> 936fb8a8121Smrg // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>, 937b17d1066Smrg // tuple<V1&&, V2&&>, std::index_sequence<0, 2>> 938fb8a8121Smrg // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 3>, 939b17d1066Smrg // tuple<V1&&, V2&&>, std::index_sequence<1>> 940fb8a8121Smrg // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>, 941b17d1066Smrg // tuple<V1&&, V2&&>, std::index_sequence<1, 0>> 942fb8a8121Smrg // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>, 943b17d1066Smrg // tuple<V1&&, V2&&>, std::index_sequence<1, 1>> 944fb8a8121Smrg // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>, 945b17d1066Smrg // tuple<V1&&, V2&&>, std::index_sequence<1, 2>> 946b17d1066Smrg // The returned multi-dimensional vtable can be fast accessed by the visitor 947b17d1066Smrg // using index calculation. 948fb8a8121Smrg template<typename _Array_type, typename _Index_seq> 949b17d1066Smrg struct __gen_vtable_impl; 950b17d1066Smrg 951181254a7Smrg // Defines the _S_apply() member that returns a _Multi_array populated 952181254a7Smrg // with function pointers that perform the visitation expressions e(m) 953181254a7Smrg // for each valid pack of indexes into the variant types _Variants. 954181254a7Smrg // 955181254a7Smrg // This partial specialization builds up the index sequences by recursively 956181254a7Smrg // calling _S_apply() on the next specialization of __gen_vtable_impl. 957181254a7Smrg // The base case of the recursion defines the actual function pointers. 958fb8a8121Smrg template<typename _Result_type, typename _Visitor, size_t... __dimensions, 959b17d1066Smrg typename... _Variants, size_t... __indices> 960b17d1066Smrg struct __gen_vtable_impl< 961b17d1066Smrg _Multi_array<_Result_type (*)(_Visitor, _Variants...), __dimensions...>, 962fb8a8121Smrg std::index_sequence<__indices...>> 963b17d1066Smrg { 964b17d1066Smrg using _Next = 965b17d1066Smrg remove_reference_t<typename _Nth_type<sizeof...(__indices), 966b17d1066Smrg _Variants...>::type>; 967b17d1066Smrg using _Array_type = 968b17d1066Smrg _Multi_array<_Result_type (*)(_Visitor, _Variants...), 969b17d1066Smrg __dimensions...>; 970b17d1066Smrg 971b17d1066Smrg static constexpr _Array_type 972b17d1066Smrg _S_apply() 973b17d1066Smrg { 974b17d1066Smrg _Array_type __vtable{}; 975b17d1066Smrg _S_apply_all_alts( 976b17d1066Smrg __vtable, make_index_sequence<variant_size_v<_Next>>()); 977b17d1066Smrg return __vtable; 978b17d1066Smrg } 979b17d1066Smrg 980b17d1066Smrg template<size_t... __var_indices> 981b17d1066Smrg static constexpr void 982b17d1066Smrg _S_apply_all_alts(_Array_type& __vtable, 983b17d1066Smrg std::index_sequence<__var_indices...>) 984b17d1066Smrg { 985181254a7Smrg if constexpr (_Extra_visit_slot_needed<_Result_type, _Next>::value) 986181254a7Smrg (_S_apply_single_alt<true, __var_indices>( 987181254a7Smrg __vtable._M_arr[__var_indices + 1], 988181254a7Smrg &(__vtable._M_arr[0])), ...); 989181254a7Smrg else 990181254a7Smrg (_S_apply_single_alt<false, __var_indices>( 991b17d1066Smrg __vtable._M_arr[__var_indices]), ...); 992b17d1066Smrg } 993b17d1066Smrg 994181254a7Smrg template<bool __do_cookie, size_t __index, typename _Tp> 995b17d1066Smrg static constexpr void 996181254a7Smrg _S_apply_single_alt(_Tp& __element, _Tp* __cookie_element = nullptr) 997b17d1066Smrg { 998181254a7Smrg if constexpr (__do_cookie) 999181254a7Smrg { 1000b17d1066Smrg __element = __gen_vtable_impl< 1001181254a7Smrg _Tp, 1002181254a7Smrg std::index_sequence<__indices..., __index>>::_S_apply(); 1003181254a7Smrg *__cookie_element = __gen_vtable_impl< 1004181254a7Smrg _Tp, 1005181254a7Smrg std::index_sequence<__indices..., variant_npos>>::_S_apply(); 1006181254a7Smrg } 1007181254a7Smrg else 1008181254a7Smrg { 1009b1e83836Smrg auto __tmp_element = __gen_vtable_impl< 1010fb8a8121Smrg remove_reference_t<decltype(__element)>, 1011b17d1066Smrg std::index_sequence<__indices..., __index>>::_S_apply(); 1012b1e83836Smrg static_assert(is_same_v<_Tp, decltype(__tmp_element)>, 1013b1e83836Smrg "std::visit requires the visitor to have the same " 1014b1e83836Smrg "return type for all alternatives of a variant"); 1015b1e83836Smrg __element = __tmp_element; 1016b17d1066Smrg } 1017181254a7Smrg } 1018b17d1066Smrg }; 1019b17d1066Smrg 1020181254a7Smrg // This partial specialization is the base case for the recursion. 1021181254a7Smrg // It populates a _Multi_array element with the address of a function 1022181254a7Smrg // that invokes the visitor with the alternatives specified by __indices. 1023fb8a8121Smrg template<typename _Result_type, typename _Visitor, typename... _Variants, 1024b17d1066Smrg size_t... __indices> 1025b17d1066Smrg struct __gen_vtable_impl< 1026b17d1066Smrg _Multi_array<_Result_type (*)(_Visitor, _Variants...)>, 1027fb8a8121Smrg std::index_sequence<__indices...>> 1028b17d1066Smrg { 1029b17d1066Smrg using _Array_type = 1030181254a7Smrg _Multi_array<_Result_type (*)(_Visitor, _Variants...)>; 1031181254a7Smrg 1032181254a7Smrg template<size_t __index, typename _Variant> 1033181254a7Smrg static constexpr decltype(auto) 1034181254a7Smrg __element_by_index_or_cookie(_Variant&& __var) noexcept 1035181254a7Smrg { 1036181254a7Smrg if constexpr (__index != variant_npos) 1037181254a7Smrg return __variant::__get<__index>(std::forward<_Variant>(__var)); 1038181254a7Smrg else 1039181254a7Smrg return __variant_cookie{}; 1040181254a7Smrg } 1041181254a7Smrg 1042181254a7Smrg static constexpr decltype(auto) 1043fb8a8121Smrg __visit_invoke(_Visitor&& __visitor, _Variants... __vars) 1044181254a7Smrg { 1045181254a7Smrg if constexpr (is_same_v<_Result_type, __variant_idx_cookie>) 1046fb8a8121Smrg // For raw visitation using indices, pass the indices to the visitor 1047fb8a8121Smrg // and discard the return value: 1048fb8a8121Smrg std::__invoke(std::forward<_Visitor>(__visitor), 1049181254a7Smrg __element_by_index_or_cookie<__indices>( 1050181254a7Smrg std::forward<_Variants>(__vars))..., 1051181254a7Smrg integral_constant<size_t, __indices>()...); 1052fb8a8121Smrg else if constexpr (is_same_v<_Result_type, __variant_cookie>) 1053fb8a8121Smrg // For raw visitation without indices, and discard the return value: 1054fb8a8121Smrg std::__invoke(std::forward<_Visitor>(__visitor), 1055181254a7Smrg __element_by_index_or_cookie<__indices>( 1056181254a7Smrg std::forward<_Variants>(__vars))...); 1057fb8a8121Smrg else if constexpr (_Array_type::__result_is_deduced::value) 1058fb8a8121Smrg // For the usual std::visit case deduce the return value: 1059181254a7Smrg return std::__invoke(std::forward<_Visitor>(__visitor), 1060181254a7Smrg __element_by_index_or_cookie<__indices>( 1061181254a7Smrg std::forward<_Variants>(__vars))...); 1062fb8a8121Smrg else // for std::visit<R> use INVOKE<R> 1063fb8a8121Smrg return std::__invoke_r<_Result_type>( 1064fb8a8121Smrg std::forward<_Visitor>(__visitor), 1065fb8a8121Smrg __variant::__get<__indices>(std::forward<_Variants>(__vars))...); 1066b17d1066Smrg } 1067b17d1066Smrg 1068b17d1066Smrg static constexpr auto 1069b17d1066Smrg _S_apply() 1070b1e83836Smrg { 1071b1e83836Smrg if constexpr (_Array_type::__result_is_deduced::value) 1072b1e83836Smrg { 1073b1e83836Smrg constexpr bool __visit_ret_type_mismatch = 1074b1e83836Smrg !is_same_v<typename _Result_type::type, 1075b1e83836Smrg decltype(__visit_invoke(std::declval<_Visitor>(), 1076b1e83836Smrg std::declval<_Variants>()...))>; 1077b1e83836Smrg if constexpr (__visit_ret_type_mismatch) 1078b1e83836Smrg { 1079b1e83836Smrg struct __cannot_match {}; 1080b1e83836Smrg return __cannot_match{}; 1081b1e83836Smrg } 1082b1e83836Smrg else 1083b1e83836Smrg return _Array_type{&__visit_invoke}; 1084b1e83836Smrg } 1085b1e83836Smrg else 1086b1e83836Smrg return _Array_type{&__visit_invoke}; 1087b1e83836Smrg } 1088b17d1066Smrg }; 1089b17d1066Smrg 1090fb8a8121Smrg template<typename _Result_type, typename _Visitor, typename... _Variants> 1091b17d1066Smrg struct __gen_vtable 1092b17d1066Smrg { 1093b17d1066Smrg using _Array_type = 1094181254a7Smrg _Multi_array<_Result_type (*)(_Visitor, _Variants...), 1095b17d1066Smrg variant_size_v<remove_reference_t<_Variants>>...>; 1096b17d1066Smrg 1097181254a7Smrg static constexpr _Array_type _S_vtable 1098fb8a8121Smrg = __gen_vtable_impl<_Array_type, std::index_sequence<>>::_S_apply(); 1099b17d1066Smrg }; 1100b17d1066Smrg 1101b17d1066Smrg template<size_t _Np, typename _Tp> 1102b17d1066Smrg struct _Base_dedup : public _Tp { }; 1103b17d1066Smrg 1104b17d1066Smrg template<typename _Variant, typename __indices> 1105b17d1066Smrg struct _Variant_hash_base; 1106b17d1066Smrg 1107b17d1066Smrg template<typename... _Types, size_t... __indices> 1108b17d1066Smrg struct _Variant_hash_base<variant<_Types...>, 1109b17d1066Smrg std::index_sequence<__indices...>> 1110b17d1066Smrg : _Base_dedup<__indices, __poison_hash<remove_const_t<_Types>>>... { }; 1111b17d1066Smrg 1112b1e83836Smrg // Equivalent to decltype(get<_Np>(as-variant(declval<_Variant>()))) 1113b1e83836Smrg template<size_t _Np, typename _Variant, 1114b1e83836Smrg typename _AsV = decltype(__variant::__as(std::declval<_Variant>())), 1115b1e83836Smrg typename _Tp = variant_alternative_t<_Np, remove_reference_t<_AsV>>> 1116b1e83836Smrg using __get_t 1117b1e83836Smrg = __conditional_t<is_lvalue_reference_v<_Variant>, _Tp&, _Tp&&>; 1118a448f87cSmrg 1119a448f87cSmrg // Return type of std::visit. 1120a448f87cSmrg template<typename _Visitor, typename... _Variants> 1121a448f87cSmrg using __visit_result_t 1122a448f87cSmrg = invoke_result_t<_Visitor, __get_t<0, _Variants>...>; 1123a448f87cSmrg 1124b1e83836Smrg template<typename _Tp, typename... _Types> 1125b1e83836Smrg constexpr inline bool __same_types = (is_same_v<_Tp, _Types> && ...); 1126b1e83836Smrg 1127b1e83836Smrg template <typename _Visitor, typename _Variant, size_t... _Idxs> 1128b1e83836Smrg constexpr bool __check_visitor_results(std::index_sequence<_Idxs...>) 1129b1e83836Smrg { 1130b1e83836Smrg return __same_types< 1131b1e83836Smrg invoke_result_t<_Visitor, __get_t<_Idxs, _Variant>>... 1132b1e83836Smrg >; 1133b1e83836Smrg } 1134b1e83836Smrg 1135b17d1066Smrg} // namespace __variant 1136b17d1066Smrg} // namespace __detail 1137b17d1066Smrg 1138b17d1066Smrg template<typename _Tp, typename... _Types> 1139a3e9eb18Smrg constexpr bool 1140a3e9eb18Smrg holds_alternative(const variant<_Types...>& __v) noexcept 1141b17d1066Smrg { 1142b17d1066Smrg static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, 1143fb8a8121Smrg "T must occur exactly once in alternatives"); 1144b1e83836Smrg return __v.index() == std::__find_uniq_type_in_pack<_Tp, _Types...>(); 1145b17d1066Smrg } 1146b17d1066Smrg 1147b17d1066Smrg template<typename _Tp, typename... _Types> 1148b1e83836Smrg constexpr _Tp& 1149b1e83836Smrg get(variant<_Types...>& __v) 1150b17d1066Smrg { 1151b17d1066Smrg static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, 1152fb8a8121Smrg "T must occur exactly once in alternatives"); 1153b1e83836Smrg constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>(); 1154b1e83836Smrg return std::get<__n>(__v); 1155b17d1066Smrg } 1156b17d1066Smrg 1157b17d1066Smrg template<typename _Tp, typename... _Types> 1158b1e83836Smrg constexpr _Tp&& 1159b1e83836Smrg get(variant<_Types...>&& __v) 1160b17d1066Smrg { 1161b17d1066Smrg static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, 1162fb8a8121Smrg "T must occur exactly once in alternatives"); 1163b1e83836Smrg constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>(); 1164b1e83836Smrg return std::get<__n>(std::move(__v)); 1165b17d1066Smrg } 1166b17d1066Smrg 1167b17d1066Smrg template<typename _Tp, typename... _Types> 1168b1e83836Smrg constexpr const _Tp& 1169b1e83836Smrg get(const variant<_Types...>& __v) 1170b17d1066Smrg { 1171b17d1066Smrg static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, 1172fb8a8121Smrg "T must occur exactly once in alternatives"); 1173b1e83836Smrg constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>(); 1174b1e83836Smrg return std::get<__n>(__v); 1175b17d1066Smrg } 1176b17d1066Smrg 1177b17d1066Smrg template<typename _Tp, typename... _Types> 1178b1e83836Smrg constexpr const _Tp&& 1179b1e83836Smrg get(const variant<_Types...>&& __v) 1180b17d1066Smrg { 1181b17d1066Smrg static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, 1182fb8a8121Smrg "T must occur exactly once in alternatives"); 1183b1e83836Smrg constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>(); 1184b1e83836Smrg return std::get<__n>(std::move(__v)); 1185b17d1066Smrg } 1186b17d1066Smrg 1187b17d1066Smrg template<size_t _Np, typename... _Types> 1188a3e9eb18Smrg constexpr add_pointer_t<variant_alternative_t<_Np, variant<_Types...>>> 1189b17d1066Smrg get_if(variant<_Types...>* __ptr) noexcept 1190b17d1066Smrg { 1191b17d1066Smrg using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>; 1192b17d1066Smrg static_assert(_Np < sizeof...(_Types), 1193fb8a8121Smrg "The index must be in [0, number of alternatives)"); 1194fb8a8121Smrg static_assert(!is_void_v<_Alternative_type>, "_Tp must not be void"); 1195b17d1066Smrg if (__ptr && __ptr->index() == _Np) 1196181254a7Smrg return std::addressof(__detail::__variant::__get<_Np>(*__ptr)); 1197b17d1066Smrg return nullptr; 1198b17d1066Smrg } 1199b17d1066Smrg 1200b17d1066Smrg template<size_t _Np, typename... _Types> 1201a3e9eb18Smrg constexpr 1202b17d1066Smrg add_pointer_t<const variant_alternative_t<_Np, variant<_Types...>>> 1203b17d1066Smrg get_if(const variant<_Types...>* __ptr) noexcept 1204b17d1066Smrg { 1205b17d1066Smrg using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>; 1206b17d1066Smrg static_assert(_Np < sizeof...(_Types), 1207fb8a8121Smrg "The index must be in [0, number of alternatives)"); 1208fb8a8121Smrg static_assert(!is_void_v<_Alternative_type>, "_Tp must not be void"); 1209b17d1066Smrg if (__ptr && __ptr->index() == _Np) 1210181254a7Smrg return std::addressof(__detail::__variant::__get<_Np>(*__ptr)); 1211b17d1066Smrg return nullptr; 1212b17d1066Smrg } 1213b17d1066Smrg 1214b17d1066Smrg template<typename _Tp, typename... _Types> 1215a3e9eb18Smrg constexpr add_pointer_t<_Tp> 1216b17d1066Smrg get_if(variant<_Types...>* __ptr) noexcept 1217b17d1066Smrg { 1218b17d1066Smrg static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, 1219fb8a8121Smrg "T must occur exactly once in alternatives"); 1220fb8a8121Smrg static_assert(!is_void_v<_Tp>, "_Tp must not be void"); 1221b1e83836Smrg constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>(); 1222b1e83836Smrg return std::get_if<__n>(__ptr); 1223b17d1066Smrg } 1224b17d1066Smrg 1225b17d1066Smrg template<typename _Tp, typename... _Types> 1226a3e9eb18Smrg constexpr add_pointer_t<const _Tp> 1227181254a7Smrg get_if(const variant<_Types...>* __ptr) noexcept 1228b17d1066Smrg { 1229b17d1066Smrg static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, 1230fb8a8121Smrg "T must occur exactly once in alternatives"); 1231fb8a8121Smrg static_assert(!is_void_v<_Tp>, "_Tp must not be void"); 1232b1e83836Smrg constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>(); 1233b1e83836Smrg return std::get_if<__n>(__ptr); 1234b17d1066Smrg } 1235b17d1066Smrg 1236b17d1066Smrg struct monostate { }; 1237b17d1066Smrg 1238b17d1066Smrg#define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \ 1239b17d1066Smrg template<typename... _Types> \ 1240b17d1066Smrg constexpr bool operator __OP(const variant<_Types...>& __lhs, \ 1241b17d1066Smrg const variant<_Types...>& __rhs) \ 1242b17d1066Smrg { \ 1243181254a7Smrg bool __ret = true; \ 1244fb8a8121Smrg __detail::__variant::__raw_idx_visit( \ 1245fb8a8121Smrg [&__ret, &__lhs] (auto&& __rhs_mem, auto __rhs_index) mutable \ 1246181254a7Smrg { \ 1247181254a7Smrg if constexpr (__rhs_index != variant_npos) \ 1248181254a7Smrg { \ 1249181254a7Smrg if (__lhs.index() == __rhs_index) \ 1250181254a7Smrg { \ 1251181254a7Smrg auto& __this_mem = std::get<__rhs_index>(__lhs); \ 1252181254a7Smrg __ret = __this_mem __OP __rhs_mem; \ 1253181254a7Smrg } \ 1254181254a7Smrg else \ 1255181254a7Smrg __ret = (__lhs.index() + 1) __OP (__rhs_index + 1); \ 1256181254a7Smrg } \ 1257181254a7Smrg else \ 1258181254a7Smrg __ret = (__lhs.index() + 1) __OP (__rhs_index + 1); \ 1259181254a7Smrg }, __rhs); \ 1260181254a7Smrg return __ret; \ 1261fb8a8121Smrg } 1262b17d1066Smrg 1263b17d1066Smrg _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less) 1264b17d1066Smrg _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal) 1265b17d1066Smrg _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal) 1266b17d1066Smrg _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal) 1267b17d1066Smrg _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal) 1268b17d1066Smrg _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater) 1269b17d1066Smrg 1270b17d1066Smrg#undef _VARIANT_RELATION_FUNCTION_TEMPLATE 1271b17d1066Smrg 1272fb8a8121Smrg constexpr bool operator==(monostate, monostate) noexcept { return true; } 1273fb8a8121Smrg 1274fb8a8121Smrg#ifdef __cpp_lib_three_way_comparison 1275fb8a8121Smrg template<typename... _Types> 1276fb8a8121Smrg requires (three_way_comparable<_Types> && ...) 1277fb8a8121Smrg constexpr 1278fb8a8121Smrg common_comparison_category_t<compare_three_way_result_t<_Types>...> 1279fb8a8121Smrg operator<=>(const variant<_Types...>& __v, const variant<_Types...>& __w) 1280fb8a8121Smrg { 1281fb8a8121Smrg common_comparison_category_t<compare_three_way_result_t<_Types>...> __ret 1282fb8a8121Smrg = strong_ordering::equal; 1283fb8a8121Smrg 1284fb8a8121Smrg __detail::__variant::__raw_idx_visit( 1285fb8a8121Smrg [&__ret, &__v] (auto&& __w_mem, auto __w_index) mutable 1286fb8a8121Smrg { 1287fb8a8121Smrg if constexpr (__w_index != variant_npos) 1288fb8a8121Smrg { 1289fb8a8121Smrg if (__v.index() == __w_index) 1290fb8a8121Smrg { 1291fb8a8121Smrg auto& __this_mem = std::get<__w_index>(__v); 1292fb8a8121Smrg __ret = __this_mem <=> __w_mem; 1293fb8a8121Smrg return; 1294fb8a8121Smrg } 1295fb8a8121Smrg } 1296fb8a8121Smrg __ret = (__v.index() + 1) <=> (__w_index + 1); 1297fb8a8121Smrg }, __w); 1298fb8a8121Smrg return __ret; 1299fb8a8121Smrg } 1300fb8a8121Smrg 1301fb8a8121Smrg constexpr strong_ordering 1302fb8a8121Smrg operator<=>(monostate, monostate) noexcept { return strong_ordering::equal; } 1303fb8a8121Smrg#else 1304fb8a8121Smrg constexpr bool operator!=(monostate, monostate) noexcept { return false; } 1305fb8a8121Smrg constexpr bool operator<(monostate, monostate) noexcept { return false; } 1306fb8a8121Smrg constexpr bool operator>(monostate, monostate) noexcept { return false; } 1307fb8a8121Smrg constexpr bool operator<=(monostate, monostate) noexcept { return true; } 1308fb8a8121Smrg constexpr bool operator>=(monostate, monostate) noexcept { return true; } 1309fb8a8121Smrg#endif 1310fb8a8121Smrg 1311b17d1066Smrg template<typename _Visitor, typename... _Variants> 1312a448f87cSmrg constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...> 1313a448f87cSmrg visit(_Visitor&&, _Variants&&...); 1314b17d1066Smrg 1315b17d1066Smrg template<typename... _Types> 1316b1e83836Smrg _GLIBCXX20_CONSTEXPR 1317b17d1066Smrg inline enable_if_t<(is_move_constructible_v<_Types> && ...) 1318b17d1066Smrg && (is_swappable_v<_Types> && ...)> 1319b17d1066Smrg swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs) 1320b17d1066Smrg noexcept(noexcept(__lhs.swap(__rhs))) 1321b17d1066Smrg { __lhs.swap(__rhs); } 1322b17d1066Smrg 1323b17d1066Smrg template<typename... _Types> 1324b17d1066Smrg enable_if_t<!((is_move_constructible_v<_Types> && ...) 1325b17d1066Smrg && (is_swappable_v<_Types> && ...))> 1326b17d1066Smrg swap(variant<_Types...>&, variant<_Types...>&) = delete; 1327b17d1066Smrg 1328b17d1066Smrg class bad_variant_access : public exception 1329b17d1066Smrg { 1330b17d1066Smrg public: 1331fb8a8121Smrg bad_variant_access() noexcept { } 1332fb8a8121Smrg 1333b17d1066Smrg const char* what() const noexcept override 1334b17d1066Smrg { return _M_reason; } 1335b17d1066Smrg 1336b17d1066Smrg private: 1337fb8a8121Smrg bad_variant_access(const char* __reason) noexcept : _M_reason(__reason) { } 1338b17d1066Smrg 1339fb8a8121Smrg // Must point to a string with static storage duration: 1340fb8a8121Smrg const char* _M_reason = "bad variant access"; 1341b17d1066Smrg 1342b17d1066Smrg friend void __throw_bad_variant_access(const char* __what); 1343b17d1066Smrg }; 1344b17d1066Smrg 1345fb8a8121Smrg // Must only be called with a string literal 1346b17d1066Smrg inline void 1347b17d1066Smrg __throw_bad_variant_access(const char* __what) 1348b17d1066Smrg { _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__what)); } 1349b17d1066Smrg 1350fb8a8121Smrg inline void 1351fb8a8121Smrg __throw_bad_variant_access(bool __valueless) 1352fb8a8121Smrg { 1353fb8a8121Smrg if (__valueless) [[__unlikely__]] 1354fb8a8121Smrg __throw_bad_variant_access("std::get: variant is valueless"); 1355fb8a8121Smrg else 1356fb8a8121Smrg __throw_bad_variant_access("std::get: wrong index for variant"); 1357fb8a8121Smrg } 1358fb8a8121Smrg 1359b17d1066Smrg template<typename... _Types> 1360b17d1066Smrg class variant 1361b17d1066Smrg : private __detail::__variant::_Variant_base<_Types...>, 1362b17d1066Smrg private _Enable_default_constructor< 1363a3e9eb18Smrg __detail::__variant::_Traits<_Types...>::_S_default_ctor, 1364a3e9eb18Smrg variant<_Types...>>, 1365b17d1066Smrg private _Enable_copy_move< 1366a3e9eb18Smrg __detail::__variant::_Traits<_Types...>::_S_copy_ctor, 1367a3e9eb18Smrg __detail::__variant::_Traits<_Types...>::_S_copy_assign, 1368a3e9eb18Smrg __detail::__variant::_Traits<_Types...>::_S_move_ctor, 1369a3e9eb18Smrg __detail::__variant::_Traits<_Types...>::_S_move_assign, 1370b17d1066Smrg variant<_Types...>> 1371b17d1066Smrg { 1372b17d1066Smrg private: 1373181254a7Smrg template <typename... _UTypes, typename _Tp> 1374b1e83836Smrg friend _GLIBCXX20_CONSTEXPR decltype(auto) 1375b1e83836Smrg __variant_cast(_Tp&&); 1376181254a7Smrg 1377b17d1066Smrg static_assert(sizeof...(_Types) > 0, 1378b17d1066Smrg "variant must have at least one alternative"); 1379b17d1066Smrg static_assert(!(std::is_reference_v<_Types> || ...), 1380b17d1066Smrg "variant must have no reference alternative"); 1381b17d1066Smrg static_assert(!(std::is_void_v<_Types> || ...), 1382b17d1066Smrg "variant must have no void alternative"); 1383b17d1066Smrg 1384b17d1066Smrg using _Base = __detail::__variant::_Variant_base<_Types...>; 1385b17d1066Smrg using _Default_ctor_enabler = 1386b17d1066Smrg _Enable_default_constructor< 1387a3e9eb18Smrg __detail::__variant::_Traits<_Types...>::_S_default_ctor, 1388a3e9eb18Smrg variant<_Types...>>; 1389b17d1066Smrg 1390b17d1066Smrg template<typename _Tp> 1391181254a7Smrg static constexpr bool __not_self 1392181254a7Smrg = !is_same_v<__remove_cvref_t<_Tp>, variant>; 1393181254a7Smrg 1394181254a7Smrg template<typename _Tp> 1395b17d1066Smrg static constexpr bool 1396b17d1066Smrg __exactly_once = __detail::__variant::__exactly_once<_Tp, _Types...>; 1397b17d1066Smrg 1398b17d1066Smrg template<typename _Tp> 1399fb8a8121Smrg static constexpr size_t __accepted_index 1400fb8a8121Smrg = __detail::__variant::__accepted_index<_Tp, variant>::value; 1401b17d1066Smrg 1402181254a7Smrg template<size_t _Np, typename = enable_if_t<(_Np < sizeof...(_Types))>> 1403b1e83836Smrg using __to_type = typename _Nth_type<_Np, _Types...>::type; 1404b17d1066Smrg 1405181254a7Smrg template<typename _Tp, typename = enable_if_t<__not_self<_Tp>>> 1406b17d1066Smrg using __accepted_type = __to_type<__accepted_index<_Tp>>; 1407b17d1066Smrg 1408b17d1066Smrg template<typename _Tp> 1409b1e83836Smrg static constexpr size_t __index_of 1410b1e83836Smrg = std::__find_uniq_type_in_pack<_Tp, _Types...>(); 1411b17d1066Smrg 1412a3e9eb18Smrg using _Traits = __detail::__variant::_Traits<_Types...>; 1413a3e9eb18Smrg 1414a3e9eb18Smrg template<typename _Tp> 1415a3e9eb18Smrg struct __is_in_place_tag : false_type { }; 1416a3e9eb18Smrg template<typename _Tp> 1417a3e9eb18Smrg struct __is_in_place_tag<in_place_type_t<_Tp>> : true_type { }; 1418a3e9eb18Smrg template<size_t _Np> 1419a3e9eb18Smrg struct __is_in_place_tag<in_place_index_t<_Np>> : true_type { }; 1420a3e9eb18Smrg 1421a3e9eb18Smrg template<typename _Tp> 1422a3e9eb18Smrg static constexpr bool __not_in_place_tag 1423181254a7Smrg = !__is_in_place_tag<__remove_cvref_t<_Tp>>::value; 1424a3e9eb18Smrg 1425b17d1066Smrg public: 1426a3e9eb18Smrg variant() = default; 1427a3e9eb18Smrg variant(const variant& __rhs) = default; 1428a3e9eb18Smrg variant(variant&&) = default; 1429a3e9eb18Smrg variant& operator=(const variant&) = default; 1430a3e9eb18Smrg variant& operator=(variant&&) = default; 1431b1e83836Smrg _GLIBCXX20_CONSTEXPR ~variant() = default; 1432b17d1066Smrg 1433b17d1066Smrg template<typename _Tp, 1434181254a7Smrg typename = enable_if_t<sizeof...(_Types) != 0>, 1435a3e9eb18Smrg typename = enable_if_t<__not_in_place_tag<_Tp>>, 1436181254a7Smrg typename _Tj = __accepted_type<_Tp&&>, 1437181254a7Smrg typename = enable_if_t<__exactly_once<_Tj> 1438181254a7Smrg && is_constructible_v<_Tj, _Tp>>> 1439b17d1066Smrg constexpr 1440b17d1066Smrg variant(_Tp&& __t) 1441181254a7Smrg noexcept(is_nothrow_constructible_v<_Tj, _Tp>) 1442fb8a8121Smrg : variant(in_place_index<__accepted_index<_Tp>>, 1443a3e9eb18Smrg std::forward<_Tp>(__t)) 1444181254a7Smrg { } 1445b17d1066Smrg 1446b17d1066Smrg template<typename _Tp, typename... _Args, 1447b17d1066Smrg typename = enable_if_t<__exactly_once<_Tp> 1448181254a7Smrg && is_constructible_v<_Tp, _Args...>>> 1449b17d1066Smrg constexpr explicit 1450b17d1066Smrg variant(in_place_type_t<_Tp>, _Args&&... __args) 1451a3e9eb18Smrg : variant(in_place_index<__index_of<_Tp>>, 1452a3e9eb18Smrg std::forward<_Args>(__args)...) 1453181254a7Smrg { } 1454b17d1066Smrg 1455b17d1066Smrg template<typename _Tp, typename _Up, typename... _Args, 1456b17d1066Smrg typename = enable_if_t<__exactly_once<_Tp> 1457181254a7Smrg && is_constructible_v<_Tp, 1458181254a7Smrg initializer_list<_Up>&, _Args...>>> 1459b17d1066Smrg constexpr explicit 1460b17d1066Smrg variant(in_place_type_t<_Tp>, initializer_list<_Up> __il, 1461b17d1066Smrg _Args&&... __args) 1462b17d1066Smrg : variant(in_place_index<__index_of<_Tp>>, __il, 1463b17d1066Smrg std::forward<_Args>(__args)...) 1464181254a7Smrg { } 1465b17d1066Smrg 1466b17d1066Smrg template<size_t _Np, typename... _Args, 1467181254a7Smrg typename _Tp = __to_type<_Np>, 1468181254a7Smrg typename = enable_if_t<is_constructible_v<_Tp, _Args...>>> 1469b17d1066Smrg constexpr explicit 1470b17d1066Smrg variant(in_place_index_t<_Np>, _Args&&... __args) 1471b17d1066Smrg : _Base(in_place_index<_Np>, std::forward<_Args>(__args)...), 1472b17d1066Smrg _Default_ctor_enabler(_Enable_default_constructor_tag{}) 1473181254a7Smrg { } 1474b17d1066Smrg 1475b17d1066Smrg template<size_t _Np, typename _Up, typename... _Args, 1476181254a7Smrg typename _Tp = __to_type<_Np>, 1477181254a7Smrg typename = enable_if_t<is_constructible_v<_Tp, 1478181254a7Smrg initializer_list<_Up>&, 1479181254a7Smrg _Args...>>> 1480b17d1066Smrg constexpr explicit 1481b17d1066Smrg variant(in_place_index_t<_Np>, initializer_list<_Up> __il, 1482b17d1066Smrg _Args&&... __args) 1483b17d1066Smrg : _Base(in_place_index<_Np>, __il, std::forward<_Args>(__args)...), 1484b17d1066Smrg _Default_ctor_enabler(_Enable_default_constructor_tag{}) 1485181254a7Smrg { } 1486b17d1066Smrg 1487b17d1066Smrg template<typename _Tp> 1488b1e83836Smrg _GLIBCXX20_CONSTEXPR 1489b17d1066Smrg enable_if_t<__exactly_once<__accepted_type<_Tp&&>> 1490181254a7Smrg && is_constructible_v<__accepted_type<_Tp&&>, _Tp> 1491181254a7Smrg && is_assignable_v<__accepted_type<_Tp&&>&, _Tp>, 1492181254a7Smrg variant&> 1493b17d1066Smrg operator=(_Tp&& __rhs) 1494181254a7Smrg noexcept(is_nothrow_assignable_v<__accepted_type<_Tp&&>&, _Tp> 1495181254a7Smrg && is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp>) 1496b17d1066Smrg { 1497fb8a8121Smrg constexpr auto __index = __accepted_index<_Tp>; 1498b17d1066Smrg if (index() == __index) 1499b17d1066Smrg std::get<__index>(*this) = std::forward<_Tp>(__rhs); 1500b17d1066Smrg else 1501181254a7Smrg { 1502181254a7Smrg using _Tj = __accepted_type<_Tp&&>; 1503181254a7Smrg if constexpr (is_nothrow_constructible_v<_Tj, _Tp> 1504181254a7Smrg || !is_nothrow_move_constructible_v<_Tj>) 1505b17d1066Smrg this->emplace<__index>(std::forward<_Tp>(__rhs)); 1506181254a7Smrg else 1507b1e83836Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 1508b1e83836Smrg // 3585. converting assignment with immovable alternative 1509b1e83836Smrg this->emplace<__index>(_Tj(std::forward<_Tp>(__rhs))); 1510181254a7Smrg } 1511b17d1066Smrg return *this; 1512b17d1066Smrg } 1513b17d1066Smrg 1514b17d1066Smrg template<typename _Tp, typename... _Args> 1515b1e83836Smrg _GLIBCXX20_CONSTEXPR 1516b17d1066Smrg enable_if_t<is_constructible_v<_Tp, _Args...> && __exactly_once<_Tp>, 1517b17d1066Smrg _Tp&> 1518b17d1066Smrg emplace(_Args&&... __args) 1519b17d1066Smrg { 1520181254a7Smrg constexpr size_t __index = __index_of<_Tp>; 1521181254a7Smrg return this->emplace<__index>(std::forward<_Args>(__args)...); 1522b17d1066Smrg } 1523b17d1066Smrg 1524b17d1066Smrg template<typename _Tp, typename _Up, typename... _Args> 1525b1e83836Smrg _GLIBCXX20_CONSTEXPR 1526b17d1066Smrg enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...> 1527b17d1066Smrg && __exactly_once<_Tp>, 1528b17d1066Smrg _Tp&> 1529b17d1066Smrg emplace(initializer_list<_Up> __il, _Args&&... __args) 1530b17d1066Smrg { 1531181254a7Smrg constexpr size_t __index = __index_of<_Tp>; 1532181254a7Smrg return this->emplace<__index>(__il, std::forward<_Args>(__args)...); 1533b17d1066Smrg } 1534b17d1066Smrg 1535b17d1066Smrg template<size_t _Np, typename... _Args> 1536b1e83836Smrg _GLIBCXX20_CONSTEXPR 1537b1e83836Smrg enable_if_t<is_constructible_v<__to_type<_Np>, _Args...>, 1538b1e83836Smrg __to_type<_Np>&> 1539b17d1066Smrg emplace(_Args&&... __args) 1540b17d1066Smrg { 1541b1e83836Smrg namespace __variant = std::__detail::__variant; 1542b1e83836Smrg using type = typename _Nth_type<_Np, _Types...>::type; 1543181254a7Smrg // Provide the strong exception-safety guarantee when possible, 1544181254a7Smrg // to avoid becoming valueless. 1545181254a7Smrg if constexpr (is_nothrow_constructible_v<type, _Args...>) 1546181254a7Smrg { 1547b1e83836Smrg __variant::__emplace<_Np>(*this, std::forward<_Args>(__args)...); 1548181254a7Smrg } 1549181254a7Smrg else if constexpr (is_scalar_v<type>) 1550181254a7Smrg { 1551181254a7Smrg // This might invoke a potentially-throwing conversion operator: 1552181254a7Smrg const type __tmp(std::forward<_Args>(__args)...); 1553b1e83836Smrg // But this won't throw: 1554b1e83836Smrg __variant::__emplace<_Np>(*this, __tmp); 1555181254a7Smrg } 1556b1e83836Smrg else if constexpr (__variant::_Never_valueless_alt<type>() 1557181254a7Smrg && _Traits::_S_move_assign) 1558181254a7Smrg { 1559181254a7Smrg // This construction might throw: 1560181254a7Smrg variant __tmp(in_place_index<_Np>, 1561181254a7Smrg std::forward<_Args>(__args)...); 1562181254a7Smrg // But _Never_valueless_alt<type> means this won't: 1563181254a7Smrg *this = std::move(__tmp); 1564181254a7Smrg } 1565181254a7Smrg else 1566181254a7Smrg { 1567181254a7Smrg // This case only provides the basic exception-safety guarantee, 1568181254a7Smrg // i.e. the variant can become valueless. 1569b1e83836Smrg __variant::__emplace<_Np>(*this, std::forward<_Args>(__args)...); 1570181254a7Smrg } 1571b17d1066Smrg return std::get<_Np>(*this); 1572b17d1066Smrg } 1573b17d1066Smrg 1574b17d1066Smrg template<size_t _Np, typename _Up, typename... _Args> 1575b1e83836Smrg _GLIBCXX20_CONSTEXPR 1576b1e83836Smrg enable_if_t<is_constructible_v<__to_type<_Np>, 1577b17d1066Smrg initializer_list<_Up>&, _Args...>, 1578b1e83836Smrg __to_type<_Np>&> 1579b17d1066Smrg emplace(initializer_list<_Up> __il, _Args&&... __args) 1580b17d1066Smrg { 1581b1e83836Smrg namespace __variant = std::__detail::__variant; 1582b1e83836Smrg using type = typename _Nth_type<_Np, _Types...>::type; 1583181254a7Smrg // Provide the strong exception-safety guarantee when possible, 1584181254a7Smrg // to avoid becoming valueless. 1585181254a7Smrg if constexpr (is_nothrow_constructible_v<type, 1586181254a7Smrg initializer_list<_Up>&, 1587181254a7Smrg _Args...>) 1588181254a7Smrg { 1589b1e83836Smrg __variant::__emplace<_Np>(*this, __il, 1590181254a7Smrg std::forward<_Args>(__args)...); 1591181254a7Smrg } 1592b1e83836Smrg else if constexpr (__variant::_Never_valueless_alt<type>() 1593181254a7Smrg && _Traits::_S_move_assign) 1594181254a7Smrg { 1595181254a7Smrg // This construction might throw: 1596181254a7Smrg variant __tmp(in_place_index<_Np>, __il, 1597181254a7Smrg std::forward<_Args>(__args)...); 1598181254a7Smrg // But _Never_valueless_alt<type> means this won't: 1599181254a7Smrg *this = std::move(__tmp); 1600181254a7Smrg } 1601181254a7Smrg else 1602181254a7Smrg { 1603181254a7Smrg // This case only provides the basic exception-safety guarantee, 1604181254a7Smrg // i.e. the variant can become valueless. 1605b1e83836Smrg __variant::__emplace<_Np>(*this, __il, 1606b17d1066Smrg std::forward<_Args>(__args)...); 1607b17d1066Smrg } 1608b17d1066Smrg return std::get<_Np>(*this); 1609b17d1066Smrg } 1610b17d1066Smrg 1611b1e83836Smrg template<size_t _Np, typename... _Args> 1612b1e83836Smrg enable_if_t<!(_Np < sizeof...(_Types))> emplace(_Args&&...) = delete; 1613b1e83836Smrg 1614b1e83836Smrg template<typename _Tp, typename... _Args> 1615b1e83836Smrg enable_if_t<!__exactly_once<_Tp>> emplace(_Args&&...) = delete; 1616b1e83836Smrg 1617b17d1066Smrg constexpr bool valueless_by_exception() const noexcept 1618b17d1066Smrg { return !this->_M_valid(); } 1619b17d1066Smrg 1620b17d1066Smrg constexpr size_t index() const noexcept 1621b17d1066Smrg { 1622fb8a8121Smrg using __index_type = typename _Base::__index_type; 1623fb8a8121Smrg if constexpr (__detail::__variant::__never_valueless<_Types...>()) 1624b17d1066Smrg return this->_M_index; 1625fb8a8121Smrg else if constexpr (sizeof...(_Types) <= __index_type(-1) / 2) 1626fb8a8121Smrg return make_signed_t<__index_type>(this->_M_index); 1627fb8a8121Smrg else 1628fb8a8121Smrg return size_t(__index_type(this->_M_index + 1)) - 1; 1629b17d1066Smrg } 1630b17d1066Smrg 1631b1e83836Smrg _GLIBCXX20_CONSTEXPR 1632b17d1066Smrg void 1633b17d1066Smrg swap(variant& __rhs) 1634b17d1066Smrg noexcept((__is_nothrow_swappable<_Types>::value && ...) 1635b17d1066Smrg && is_nothrow_move_constructible_v<variant>) 1636b17d1066Smrg { 1637b1e83836Smrg static_assert((is_move_constructible_v<_Types> && ...)); 1638b1e83836Smrg 1639b1e83836Smrg // Handle this here to simplify the visitation. 1640b1e83836Smrg if (__rhs.valueless_by_exception()) [[__unlikely__]] 1641b1e83836Smrg { 1642b1e83836Smrg if (!this->valueless_by_exception()) [[__likely__]] 1643b1e83836Smrg __rhs.swap(*this); 1644b1e83836Smrg return; 1645b1e83836Smrg } 1646b1e83836Smrg 1647b1e83836Smrg namespace __variant = __detail::__variant; 1648b1e83836Smrg 1649b1e83836Smrg __variant::__raw_idx_visit( 1650fb8a8121Smrg [this, &__rhs](auto&& __rhs_mem, auto __rhs_index) mutable 1651b17d1066Smrg { 1652b1e83836Smrg constexpr size_t __j = __rhs_index; 1653b1e83836Smrg if constexpr (__j != variant_npos) 1654b17d1066Smrg { 1655b1e83836Smrg if (this->index() == __j) 1656b17d1066Smrg { 1657181254a7Smrg using std::swap; 1658b1e83836Smrg swap(std::get<__j>(*this), __rhs_mem); 1659b17d1066Smrg } 1660b17d1066Smrg else 1661b17d1066Smrg { 1662181254a7Smrg auto __tmp(std::move(__rhs_mem)); 1663b1e83836Smrg 1664b1e83836Smrg if constexpr (_Traits::_S_trivial_move_assign) 1665181254a7Smrg __rhs = std::move(*this); 1666181254a7Smrg else 1667b1e83836Smrg __variant::__raw_idx_visit( 1668b1e83836Smrg [&__rhs](auto&& __this_mem, auto __this_index) mutable 1669181254a7Smrg { 1670b1e83836Smrg constexpr size_t __k = __this_index; 1671b1e83836Smrg if constexpr (__k != variant_npos) 1672b1e83836Smrg __variant::__emplace<__k>(__rhs, 1673b1e83836Smrg std::move(__this_mem)); 1674b1e83836Smrg }, *this); 1675b1e83836Smrg 1676b1e83836Smrg __variant::__emplace<__j>(*this, std::move(__tmp)); 1677181254a7Smrg } 1678181254a7Smrg } 1679181254a7Smrg }, __rhs); 1680b17d1066Smrg } 1681b17d1066Smrg 1682181254a7Smrg#if defined(__clang__) && __clang_major__ <= 7 1683b17d1066Smrg public: 1684b17d1066Smrg using _Base::_M_u; // See https://bugs.llvm.org/show_bug.cgi?id=31852 1685b17d1066Smrg#endif 1686b17d1066Smrg 1687b1e83836Smrg private: 1688b17d1066Smrg template<size_t _Np, typename _Vp> 1689181254a7Smrg friend constexpr decltype(auto) 1690181254a7Smrg __detail::__variant::__get(_Vp&& __v) noexcept; 1691b17d1066Smrg 1692b17d1066Smrg#define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP) \ 1693b17d1066Smrg template<typename... _Tp> \ 1694b17d1066Smrg friend constexpr bool \ 1695b17d1066Smrg operator __OP(const variant<_Tp...>& __lhs, \ 1696b17d1066Smrg const variant<_Tp...>& __rhs); 1697b17d1066Smrg 1698b17d1066Smrg _VARIANT_RELATION_FUNCTION_TEMPLATE(<) 1699b17d1066Smrg _VARIANT_RELATION_FUNCTION_TEMPLATE(<=) 1700b17d1066Smrg _VARIANT_RELATION_FUNCTION_TEMPLATE(==) 1701b17d1066Smrg _VARIANT_RELATION_FUNCTION_TEMPLATE(!=) 1702b17d1066Smrg _VARIANT_RELATION_FUNCTION_TEMPLATE(>=) 1703b17d1066Smrg _VARIANT_RELATION_FUNCTION_TEMPLATE(>) 1704b17d1066Smrg 1705b17d1066Smrg#undef _VARIANT_RELATION_FUNCTION_TEMPLATE 1706b17d1066Smrg }; 1707b17d1066Smrg 1708b17d1066Smrg template<size_t _Np, typename... _Types> 1709b17d1066Smrg constexpr variant_alternative_t<_Np, variant<_Types...>>& 1710b17d1066Smrg get(variant<_Types...>& __v) 1711b17d1066Smrg { 1712b17d1066Smrg static_assert(_Np < sizeof...(_Types), 1713fb8a8121Smrg "The index must be in [0, number of alternatives)"); 1714b17d1066Smrg if (__v.index() != _Np) 1715fb8a8121Smrg __throw_bad_variant_access(__v.valueless_by_exception()); 1716b17d1066Smrg return __detail::__variant::__get<_Np>(__v); 1717b17d1066Smrg } 1718b17d1066Smrg 1719b17d1066Smrg template<size_t _Np, typename... _Types> 1720b17d1066Smrg constexpr variant_alternative_t<_Np, variant<_Types...>>&& 1721b17d1066Smrg get(variant<_Types...>&& __v) 1722b17d1066Smrg { 1723b17d1066Smrg static_assert(_Np < sizeof...(_Types), 1724fb8a8121Smrg "The index must be in [0, number of alternatives)"); 1725b17d1066Smrg if (__v.index() != _Np) 1726fb8a8121Smrg __throw_bad_variant_access(__v.valueless_by_exception()); 1727b17d1066Smrg return __detail::__variant::__get<_Np>(std::move(__v)); 1728b17d1066Smrg } 1729b17d1066Smrg 1730b17d1066Smrg template<size_t _Np, typename... _Types> 1731b17d1066Smrg constexpr const variant_alternative_t<_Np, variant<_Types...>>& 1732b17d1066Smrg get(const variant<_Types...>& __v) 1733b17d1066Smrg { 1734b17d1066Smrg static_assert(_Np < sizeof...(_Types), 1735fb8a8121Smrg "The index must be in [0, number of alternatives)"); 1736b17d1066Smrg if (__v.index() != _Np) 1737fb8a8121Smrg __throw_bad_variant_access(__v.valueless_by_exception()); 1738b17d1066Smrg return __detail::__variant::__get<_Np>(__v); 1739b17d1066Smrg } 1740b17d1066Smrg 1741b17d1066Smrg template<size_t _Np, typename... _Types> 1742b17d1066Smrg constexpr const variant_alternative_t<_Np, variant<_Types...>>&& 1743b17d1066Smrg get(const variant<_Types...>&& __v) 1744b17d1066Smrg { 1745b17d1066Smrg static_assert(_Np < sizeof...(_Types), 1746fb8a8121Smrg "The index must be in [0, number of alternatives)"); 1747b17d1066Smrg if (__v.index() != _Np) 1748fb8a8121Smrg __throw_bad_variant_access(__v.valueless_by_exception()); 1749b17d1066Smrg return __detail::__variant::__get<_Np>(std::move(__v)); 1750b17d1066Smrg } 1751b17d1066Smrg 1752b1e83836Smrg /// @cond undocumented 1753fb8a8121Smrg template<typename _Result_type, typename _Visitor, typename... _Variants> 1754181254a7Smrg constexpr decltype(auto) 1755181254a7Smrg __do_visit(_Visitor&& __visitor, _Variants&&... __variants) 1756181254a7Smrg { 1757b1e83836Smrg // Get the silly case of visiting no variants out of the way first. 1758b1e83836Smrg if constexpr (sizeof...(_Variants) == 0) 1759b1e83836Smrg { 1760b1e83836Smrg if constexpr (is_void_v<_Result_type>) 1761b1e83836Smrg return (void) std::forward<_Visitor>(__visitor)(); 1762b1e83836Smrg else 1763b1e83836Smrg return std::forward<_Visitor>(__visitor)(); 1764b1e83836Smrg } 1765b1e83836Smrg else 1766b1e83836Smrg { 1767b1e83836Smrg constexpr size_t __max = 11; // "These go to eleven." 1768b1e83836Smrg 1769b1e83836Smrg // The type of the first variant in the pack. 1770b1e83836Smrg using _V0 = typename _Nth_type<0, _Variants...>::type; 1771b1e83836Smrg // The number of alternatives in that first variant. 1772b1e83836Smrg constexpr auto __n = variant_size_v<remove_reference_t<_V0>>; 1773b1e83836Smrg 1774b1e83836Smrg if constexpr (sizeof...(_Variants) > 1 || __n > __max) 1775b1e83836Smrg { 1776b1e83836Smrg // Use a jump table for the general case. 1777181254a7Smrg constexpr auto& __vtable = __detail::__variant::__gen_vtable< 1778181254a7Smrg _Result_type, _Visitor&&, _Variants&&...>::_S_vtable; 1779181254a7Smrg 1780181254a7Smrg auto __func_ptr = __vtable._M_access(__variants.index()...); 1781181254a7Smrg return (*__func_ptr)(std::forward<_Visitor>(__visitor), 1782181254a7Smrg std::forward<_Variants>(__variants)...); 1783181254a7Smrg } 1784b1e83836Smrg else // We have a single variant with a small number of alternatives. 1785b1e83836Smrg { 1786b1e83836Smrg // A name for the first variant in the pack. 1787b1e83836Smrg _V0& __v0 1788b1e83836Smrg = [](_V0& __v, ...) -> _V0& { return __v; }(__variants...); 1789b1e83836Smrg 1790b1e83836Smrg using __detail::__variant::_Multi_array; 1791b1e83836Smrg using __detail::__variant::__gen_vtable_impl; 1792b1e83836Smrg using _Ma = _Multi_array<_Result_type (*)(_Visitor&&, _V0&&)>; 1793b1e83836Smrg 1794b1e83836Smrg#ifdef _GLIBCXX_DEBUG 1795b1e83836Smrg# define _GLIBCXX_VISIT_UNREACHABLE __builtin_trap 1796b1e83836Smrg#else 1797b1e83836Smrg# define _GLIBCXX_VISIT_UNREACHABLE __builtin_unreachable 1798b1e83836Smrg#endif 1799b1e83836Smrg 1800b1e83836Smrg#define _GLIBCXX_VISIT_CASE(N) \ 1801b1e83836Smrg case N: \ 1802b1e83836Smrg { \ 1803b1e83836Smrg if constexpr (N < __n) \ 1804b1e83836Smrg { \ 1805b1e83836Smrg return __gen_vtable_impl<_Ma, index_sequence<N>>:: \ 1806b1e83836Smrg __visit_invoke(std::forward<_Visitor>(__visitor), \ 1807b1e83836Smrg std::forward<_V0>(__v0)); \ 1808b1e83836Smrg } \ 1809b1e83836Smrg else _GLIBCXX_VISIT_UNREACHABLE(); \ 1810b1e83836Smrg } 1811b1e83836Smrg 1812b1e83836Smrg switch (__v0.index()) 1813b1e83836Smrg { 1814b1e83836Smrg _GLIBCXX_VISIT_CASE(0) 1815b1e83836Smrg _GLIBCXX_VISIT_CASE(1) 1816b1e83836Smrg _GLIBCXX_VISIT_CASE(2) 1817b1e83836Smrg _GLIBCXX_VISIT_CASE(3) 1818b1e83836Smrg _GLIBCXX_VISIT_CASE(4) 1819b1e83836Smrg _GLIBCXX_VISIT_CASE(5) 1820b1e83836Smrg _GLIBCXX_VISIT_CASE(6) 1821b1e83836Smrg _GLIBCXX_VISIT_CASE(7) 1822b1e83836Smrg _GLIBCXX_VISIT_CASE(8) 1823b1e83836Smrg _GLIBCXX_VISIT_CASE(9) 1824b1e83836Smrg _GLIBCXX_VISIT_CASE(10) 1825b1e83836Smrg case variant_npos: 1826b1e83836Smrg using __detail::__variant::__variant_idx_cookie; 1827b1e83836Smrg using __detail::__variant::__variant_cookie; 1828b1e83836Smrg if constexpr (is_same_v<_Result_type, __variant_idx_cookie> 1829b1e83836Smrg || is_same_v<_Result_type, __variant_cookie>) 1830b1e83836Smrg { 1831b1e83836Smrg using _Npos = index_sequence<variant_npos>; 1832b1e83836Smrg return __gen_vtable_impl<_Ma, _Npos>:: 1833b1e83836Smrg __visit_invoke(std::forward<_Visitor>(__visitor), 1834b1e83836Smrg std::forward<_V0>(__v0)); 1835b1e83836Smrg } 1836b1e83836Smrg else 1837b1e83836Smrg _GLIBCXX_VISIT_UNREACHABLE(); 1838b1e83836Smrg default: 1839b1e83836Smrg _GLIBCXX_VISIT_UNREACHABLE(); 1840b1e83836Smrg } 1841b1e83836Smrg#undef _GLIBCXX_VISIT_CASE 1842b1e83836Smrg#undef _GLIBCXX_VISIT_UNREACHABLE 1843b1e83836Smrg } 1844b1e83836Smrg } 1845b1e83836Smrg } 1846b1e83836Smrg /// @endcond 1847181254a7Smrg 1848b17d1066Smrg template<typename _Visitor, typename... _Variants> 1849a448f87cSmrg constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...> 1850b17d1066Smrg visit(_Visitor&& __visitor, _Variants&&... __variants) 1851b17d1066Smrg { 1852b1e83836Smrg namespace __variant = std::__detail::__variant; 1853b1e83836Smrg 1854b1e83836Smrg if ((__variant::__as(__variants).valueless_by_exception() || ...)) 1855fb8a8121Smrg __throw_bad_variant_access("std::visit: variant is valueless"); 1856b17d1066Smrg 1857a448f87cSmrg using _Result_type 1858a448f87cSmrg = __detail::__variant::__visit_result_t<_Visitor, _Variants...>; 1859fb8a8121Smrg 1860fb8a8121Smrg using _Tag = __detail::__variant::__deduce_visit_result<_Result_type>; 1861fb8a8121Smrg 1862b1e83836Smrg if constexpr (sizeof...(_Variants) == 1) 1863b1e83836Smrg { 1864b1e83836Smrg using _Vp = decltype(__variant::__as(std::declval<_Variants>()...)); 1865b1e83836Smrg 1866b1e83836Smrg constexpr bool __visit_rettypes_match = __detail::__variant:: 1867b1e83836Smrg __check_visitor_results<_Visitor, _Vp>( 1868b1e83836Smrg make_index_sequence<variant_size_v<remove_reference_t<_Vp>>>()); 1869b1e83836Smrg if constexpr (!__visit_rettypes_match) 1870b1e83836Smrg { 1871b1e83836Smrg static_assert(__visit_rettypes_match, 1872b1e83836Smrg "std::visit requires the visitor to have the same " 1873b1e83836Smrg "return type for all alternatives of a variant"); 1874b1e83836Smrg return; 1875b1e83836Smrg } 1876b1e83836Smrg else 1877b1e83836Smrg return std::__do_visit<_Tag>( 1878b1e83836Smrg std::forward<_Visitor>(__visitor), 1879b1e83836Smrg static_cast<_Vp>(__variants)...); 1880b1e83836Smrg } 1881b1e83836Smrg else 1882b1e83836Smrg return std::__do_visit<_Tag>( 1883b1e83836Smrg std::forward<_Visitor>(__visitor), 1884b1e83836Smrg __variant::__as(std::forward<_Variants>(__variants))...); 1885b17d1066Smrg } 1886b17d1066Smrg 1887181254a7Smrg#if __cplusplus > 201703L 1888181254a7Smrg template<typename _Res, typename _Visitor, typename... _Variants> 1889181254a7Smrg constexpr _Res 1890181254a7Smrg visit(_Visitor&& __visitor, _Variants&&... __variants) 1891181254a7Smrg { 1892b1e83836Smrg namespace __variant = std::__detail::__variant; 1893b1e83836Smrg 1894b1e83836Smrg if ((__variant::__as(__variants).valueless_by_exception() || ...)) 1895fb8a8121Smrg __throw_bad_variant_access("std::visit<R>: variant is valueless"); 1896181254a7Smrg 1897fb8a8121Smrg return std::__do_visit<_Res>(std::forward<_Visitor>(__visitor), 1898b1e83836Smrg __variant::__as(std::forward<_Variants>(__variants))...); 1899181254a7Smrg } 1900181254a7Smrg#endif 1901181254a7Smrg 1902b1e83836Smrg /// @cond undocumented 1903b17d1066Smrg template<bool, typename... _Types> 1904b17d1066Smrg struct __variant_hash_call_base_impl 1905b17d1066Smrg { 1906b17d1066Smrg size_t 1907b17d1066Smrg operator()(const variant<_Types...>& __t) const 1908b17d1066Smrg noexcept((is_nothrow_invocable_v<hash<decay_t<_Types>>, _Types> && ...)) 1909b17d1066Smrg { 1910181254a7Smrg size_t __ret; 1911fb8a8121Smrg __detail::__variant::__raw_visit( 1912fb8a8121Smrg [&__t, &__ret](auto&& __t_mem) mutable 1913b17d1066Smrg { 1914181254a7Smrg using _Type = __remove_cvref_t<decltype(__t_mem)>; 1915181254a7Smrg if constexpr (!is_same_v<_Type, 1916181254a7Smrg __detail::__variant::__variant_cookie>) 1917181254a7Smrg __ret = std::hash<size_t>{}(__t.index()) 1918181254a7Smrg + std::hash<_Type>{}(__t_mem); 1919181254a7Smrg else 1920181254a7Smrg __ret = std::hash<size_t>{}(__t.index()); 1921181254a7Smrg }, __t); 1922181254a7Smrg return __ret; 1923b17d1066Smrg } 1924b17d1066Smrg }; 1925b17d1066Smrg 1926b17d1066Smrg template<typename... _Types> 1927b17d1066Smrg struct __variant_hash_call_base_impl<false, _Types...> {}; 1928b17d1066Smrg 1929b17d1066Smrg template<typename... _Types> 1930b17d1066Smrg using __variant_hash_call_base = 1931b17d1066Smrg __variant_hash_call_base_impl<(__poison_hash<remove_const_t<_Types>>:: 1932b17d1066Smrg __enable_hash_call &&...), _Types...>; 1933b1e83836Smrg /// @endcond 1934b17d1066Smrg 1935b17d1066Smrg template<typename... _Types> 1936b17d1066Smrg struct hash<variant<_Types...>> 1937b17d1066Smrg : private __detail::__variant::_Variant_hash_base< 1938b17d1066Smrg variant<_Types...>, std::index_sequence_for<_Types...>>, 1939b17d1066Smrg public __variant_hash_call_base<_Types...> 1940b17d1066Smrg { 1941a3e9eb18Smrg using result_type [[__deprecated__]] = size_t; 1942a3e9eb18Smrg using argument_type [[__deprecated__]] = variant<_Types...>; 1943b17d1066Smrg }; 1944b17d1066Smrg 1945b17d1066Smrg template<> 1946b17d1066Smrg struct hash<monostate> 1947b17d1066Smrg { 1948a3e9eb18Smrg using result_type [[__deprecated__]] = size_t; 1949a3e9eb18Smrg using argument_type [[__deprecated__]] = monostate; 1950b17d1066Smrg 1951b17d1066Smrg size_t 1952fb8a8121Smrg operator()(const monostate&) const noexcept 1953b17d1066Smrg { 1954b17d1066Smrg constexpr size_t __magic_monostate_hash = -7777; 1955b17d1066Smrg return __magic_monostate_hash; 1956b17d1066Smrg } 1957b17d1066Smrg }; 1958b17d1066Smrg 1959a3e9eb18Smrg template<typename... _Types> 1960a3e9eb18Smrg struct __is_fast_hash<hash<variant<_Types...>>> 1961a3e9eb18Smrg : bool_constant<(__is_fast_hash<_Types>::value && ...)> 1962a3e9eb18Smrg { }; 1963a3e9eb18Smrg 1964b17d1066Smrg_GLIBCXX_END_NAMESPACE_VERSION 1965b17d1066Smrg} // namespace std 1966b17d1066Smrg 1967b17d1066Smrg#endif // C++17 1968b17d1066Smrg 1969b17d1066Smrg#endif // _GLIBCXX_VARIANT 1970