xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/std/expected (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1*b1e83836Smrg// <expected> -*- C++ -*-
2*b1e83836Smrg
3*b1e83836Smrg// Copyright The GNU Toolchain Authors.
4*b1e83836Smrg//
5*b1e83836Smrg// This file is part of the GNU ISO C++ Library.  This library is free
6*b1e83836Smrg// software; you can redistribute it and/or modify it under the
7*b1e83836Smrg// terms of the GNU General Public License as published by the
8*b1e83836Smrg// Free Software Foundation; either version 3, or (at your option)
9*b1e83836Smrg// any later version.
10*b1e83836Smrg
11*b1e83836Smrg// This library is distributed in the hope that it will be useful,
12*b1e83836Smrg// but WITHOUT ANY WARRANTY; without even the implied warranty of
13*b1e83836Smrg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*b1e83836Smrg// GNU General Public License for more details.
15*b1e83836Smrg
16*b1e83836Smrg// Under Section 7 of GPL version 3, you are granted additional
17*b1e83836Smrg// permissions described in the GCC Runtime Library Exception, version
18*b1e83836Smrg// 3.1, as published by the Free Software Foundation.
19*b1e83836Smrg
20*b1e83836Smrg// You should have received a copy of the GNU General Public License and
21*b1e83836Smrg// a copy of the GCC Runtime Library Exception along with this program;
22*b1e83836Smrg// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23*b1e83836Smrg// <http://www.gnu.org/licenses/>.
24*b1e83836Smrg
25*b1e83836Smrg/** @file include/expected
26*b1e83836Smrg *  This is a Standard C++ Library header.
27*b1e83836Smrg */
28*b1e83836Smrg
29*b1e83836Smrg#ifndef _GLIBCXX_EXPECTED
30*b1e83836Smrg#define _GLIBCXX_EXPECTED
31*b1e83836Smrg
32*b1e83836Smrg#pragma GCC system_header
33*b1e83836Smrg
34*b1e83836Smrg#if __cplusplus > 202002L && __cpp_concepts >= 202002L
35*b1e83836Smrg
36*b1e83836Smrg#include <initializer_list>
37*b1e83836Smrg#include <bits/exception.h>	// exception
38*b1e83836Smrg#include <bits/stl_construct.h>	// construct_at
39*b1e83836Smrg#include <bits/utility.h>	// in_place_t
40*b1e83836Smrg
41*b1e83836Smrgnamespace std _GLIBCXX_VISIBILITY(default)
42*b1e83836Smrg{
43*b1e83836Smrg_GLIBCXX_BEGIN_NAMESPACE_VERSION
44*b1e83836Smrg
45*b1e83836Smrg  /**
46*b1e83836Smrg   * @defgroup expected_values Expected values
47*b1e83836Smrg   * @addtogroup utilities
48*b1e83836Smrg   * @since C++23
49*b1e83836Smrg   * @{
50*b1e83836Smrg   */
51*b1e83836Smrg
52*b1e83836Smrg#define __cpp_lib_expected 202202L
53*b1e83836Smrg
54*b1e83836Smrg  /// Discriminated union that holds an expected value or an error value.
55*b1e83836Smrg  /**
56*b1e83836Smrg   * @since C++23
57*b1e83836Smrg   */
58*b1e83836Smrg  template<typename _Tp, typename _Er>
59*b1e83836Smrg    class expected;
60*b1e83836Smrg
61*b1e83836Smrg  /// Wrapper type used to pass an error value to a `std::expected`.
62*b1e83836Smrg  /**
63*b1e83836Smrg   * @since C++23
64*b1e83836Smrg   */
65*b1e83836Smrg  template<typename _Er>
66*b1e83836Smrg    class unexpected;
67*b1e83836Smrg
68*b1e83836Smrg  /// Exception thrown by std::expected when the value() is not present.
69*b1e83836Smrg  /**
70*b1e83836Smrg   * @since C++23
71*b1e83836Smrg   */
72*b1e83836Smrg  template<typename _Er>
73*b1e83836Smrg    class bad_expected_access;
74*b1e83836Smrg
75*b1e83836Smrg  template<>
76*b1e83836Smrg    class bad_expected_access<void> : public exception
77*b1e83836Smrg    {
78*b1e83836Smrg    protected:
79*b1e83836Smrg      bad_expected_access() noexcept { }
80*b1e83836Smrg      bad_expected_access(const bad_expected_access&) = default;
81*b1e83836Smrg      bad_expected_access(bad_expected_access&&) = default;
82*b1e83836Smrg      bad_expected_access& operator=(const bad_expected_access&) = default;
83*b1e83836Smrg      bad_expected_access& operator=(bad_expected_access&&) = default;
84*b1e83836Smrg      ~bad_expected_access() = default;
85*b1e83836Smrg
86*b1e83836Smrg    public:
87*b1e83836Smrg
88*b1e83836Smrg      [[nodiscard]]
89*b1e83836Smrg      const char*
90*b1e83836Smrg      what() const noexcept override
91*b1e83836Smrg      { return "bad access to std::expected without expected value"; }
92*b1e83836Smrg    };
93*b1e83836Smrg
94*b1e83836Smrg  template<typename _Er>
95*b1e83836Smrg    class bad_expected_access : public bad_expected_access<void> {
96*b1e83836Smrg    public:
97*b1e83836Smrg      explicit
98*b1e83836Smrg      bad_expected_access(_Er __e) : _M_unex(std::move(__e)) { }
99*b1e83836Smrg
100*b1e83836Smrg      // XXX const char* what() const noexcept override;
101*b1e83836Smrg
102*b1e83836Smrg      [[nodiscard]]
103*b1e83836Smrg      _Er&
104*b1e83836Smrg      error() & noexcept
105*b1e83836Smrg      { return _M_unex; }
106*b1e83836Smrg
107*b1e83836Smrg      [[nodiscard]]
108*b1e83836Smrg      const _Er&
109*b1e83836Smrg      error() const & noexcept
110*b1e83836Smrg      { return _M_unex; }
111*b1e83836Smrg
112*b1e83836Smrg      [[nodiscard]]
113*b1e83836Smrg      _Er&&
114*b1e83836Smrg      error() && noexcept
115*b1e83836Smrg      { return std::move(_M_unex); }
116*b1e83836Smrg
117*b1e83836Smrg      [[nodiscard]]
118*b1e83836Smrg      const _Er&&
119*b1e83836Smrg      error() const && noexcept
120*b1e83836Smrg      { return std::move(_M_unex); }
121*b1e83836Smrg
122*b1e83836Smrg    private:
123*b1e83836Smrg      _Er _M_unex;
124*b1e83836Smrg    };
125*b1e83836Smrg
126*b1e83836Smrg  /// Tag type for constructing unexpected values in a std::expected
127*b1e83836Smrg  /**
128*b1e83836Smrg   * @since C++23
129*b1e83836Smrg   */
130*b1e83836Smrg  struct unexpect_t
131*b1e83836Smrg  {
132*b1e83836Smrg    explicit unexpect_t() = default;
133*b1e83836Smrg  };
134*b1e83836Smrg
135*b1e83836Smrg  /// Tag for constructing unexpected values in a std::expected
136*b1e83836Smrg  /**
137*b1e83836Smrg   * @since C++23
138*b1e83836Smrg   */
139*b1e83836Smrg  inline constexpr unexpect_t unexpect{};
140*b1e83836Smrg
141*b1e83836Smrg/// @cond undoc
142*b1e83836Smrgnamespace __expected
143*b1e83836Smrg{
144*b1e83836Smrg  template<typename _Tp>
145*b1e83836Smrg    constexpr bool __is_expected = false;
146*b1e83836Smrg  template<typename _Tp, typename _Er>
147*b1e83836Smrg    constexpr bool __is_expected<expected<_Tp, _Er>> = true;
148*b1e83836Smrg
149*b1e83836Smrg  template<typename _Tp>
150*b1e83836Smrg    constexpr bool __is_unexpected = false;
151*b1e83836Smrg  template<typename _Tp>
152*b1e83836Smrg    constexpr bool __is_unexpected<unexpected<_Tp>> = true;
153*b1e83836Smrg
154*b1e83836Smrg  template<typename _Er>
155*b1e83836Smrg    concept __can_be_unexpected
156*b1e83836Smrg      = is_object_v<_Er> && (!is_array_v<_Er>)
157*b1e83836Smrg	  && (!__expected::__is_unexpected<_Er>)
158*b1e83836Smrg	  && (!is_const_v<_Er>) && (!is_volatile_v<_Er>);
159*b1e83836Smrg}
160*b1e83836Smrg/// @endcond
161*b1e83836Smrg
162*b1e83836Smrg  template<typename _Er>
163*b1e83836Smrg    class unexpected
164*b1e83836Smrg    {
165*b1e83836Smrg      static_assert( __expected::__can_be_unexpected<_Er> );
166*b1e83836Smrg
167*b1e83836Smrg    public:
168*b1e83836Smrg      constexpr unexpected(const unexpected&) = default;
169*b1e83836Smrg      constexpr unexpected(unexpected&&) = default;
170*b1e83836Smrg
171*b1e83836Smrg      template<typename _Err = _Er>
172*b1e83836Smrg	requires (!is_same_v<remove_cvref_t<_Err>, unexpected>)
173*b1e83836Smrg	  && (!is_same_v<remove_cvref_t<_Err>, in_place_t>)
174*b1e83836Smrg	  && is_constructible_v<_Er, _Err>
175*b1e83836Smrg	constexpr explicit
176*b1e83836Smrg	unexpected(_Err&& __e)
177*b1e83836Smrg	noexcept(is_nothrow_constructible_v<_Er, _Err>)
178*b1e83836Smrg	: _M_unex(std::forward<_Err>(__e))
179*b1e83836Smrg	{ }
180*b1e83836Smrg
181*b1e83836Smrg      template<typename... _Args>
182*b1e83836Smrg	requires is_constructible_v<_Er, _Args...>
183*b1e83836Smrg	constexpr explicit
184*b1e83836Smrg	unexpected(in_place_t, _Args&&... __args)
185*b1e83836Smrg	noexcept(is_nothrow_constructible_v<_Er, _Args...>)
186*b1e83836Smrg	: _M_unex(std::forward<_Args>(__args)...)
187*b1e83836Smrg	{ }
188*b1e83836Smrg
189*b1e83836Smrg      template<typename _Up, typename... _Args>
190*b1e83836Smrg	requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
191*b1e83836Smrg	constexpr explicit
192*b1e83836Smrg	unexpected(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
193*b1e83836Smrg	noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
194*b1e83836Smrg					    _Args...>)
195*b1e83836Smrg	: _M_unex(__il, std::forward<_Args>(__args)...)
196*b1e83836Smrg	{ }
197*b1e83836Smrg
198*b1e83836Smrg      constexpr unexpected& operator=(const unexpected&) = default;
199*b1e83836Smrg      constexpr unexpected& operator=(unexpected&&) = default;
200*b1e83836Smrg
201*b1e83836Smrg
202*b1e83836Smrg      [[nodiscard]]
203*b1e83836Smrg      constexpr const _Er&
204*b1e83836Smrg      error() const & noexcept { return _M_unex; }
205*b1e83836Smrg
206*b1e83836Smrg      [[nodiscard]]
207*b1e83836Smrg      constexpr _Er&
208*b1e83836Smrg      error() & noexcept { return _M_unex; }
209*b1e83836Smrg
210*b1e83836Smrg      [[nodiscard]]
211*b1e83836Smrg      constexpr const _Er&&
212*b1e83836Smrg      error() const && noexcept { return std::move(_M_unex); }
213*b1e83836Smrg
214*b1e83836Smrg      [[nodiscard]]
215*b1e83836Smrg      constexpr _Er&&
216*b1e83836Smrg      error() && noexcept { return std::move(_M_unex); }
217*b1e83836Smrg
218*b1e83836Smrg      constexpr void
219*b1e83836Smrg      swap(unexpected& __other) noexcept(is_nothrow_swappable_v<_Er>)
220*b1e83836Smrg      requires is_swappable_v<_Er>
221*b1e83836Smrg      {
222*b1e83836Smrg	using std::swap;
223*b1e83836Smrg	swap(_M_unex, __other._M_unex);
224*b1e83836Smrg      }
225*b1e83836Smrg
226*b1e83836Smrg      template<typename _Err>
227*b1e83836Smrg	[[nodiscard]]
228*b1e83836Smrg	friend constexpr bool
229*b1e83836Smrg	operator==(const unexpected& __x, const unexpected<_Err>& __y)
230*b1e83836Smrg	{ return __x._M_unex == __y.error(); }
231*b1e83836Smrg
232*b1e83836Smrg      friend constexpr void
233*b1e83836Smrg      swap(unexpected& __x, unexpected& __y) noexcept(noexcept(__x.swap(__y)))
234*b1e83836Smrg      requires is_swappable_v<_Er>
235*b1e83836Smrg      { __x.swap(__y); }
236*b1e83836Smrg
237*b1e83836Smrg    private:
238*b1e83836Smrg      _Er _M_unex;
239*b1e83836Smrg    };
240*b1e83836Smrg
241*b1e83836Smrg  template<typename _Er> unexpected(_Er) -> unexpected<_Er>;
242*b1e83836Smrg
243*b1e83836Smrg/// @cond undoc
244*b1e83836Smrgnamespace __expected
245*b1e83836Smrg{
246*b1e83836Smrg  template<typename _Tp>
247*b1e83836Smrg    struct _Guard
248*b1e83836Smrg    {
249*b1e83836Smrg      static_assert( is_nothrow_move_constructible_v<_Tp> );
250*b1e83836Smrg
251*b1e83836Smrg      constexpr explicit
252*b1e83836Smrg      _Guard(_Tp& __x)
253*b1e83836Smrg      : _M_guarded(__builtin_addressof(__x)), _M_tmp(std::move(__x)) // nothrow
254*b1e83836Smrg      { std::destroy_at(_M_guarded); }
255*b1e83836Smrg
256*b1e83836Smrg      constexpr
257*b1e83836Smrg      ~_Guard()
258*b1e83836Smrg      {
259*b1e83836Smrg	if (_M_guarded) [[unlikely]]
260*b1e83836Smrg	  std::construct_at(_M_guarded, std::move(_M_tmp));
261*b1e83836Smrg      }
262*b1e83836Smrg
263*b1e83836Smrg      _Guard(const _Guard&) = delete;
264*b1e83836Smrg      _Guard& operator=(const _Guard&) = delete;
265*b1e83836Smrg
266*b1e83836Smrg      constexpr _Tp&&
267*b1e83836Smrg      release() noexcept
268*b1e83836Smrg      {
269*b1e83836Smrg	_M_guarded = nullptr;
270*b1e83836Smrg	return std::move(_M_tmp);
271*b1e83836Smrg      }
272*b1e83836Smrg
273*b1e83836Smrg    private:
274*b1e83836Smrg      _Tp* _M_guarded;
275*b1e83836Smrg      _Tp _M_tmp;
276*b1e83836Smrg    };
277*b1e83836Smrg
278*b1e83836Smrg  // reinit-expected helper from [expected.object.assign]
279*b1e83836Smrg  template<typename _Tp, typename _Up, typename _Vp>
280*b1e83836Smrg    constexpr void
281*b1e83836Smrg    __reinit(_Tp* __newval, _Up* __oldval, _Vp&& __arg)
282*b1e83836Smrg    noexcept(is_nothrow_constructible_v<_Tp, _Vp>)
283*b1e83836Smrg    {
284*b1e83836Smrg      if constexpr (is_nothrow_constructible_v<_Tp, _Vp>)
285*b1e83836Smrg	{
286*b1e83836Smrg	  std::destroy_at(__oldval);
287*b1e83836Smrg	  std::construct_at(__newval, std::forward<_Vp>(__arg));
288*b1e83836Smrg	}
289*b1e83836Smrg      else if constexpr (is_nothrow_move_constructible_v<_Tp>)
290*b1e83836Smrg	{
291*b1e83836Smrg	  _Tp __tmp(std::forward<_Vp>(__arg)); // might throw
292*b1e83836Smrg	  std::destroy_at(__oldval);
293*b1e83836Smrg	  std::construct_at(__newval, std::move(__tmp));
294*b1e83836Smrg	}
295*b1e83836Smrg      else
296*b1e83836Smrg	{
297*b1e83836Smrg	  _Guard<_Up> __guard(*__oldval);
298*b1e83836Smrg	  std::construct_at(__newval, std::forward<_Vp>(__arg)); // might throw
299*b1e83836Smrg	  __guard.release();
300*b1e83836Smrg	}
301*b1e83836Smrg    }
302*b1e83836Smrg}
303*b1e83836Smrg/// @endcond
304*b1e83836Smrg
305*b1e83836Smrg  template<typename _Tp, typename _Er>
306*b1e83836Smrg    class expected
307*b1e83836Smrg    {
308*b1e83836Smrg      static_assert( ! is_reference_v<_Tp> );
309*b1e83836Smrg      static_assert( ! is_function_v<_Tp> );
310*b1e83836Smrg      static_assert( ! is_same_v<remove_cv_t<_Tp>, in_place_t> );
311*b1e83836Smrg      static_assert( ! is_same_v<remove_cv_t<_Tp>, unexpect_t> );
312*b1e83836Smrg      static_assert( ! __expected::__is_unexpected<remove_cv_t<_Tp>> );
313*b1e83836Smrg      static_assert( __expected::__can_be_unexpected<_Er> );
314*b1e83836Smrg
315*b1e83836Smrg      template<typename _Up, typename _Err, typename _Unex = unexpected<_Er>>
316*b1e83836Smrg	static constexpr bool __cons_from_expected
317*b1e83836Smrg	  = __or_v<is_constructible<_Tp, expected<_Up, _Err>&>,
318*b1e83836Smrg		   is_constructible<_Tp, expected<_Up, _Err>>,
319*b1e83836Smrg		   is_constructible<_Tp, const expected<_Up, _Err>&>,
320*b1e83836Smrg		   is_constructible<_Tp, const expected<_Up, _Err>>,
321*b1e83836Smrg		   is_convertible<expected<_Up, _Err>&, _Tp>,
322*b1e83836Smrg		   is_convertible<expected<_Up, _Err>, _Tp>,
323*b1e83836Smrg		   is_convertible<const expected<_Up, _Err>&, _Tp>,
324*b1e83836Smrg		   is_convertible<const expected<_Up, _Err>, _Tp>,
325*b1e83836Smrg		   is_constructible<_Unex, expected<_Up, _Err>&>,
326*b1e83836Smrg		   is_constructible<_Unex, expected<_Up, _Err>>,
327*b1e83836Smrg		   is_constructible<_Unex, const expected<_Up, _Err>&>,
328*b1e83836Smrg		   is_constructible<_Unex, const expected<_Up, _Err>>
329*b1e83836Smrg		  >;
330*b1e83836Smrg
331*b1e83836Smrg      template<typename _Up, typename _Err>
332*b1e83836Smrg	constexpr static bool __explicit_conv
333*b1e83836Smrg	  = __or_v<__not_<is_convertible<_Up, _Tp>>,
334*b1e83836Smrg		   __not_<is_convertible<_Err, _Er>>
335*b1e83836Smrg		  >;
336*b1e83836Smrg
337*b1e83836Smrg    public:
338*b1e83836Smrg      using value_type = _Tp;
339*b1e83836Smrg      using error_type = _Er;
340*b1e83836Smrg      using unexpected_type = unexpected<_Er>;
341*b1e83836Smrg
342*b1e83836Smrg      template<typename _Up>
343*b1e83836Smrg	using rebind = expected<_Up, error_type>;
344*b1e83836Smrg
345*b1e83836Smrg      constexpr
346*b1e83836Smrg      expected()
347*b1e83836Smrg      noexcept(is_nothrow_default_constructible_v<_Tp>)
348*b1e83836Smrg      requires is_default_constructible_v<_Tp>
349*b1e83836Smrg      : _M_val(), _M_has_value(true)
350*b1e83836Smrg      { }
351*b1e83836Smrg
352*b1e83836Smrg      expected(const expected&) = default;
353*b1e83836Smrg
354*b1e83836Smrg      constexpr
355*b1e83836Smrg      expected(const expected& __x)
356*b1e83836Smrg      noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
357*b1e83836Smrg		       is_nothrow_copy_constructible<_Er>>)
358*b1e83836Smrg      requires is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Er>
359*b1e83836Smrg      && (!is_trivially_copy_constructible_v<_Tp>
360*b1e83836Smrg	  || !is_trivially_copy_constructible_v<_Er>)
361*b1e83836Smrg      : _M_has_value(__x._M_has_value)
362*b1e83836Smrg      {
363*b1e83836Smrg	if (_M_has_value)
364*b1e83836Smrg	  std::construct_at(__builtin_addressof(_M_val), __x._M_val);
365*b1e83836Smrg	else
366*b1e83836Smrg	  std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
367*b1e83836Smrg      }
368*b1e83836Smrg
369*b1e83836Smrg      expected(expected&&) = default;
370*b1e83836Smrg
371*b1e83836Smrg      constexpr
372*b1e83836Smrg      expected(expected&& __x)
373*b1e83836Smrg      noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
374*b1e83836Smrg		       is_nothrow_move_constructible<_Er>>)
375*b1e83836Smrg      requires is_move_constructible_v<_Tp> && is_move_constructible_v<_Er>
376*b1e83836Smrg      && (!is_trivially_move_constructible_v<_Tp>
377*b1e83836Smrg	  || !is_trivially_move_constructible_v<_Er>)
378*b1e83836Smrg      : _M_has_value(__x._M_has_value)
379*b1e83836Smrg      {
380*b1e83836Smrg	if (_M_has_value)
381*b1e83836Smrg	  std::construct_at(__builtin_addressof(_M_val),
382*b1e83836Smrg			    std::move(__x)._M_val);
383*b1e83836Smrg	else
384*b1e83836Smrg	  std::construct_at(__builtin_addressof(_M_unex),
385*b1e83836Smrg			    std::move(__x)._M_unex);
386*b1e83836Smrg      }
387*b1e83836Smrg
388*b1e83836Smrg      template<typename _Up, typename _Gr>
389*b1e83836Smrg	requires is_constructible_v<_Tp, const _Up&>
390*b1e83836Smrg	      && is_constructible_v<_Er, const _Gr&>
391*b1e83836Smrg	      && (!__cons_from_expected<_Up, _Gr>)
392*b1e83836Smrg	constexpr explicit(__explicit_conv<const _Up&, const _Gr&>)
393*b1e83836Smrg	expected(const expected<_Up, _Gr>& __x)
394*b1e83836Smrg	noexcept(__and_v<is_nothrow_constructible<_Tp, const _Up&>,
395*b1e83836Smrg			 is_nothrow_constructible<_Er, const _Gr&>>)
396*b1e83836Smrg	: _M_has_value(__x._M_has_value)
397*b1e83836Smrg	{
398*b1e83836Smrg	  if (_M_has_value)
399*b1e83836Smrg	    std::construct_at(__builtin_addressof(_M_val), __x._M_val);
400*b1e83836Smrg	  else
401*b1e83836Smrg	    std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
402*b1e83836Smrg	}
403*b1e83836Smrg
404*b1e83836Smrg      template<typename _Up, typename _Gr>
405*b1e83836Smrg	requires is_constructible_v<_Tp, _Up>
406*b1e83836Smrg	      && is_constructible_v<_Er, _Gr>
407*b1e83836Smrg	      && (!__cons_from_expected<_Up, _Gr>)
408*b1e83836Smrg	constexpr explicit(__explicit_conv<_Up, _Gr>)
409*b1e83836Smrg	expected(expected<_Up, _Gr>&& __x)
410*b1e83836Smrg	noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>,
411*b1e83836Smrg			 is_nothrow_constructible<_Er, _Gr>>)
412*b1e83836Smrg	: _M_has_value(__x._M_has_value)
413*b1e83836Smrg	{
414*b1e83836Smrg	  if (_M_has_value)
415*b1e83836Smrg	    std::construct_at(__builtin_addressof(_M_val),
416*b1e83836Smrg			      std::move(__x)._M_val);
417*b1e83836Smrg	  else
418*b1e83836Smrg	    std::construct_at(__builtin_addressof(_M_unex),
419*b1e83836Smrg			      std::move(__x)._M_unex);
420*b1e83836Smrg	}
421*b1e83836Smrg
422*b1e83836Smrg      template<typename _Up = _Tp>
423*b1e83836Smrg	requires (!is_same_v<remove_cvref_t<_Up>, expected>)
424*b1e83836Smrg	  && (!is_same_v<remove_cvref_t<_Up>, in_place_t>)
425*b1e83836Smrg	  && (!__expected::__is_unexpected<remove_cvref_t<_Up>>)
426*b1e83836Smrg	  && is_constructible_v<_Tp, _Up>
427*b1e83836Smrg	constexpr explicit(!is_convertible_v<_Up, _Tp>)
428*b1e83836Smrg	expected(_Up&& __v)
429*b1e83836Smrg	noexcept(is_nothrow_constructible_v<_Tp, _Up>)
430*b1e83836Smrg	: _M_val(std::forward<_Up>(__v)), _M_has_value(true)
431*b1e83836Smrg	{ }
432*b1e83836Smrg
433*b1e83836Smrg      template<typename _Gr = _Er>
434*b1e83836Smrg	requires is_constructible_v<_Er, const _Gr&>
435*b1e83836Smrg	constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
436*b1e83836Smrg	expected(const unexpected<_Gr>& __u)
437*b1e83836Smrg	noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
438*b1e83836Smrg	: _M_unex(__u.error()), _M_has_value(false)
439*b1e83836Smrg	{ }
440*b1e83836Smrg
441*b1e83836Smrg      template<typename _Gr = _Er>
442*b1e83836Smrg	requires is_constructible_v<_Er, _Gr>
443*b1e83836Smrg	constexpr explicit(!is_convertible_v<_Gr, _Er>)
444*b1e83836Smrg	expected(unexpected<_Gr>&& __u)
445*b1e83836Smrg	noexcept(is_nothrow_constructible_v<_Er, _Gr>)
446*b1e83836Smrg	: _M_unex(std::move(__u).error()), _M_has_value(false)
447*b1e83836Smrg	{ }
448*b1e83836Smrg
449*b1e83836Smrg      template<typename... _Args>
450*b1e83836Smrg	requires is_constructible_v<_Tp, _Args...>
451*b1e83836Smrg	constexpr explicit
452*b1e83836Smrg	expected(in_place_t, _Args&&... __args)
453*b1e83836Smrg	noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
454*b1e83836Smrg	: _M_val(std::forward<_Args>(__args)...), _M_has_value(true)
455*b1e83836Smrg	{ }
456*b1e83836Smrg
457*b1e83836Smrg      template<typename _Up, typename... _Args>
458*b1e83836Smrg	requires is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
459*b1e83836Smrg	constexpr explicit
460*b1e83836Smrg	expected(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
461*b1e83836Smrg	noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
462*b1e83836Smrg					    _Args...>)
463*b1e83836Smrg	: _M_val(__il, std::forward<_Args>(__args)...), _M_has_value(true)
464*b1e83836Smrg	{ }
465*b1e83836Smrg
466*b1e83836Smrg      template<typename... _Args>
467*b1e83836Smrg	requires is_constructible_v<_Er, _Args...>
468*b1e83836Smrg	constexpr explicit
469*b1e83836Smrg	expected(unexpect_t, _Args&&... __args)
470*b1e83836Smrg	noexcept(is_nothrow_constructible_v<_Er, _Args...>)
471*b1e83836Smrg	: _M_unex(std::forward<_Args>(__args)...), _M_has_value(false)
472*b1e83836Smrg	{ }
473*b1e83836Smrg
474*b1e83836Smrg      template<typename _Up, typename... _Args>
475*b1e83836Smrg	requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
476*b1e83836Smrg	constexpr explicit
477*b1e83836Smrg	expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
478*b1e83836Smrg	noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
479*b1e83836Smrg					    _Args...>)
480*b1e83836Smrg	: _M_unex(__il, std::forward<_Args>(__args)...), _M_has_value(false)
481*b1e83836Smrg	{ }
482*b1e83836Smrg
483*b1e83836Smrg      constexpr ~expected() = default;
484*b1e83836Smrg
485*b1e83836Smrg      constexpr ~expected()
486*b1e83836Smrg      requires (!is_trivially_destructible_v<_Tp>)
487*b1e83836Smrg	    || (!is_trivially_destructible_v<_Er>)
488*b1e83836Smrg      {
489*b1e83836Smrg	if (_M_has_value)
490*b1e83836Smrg	  std::destroy_at(__builtin_addressof(_M_val));
491*b1e83836Smrg	else
492*b1e83836Smrg	  std::destroy_at(__builtin_addressof(_M_unex));
493*b1e83836Smrg      }
494*b1e83836Smrg
495*b1e83836Smrg      // assignment
496*b1e83836Smrg
497*b1e83836Smrg      expected& operator=(const expected&) = delete;
498*b1e83836Smrg
499*b1e83836Smrg      constexpr expected&
500*b1e83836Smrg      operator=(const expected& __x)
501*b1e83836Smrg      noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
502*b1e83836Smrg		       is_nothrow_copy_constructible<_Er>,
503*b1e83836Smrg		       is_nothrow_copy_assignable<_Tp>,
504*b1e83836Smrg		       is_nothrow_copy_assignable<_Er>>)
505*b1e83836Smrg      requires is_copy_assignable_v<_Tp> && is_copy_constructible_v<_Tp>
506*b1e83836Smrg	    && is_copy_assignable_v<_Er> && is_copy_constructible_v<_Er>
507*b1e83836Smrg	    && (is_nothrow_move_constructible_v<_Tp>
508*b1e83836Smrg		|| is_nothrow_move_constructible_v<_Er>)
509*b1e83836Smrg      {
510*b1e83836Smrg	if (__x._M_has_value)
511*b1e83836Smrg	  this->_M_assign_val(__x._M_val);
512*b1e83836Smrg	else
513*b1e83836Smrg	  this->_M_assign_unex(__x._M_unex);
514*b1e83836Smrg	return *this;
515*b1e83836Smrg      }
516*b1e83836Smrg
517*b1e83836Smrg      constexpr expected&
518*b1e83836Smrg      operator=(expected&& __x)
519*b1e83836Smrg      noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
520*b1e83836Smrg		       is_nothrow_move_constructible<_Er>,
521*b1e83836Smrg		       is_nothrow_move_assignable<_Tp>,
522*b1e83836Smrg		       is_nothrow_move_assignable<_Er>>)
523*b1e83836Smrg      requires is_move_assignable_v<_Tp> && is_move_constructible_v<_Tp>
524*b1e83836Smrg	    && is_move_assignable_v<_Er> && is_move_constructible_v<_Er>
525*b1e83836Smrg	    && (is_nothrow_move_constructible_v<_Tp>
526*b1e83836Smrg		|| is_nothrow_move_constructible_v<_Er>)
527*b1e83836Smrg      {
528*b1e83836Smrg	if (__x._M_has_value)
529*b1e83836Smrg	  _M_assign_val(std::move(__x._M_val));
530*b1e83836Smrg	else
531*b1e83836Smrg	  _M_assign_unex(std::move(__x._M_unex));
532*b1e83836Smrg	return *this;
533*b1e83836Smrg      }
534*b1e83836Smrg
535*b1e83836Smrg      template<typename _Up = _Tp>
536*b1e83836Smrg	requires (!is_same_v<expected, remove_cvref_t<_Up>>)
537*b1e83836Smrg	      && (!__expected::__is_unexpected<remove_cvref_t<_Up>>)
538*b1e83836Smrg	      && is_constructible_v<_Tp, _Up> && is_assignable_v<_Tp&, _Up>
539*b1e83836Smrg	      && (is_nothrow_constructible_v<_Tp, _Up>
540*b1e83836Smrg		  || is_nothrow_move_constructible_v<_Tp>
541*b1e83836Smrg		  || is_nothrow_move_constructible_v<_Er>)
542*b1e83836Smrg	constexpr expected&
543*b1e83836Smrg	operator=(_Up&& __v)
544*b1e83836Smrg	{
545*b1e83836Smrg	  _M_assign_val(std::forward<_Up>(__v));
546*b1e83836Smrg	  return *this;
547*b1e83836Smrg	}
548*b1e83836Smrg
549*b1e83836Smrg      template<typename _Gr>
550*b1e83836Smrg	requires is_constructible_v<_Er, const _Gr&>
551*b1e83836Smrg	      && is_assignable_v<_Er&, const _Gr&>
552*b1e83836Smrg	      && (is_nothrow_constructible_v<_Er, const _Gr&>
553*b1e83836Smrg		  || is_nothrow_move_constructible_v<_Tp>
554*b1e83836Smrg		  || is_nothrow_move_constructible_v<_Er>)
555*b1e83836Smrg	constexpr expected&
556*b1e83836Smrg	operator=(const unexpected<_Gr>& __e)
557*b1e83836Smrg	{
558*b1e83836Smrg	  _M_assign_unex(__e.error());
559*b1e83836Smrg	  return *this;
560*b1e83836Smrg	}
561*b1e83836Smrg
562*b1e83836Smrg      template<typename _Gr>
563*b1e83836Smrg	requires is_constructible_v<_Er, _Gr>
564*b1e83836Smrg	      && is_assignable_v<_Er&, _Gr>
565*b1e83836Smrg	      && (is_nothrow_constructible_v<_Er, _Gr>
566*b1e83836Smrg		  || is_nothrow_move_constructible_v<_Tp>
567*b1e83836Smrg		  || is_nothrow_move_constructible_v<_Er>)
568*b1e83836Smrg	constexpr expected&
569*b1e83836Smrg	operator=(unexpected<_Gr>&& __e)
570*b1e83836Smrg	{
571*b1e83836Smrg	  _M_assign_unex(std::move(__e).error());
572*b1e83836Smrg	  return *this;
573*b1e83836Smrg	}
574*b1e83836Smrg
575*b1e83836Smrg      // modifiers
576*b1e83836Smrg
577*b1e83836Smrg      template<typename... _Args>
578*b1e83836Smrg	requires is_nothrow_constructible_v<_Tp, _Args...>
579*b1e83836Smrg	constexpr _Tp&
580*b1e83836Smrg	emplace(_Args&&... __args) noexcept
581*b1e83836Smrg	{
582*b1e83836Smrg	  if (_M_has_value)
583*b1e83836Smrg	    std::destroy_at(__builtin_addressof(_M_val));
584*b1e83836Smrg	  else
585*b1e83836Smrg	    {
586*b1e83836Smrg	      std::destroy_at(__builtin_addressof(_M_unex));
587*b1e83836Smrg	      _M_has_value = true;
588*b1e83836Smrg	    }
589*b1e83836Smrg	  std::construct_at(__builtin_addressof(_M_val),
590*b1e83836Smrg			    std::forward<_Args>(__args)...);
591*b1e83836Smrg	  return _M_val;
592*b1e83836Smrg	}
593*b1e83836Smrg
594*b1e83836Smrg      template<typename _Up, typename... _Args>
595*b1e83836Smrg	requires is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
596*b1e83836Smrg					    _Args...>
597*b1e83836Smrg	constexpr _Tp&
598*b1e83836Smrg	emplace(initializer_list<_Up> __il, _Args&&... __args) noexcept
599*b1e83836Smrg	{
600*b1e83836Smrg	  if (_M_has_value)
601*b1e83836Smrg	    std::destroy_at(__builtin_addressof(_M_val));
602*b1e83836Smrg	  else
603*b1e83836Smrg	    {
604*b1e83836Smrg	      std::destroy_at(__builtin_addressof(_M_unex));
605*b1e83836Smrg	      _M_has_value = true;
606*b1e83836Smrg	    }
607*b1e83836Smrg	  std::construct_at(__builtin_addressof(_M_val),
608*b1e83836Smrg			    __il, std::forward<_Args>(__args)...);
609*b1e83836Smrg	  return _M_val;
610*b1e83836Smrg	}
611*b1e83836Smrg
612*b1e83836Smrg      // swap
613*b1e83836Smrg      constexpr void
614*b1e83836Smrg      swap(expected& __x)
615*b1e83836Smrg      noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
616*b1e83836Smrg		       is_nothrow_move_constructible<_Er>,
617*b1e83836Smrg		       is_nothrow_swappable<_Tp&>,
618*b1e83836Smrg		       is_nothrow_swappable<_Er&>>)
619*b1e83836Smrg      requires is_swappable_v<_Tp> && is_swappable_v<_Er>
620*b1e83836Smrg	    && is_move_constructible_v<_Tp>
621*b1e83836Smrg	    && is_move_constructible_v<_Er>
622*b1e83836Smrg	    && (is_nothrow_move_constructible_v<_Tp>
623*b1e83836Smrg		|| is_nothrow_move_constructible_v<_Er>)
624*b1e83836Smrg      {
625*b1e83836Smrg	if (_M_has_value)
626*b1e83836Smrg	  {
627*b1e83836Smrg	    if (__x._M_has_value)
628*b1e83836Smrg	      {
629*b1e83836Smrg		using std::swap;
630*b1e83836Smrg		swap(_M_val, __x._M_val);
631*b1e83836Smrg	      }
632*b1e83836Smrg	    else
633*b1e83836Smrg	      this->_M_swap_val_unex(__x);
634*b1e83836Smrg	  }
635*b1e83836Smrg	else
636*b1e83836Smrg	  {
637*b1e83836Smrg	    if (__x._M_has_value)
638*b1e83836Smrg	      __x._M_swap_val_unex(*this);
639*b1e83836Smrg	    else
640*b1e83836Smrg	      {
641*b1e83836Smrg		using std::swap;
642*b1e83836Smrg		swap(_M_unex, __x._M_unex);
643*b1e83836Smrg	      }
644*b1e83836Smrg	  }
645*b1e83836Smrg      }
646*b1e83836Smrg
647*b1e83836Smrg      // observers
648*b1e83836Smrg
649*b1e83836Smrg      [[nodiscard]]
650*b1e83836Smrg      constexpr const _Tp*
651*b1e83836Smrg      operator->() const noexcept
652*b1e83836Smrg      {
653*b1e83836Smrg	__glibcxx_assert(_M_has_value);
654*b1e83836Smrg	return __builtin_addressof(_M_val);
655*b1e83836Smrg      }
656*b1e83836Smrg
657*b1e83836Smrg      [[nodiscard]]
658*b1e83836Smrg      constexpr _Tp*
659*b1e83836Smrg      operator->() noexcept
660*b1e83836Smrg      {
661*b1e83836Smrg	__glibcxx_assert(_M_has_value);
662*b1e83836Smrg	return __builtin_addressof(_M_val);
663*b1e83836Smrg      }
664*b1e83836Smrg
665*b1e83836Smrg      [[nodiscard]]
666*b1e83836Smrg      constexpr const _Tp&
667*b1e83836Smrg      operator*() const & noexcept
668*b1e83836Smrg      {
669*b1e83836Smrg	__glibcxx_assert(_M_has_value);
670*b1e83836Smrg	return _M_val;
671*b1e83836Smrg      }
672*b1e83836Smrg
673*b1e83836Smrg      [[nodiscard]]
674*b1e83836Smrg      constexpr _Tp&
675*b1e83836Smrg      operator*() & noexcept
676*b1e83836Smrg      {
677*b1e83836Smrg	__glibcxx_assert(_M_has_value);
678*b1e83836Smrg	return _M_val;
679*b1e83836Smrg      }
680*b1e83836Smrg
681*b1e83836Smrg      [[nodiscard]]
682*b1e83836Smrg      constexpr const _Tp&&
683*b1e83836Smrg      operator*() const && noexcept
684*b1e83836Smrg      {
685*b1e83836Smrg	__glibcxx_assert(_M_has_value);
686*b1e83836Smrg	return std::move(_M_val);
687*b1e83836Smrg      }
688*b1e83836Smrg
689*b1e83836Smrg      [[nodiscard]]
690*b1e83836Smrg      constexpr _Tp&&
691*b1e83836Smrg      operator*() && noexcept
692*b1e83836Smrg      {
693*b1e83836Smrg	__glibcxx_assert(_M_has_value);
694*b1e83836Smrg	return std::move(_M_val);
695*b1e83836Smrg      }
696*b1e83836Smrg
697*b1e83836Smrg      [[nodiscard]]
698*b1e83836Smrg      constexpr explicit
699*b1e83836Smrg      operator bool() const noexcept { return _M_has_value; }
700*b1e83836Smrg
701*b1e83836Smrg      [[nodiscard]]
702*b1e83836Smrg      constexpr bool has_value() const noexcept { return _M_has_value; }
703*b1e83836Smrg
704*b1e83836Smrg      constexpr const _Tp&
705*b1e83836Smrg      value() const &
706*b1e83836Smrg      {
707*b1e83836Smrg	if (_M_has_value) [[likely]]
708*b1e83836Smrg	  return _M_val;
709*b1e83836Smrg	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex));
710*b1e83836Smrg      }
711*b1e83836Smrg
712*b1e83836Smrg      constexpr _Tp&
713*b1e83836Smrg      value() &
714*b1e83836Smrg      {
715*b1e83836Smrg	if (_M_has_value) [[likely]]
716*b1e83836Smrg	  return _M_val;
717*b1e83836Smrg	const auto& __unex = _M_unex;
718*b1e83836Smrg	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(__unex));
719*b1e83836Smrg      }
720*b1e83836Smrg
721*b1e83836Smrg      constexpr const _Tp&&
722*b1e83836Smrg      value() const &&
723*b1e83836Smrg      {
724*b1e83836Smrg	if (_M_has_value) [[likely]]
725*b1e83836Smrg	  return std::move(_M_val);
726*b1e83836Smrg	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(
727*b1e83836Smrg				  std::move(_M_unex)));
728*b1e83836Smrg      }
729*b1e83836Smrg
730*b1e83836Smrg      constexpr _Tp&&
731*b1e83836Smrg      value() &&
732*b1e83836Smrg      {
733*b1e83836Smrg	if (_M_has_value) [[likely]]
734*b1e83836Smrg	  return std::move(_M_val);
735*b1e83836Smrg	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(
736*b1e83836Smrg				  std::move(_M_unex)));
737*b1e83836Smrg      }
738*b1e83836Smrg
739*b1e83836Smrg      constexpr const _Er&
740*b1e83836Smrg      error() const & noexcept
741*b1e83836Smrg      {
742*b1e83836Smrg	__glibcxx_assert(!_M_has_value);
743*b1e83836Smrg	return _M_unex;
744*b1e83836Smrg      }
745*b1e83836Smrg
746*b1e83836Smrg      constexpr _Er&
747*b1e83836Smrg      error() & noexcept
748*b1e83836Smrg      {
749*b1e83836Smrg	__glibcxx_assert(!_M_has_value);
750*b1e83836Smrg	return _M_unex;
751*b1e83836Smrg      }
752*b1e83836Smrg
753*b1e83836Smrg      constexpr const _Er&&
754*b1e83836Smrg      error() const && noexcept
755*b1e83836Smrg      {
756*b1e83836Smrg	__glibcxx_assert(!_M_has_value);
757*b1e83836Smrg	return std::move(_M_unex);
758*b1e83836Smrg      }
759*b1e83836Smrg
760*b1e83836Smrg      constexpr _Er&&
761*b1e83836Smrg      error() && noexcept
762*b1e83836Smrg      {
763*b1e83836Smrg	__glibcxx_assert(!_M_has_value);
764*b1e83836Smrg	return std::move(_M_unex);
765*b1e83836Smrg      }
766*b1e83836Smrg
767*b1e83836Smrg      template<typename _Up>
768*b1e83836Smrg	constexpr _Tp
769*b1e83836Smrg	value_or(_Up&& __v) const &
770*b1e83836Smrg	noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
771*b1e83836Smrg			 is_nothrow_convertible<_Up, _Tp>>)
772*b1e83836Smrg	{
773*b1e83836Smrg	  static_assert( is_copy_constructible_v<_Tp> );
774*b1e83836Smrg	  static_assert( is_convertible_v<_Up, _Tp> );
775*b1e83836Smrg
776*b1e83836Smrg	  if (_M_has_value)
777*b1e83836Smrg	    return _M_val;
778*b1e83836Smrg	  return static_cast<_Tp>(std::forward<_Up>(__v));
779*b1e83836Smrg	}
780*b1e83836Smrg
781*b1e83836Smrg      template<typename _Up>
782*b1e83836Smrg	constexpr _Tp
783*b1e83836Smrg	value_or(_Up&& __v) &&
784*b1e83836Smrg	noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
785*b1e83836Smrg			 is_nothrow_convertible<_Up, _Tp>>)
786*b1e83836Smrg	{
787*b1e83836Smrg	  static_assert( is_move_constructible_v<_Tp> );
788*b1e83836Smrg	  static_assert( is_convertible_v<_Up, _Tp> );
789*b1e83836Smrg
790*b1e83836Smrg	  if (_M_has_value)
791*b1e83836Smrg	    return std::move(_M_val);
792*b1e83836Smrg	  return static_cast<_Tp>(std::forward<_Up>(__v));
793*b1e83836Smrg	}
794*b1e83836Smrg
795*b1e83836Smrg      // equality operators
796*b1e83836Smrg
797*b1e83836Smrg      template<typename _Up, typename _Er2>
798*b1e83836Smrg	requires (!is_void_v<_Up>)
799*b1e83836Smrg	friend constexpr bool
800*b1e83836Smrg	operator==(const expected& __x, const expected<_Up, _Er2>& __y)
801*b1e83836Smrg	// FIXME: noexcept(noexcept(bool(*__x == *__y))
802*b1e83836Smrg		  // && noexcept(bool(__x.error() == __y.error())))
803*b1e83836Smrg	{
804*b1e83836Smrg	  if (__x.has_value())
805*b1e83836Smrg	    return __y.has_value() && bool(*__x == *__y);
806*b1e83836Smrg	  else
807*b1e83836Smrg	    return !__y.has_value() && bool(__x.error() == __y.error());
808*b1e83836Smrg	}
809*b1e83836Smrg
810*b1e83836Smrg      template<typename _Up>
811*b1e83836Smrg	friend constexpr bool
812*b1e83836Smrg	operator==(const expected& __x, const _Up& __v)
813*b1e83836Smrg	// FIXME: noexcept(noexcept(bool(*__x == __v)))
814*b1e83836Smrg	{ return __x.has_value() && bool(*__x == __v); }
815*b1e83836Smrg
816*b1e83836Smrg      template<typename _Er2>
817*b1e83836Smrg	friend constexpr bool
818*b1e83836Smrg	operator==(const expected& __x, const unexpected<_Er2>& __e)
819*b1e83836Smrg	// FIXME: noexcept(noexcept(bool(__x.error() == __e.error())))
820*b1e83836Smrg	{ return !__x.has_value() && bool(__x.error() == __e.error()); }
821*b1e83836Smrg
822*b1e83836Smrg      friend constexpr void
823*b1e83836Smrg      swap(expected& __x, expected& __y)
824*b1e83836Smrg      noexcept(noexcept(__x.swap(__y)))
825*b1e83836Smrg      requires requires {__x.swap(__y);}
826*b1e83836Smrg      { __x.swap(__y); }
827*b1e83836Smrg
828*b1e83836Smrg    private:
829*b1e83836Smrg      template<typename, typename> friend class expected;
830*b1e83836Smrg
831*b1e83836Smrg      template<typename _Vp>
832*b1e83836Smrg	constexpr void
833*b1e83836Smrg	_M_assign_val(_Vp&& __v)
834*b1e83836Smrg	{
835*b1e83836Smrg	  if (_M_has_value)
836*b1e83836Smrg	    _M_val = std::forward<_Vp>(__v);
837*b1e83836Smrg	  else
838*b1e83836Smrg	    {
839*b1e83836Smrg	      __expected::__reinit(__builtin_addressof(_M_val),
840*b1e83836Smrg				   __builtin_addressof(_M_unex),
841*b1e83836Smrg				   std::forward<_Vp>(__v));
842*b1e83836Smrg	      _M_has_value = true;
843*b1e83836Smrg	    }
844*b1e83836Smrg	}
845*b1e83836Smrg
846*b1e83836Smrg      template<typename _Vp>
847*b1e83836Smrg	constexpr void
848*b1e83836Smrg	_M_assign_unex(_Vp&& __v)
849*b1e83836Smrg	{
850*b1e83836Smrg	  if (_M_has_value)
851*b1e83836Smrg	    {
852*b1e83836Smrg	      __expected::__reinit(__builtin_addressof(_M_unex),
853*b1e83836Smrg				   __builtin_addressof(_M_val),
854*b1e83836Smrg				   std::forward<_Vp>(__v));
855*b1e83836Smrg	      _M_has_value = false;
856*b1e83836Smrg	    }
857*b1e83836Smrg	  else
858*b1e83836Smrg	    _M_unex = std::forward<_Vp>(__v);
859*b1e83836Smrg	}
860*b1e83836Smrg
861*b1e83836Smrg      // Swap two expected objects when only one has a value.
862*b1e83836Smrg      // Precondition: this->_M_has_value && !__rhs._M_has_value
863*b1e83836Smrg      constexpr void
864*b1e83836Smrg      _M_swap_val_unex(expected& __rhs)
865*b1e83836Smrg      noexcept(__and_v<is_nothrow_move_constructible<_Er>,
866*b1e83836Smrg		       is_nothrow_move_constructible<_Tp>>)
867*b1e83836Smrg      {
868*b1e83836Smrg	if constexpr (is_nothrow_move_constructible_v<_Er>)
869*b1e83836Smrg	  {
870*b1e83836Smrg	    __expected::_Guard<_Er> __guard(__rhs._M_unex);
871*b1e83836Smrg	    std::construct_at(__builtin_addressof(__rhs._M_val),
872*b1e83836Smrg			      std::move(_M_val)); // might throw
873*b1e83836Smrg	    __rhs._M_has_value = true;
874*b1e83836Smrg	    std::destroy_at(__builtin_addressof(_M_val));
875*b1e83836Smrg	    std::construct_at(__builtin_addressof(_M_unex),
876*b1e83836Smrg			      __guard.release());
877*b1e83836Smrg	    _M_has_value = false;
878*b1e83836Smrg	  }
879*b1e83836Smrg	else
880*b1e83836Smrg	  {
881*b1e83836Smrg	    __expected::_Guard<_Tp> __guard(_M_val);
882*b1e83836Smrg	    std::construct_at(__builtin_addressof(_M_unex),
883*b1e83836Smrg			      std::move(__rhs._M_unex)); // might throw
884*b1e83836Smrg	    _M_has_value = false;
885*b1e83836Smrg	    std::destroy_at(__builtin_addressof(__rhs._M_unex));
886*b1e83836Smrg	    std::construct_at(__builtin_addressof(__rhs._M_val),
887*b1e83836Smrg			      __guard.release());
888*b1e83836Smrg	    __rhs._M_has_value = true;
889*b1e83836Smrg	  }
890*b1e83836Smrg      }
891*b1e83836Smrg
892*b1e83836Smrg      union {
893*b1e83836Smrg	_Tp _M_val;
894*b1e83836Smrg	_Er _M_unex;
895*b1e83836Smrg      };
896*b1e83836Smrg
897*b1e83836Smrg      bool _M_has_value;
898*b1e83836Smrg    };
899*b1e83836Smrg
900*b1e83836Smrg  // Partial specialization for std::expected<cv void, E>
901*b1e83836Smrg  template<typename _Tp, typename _Er> requires is_void_v<_Tp>
902*b1e83836Smrg    class expected<_Tp, _Er>
903*b1e83836Smrg    {
904*b1e83836Smrg      static_assert( __expected::__can_be_unexpected<_Er> );
905*b1e83836Smrg
906*b1e83836Smrg      template<typename _Up, typename _Err, typename _Unex = unexpected<_Er>>
907*b1e83836Smrg	static constexpr bool __cons_from_expected
908*b1e83836Smrg	  = __or_v<is_constructible<_Unex, expected<_Up, _Err>&>,
909*b1e83836Smrg		   is_constructible<_Unex, expected<_Up, _Err>>,
910*b1e83836Smrg		   is_constructible<_Unex, const expected<_Up, _Err>&>,
911*b1e83836Smrg		   is_constructible<_Unex, const expected<_Up, _Err>>
912*b1e83836Smrg		  >;
913*b1e83836Smrg
914*b1e83836Smrg    public:
915*b1e83836Smrg      using value_type = _Tp;
916*b1e83836Smrg      using error_type = _Er;
917*b1e83836Smrg      using unexpected_type = unexpected<_Er>;
918*b1e83836Smrg
919*b1e83836Smrg      template<typename _Up>
920*b1e83836Smrg	using rebind = expected<_Up, error_type>;
921*b1e83836Smrg
922*b1e83836Smrg      constexpr
923*b1e83836Smrg      expected() noexcept
924*b1e83836Smrg      : _M_void(), _M_has_value(true)
925*b1e83836Smrg      { }
926*b1e83836Smrg
927*b1e83836Smrg      expected(const expected&) = default;
928*b1e83836Smrg
929*b1e83836Smrg      constexpr
930*b1e83836Smrg      expected(const expected& __x)
931*b1e83836Smrg      noexcept(is_nothrow_copy_constructible_v<_Er>)
932*b1e83836Smrg      requires is_copy_constructible_v<_Er>
933*b1e83836Smrg	    && (!is_trivially_copy_constructible_v<_Er>)
934*b1e83836Smrg      : _M_void(), _M_has_value(__x._M_has_value)
935*b1e83836Smrg      {
936*b1e83836Smrg	if (!_M_has_value)
937*b1e83836Smrg	  std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
938*b1e83836Smrg      }
939*b1e83836Smrg
940*b1e83836Smrg      expected(expected&&) = default;
941*b1e83836Smrg
942*b1e83836Smrg      constexpr
943*b1e83836Smrg      expected(expected&& __x)
944*b1e83836Smrg      noexcept(is_nothrow_move_constructible_v<_Er>)
945*b1e83836Smrg      requires is_move_constructible_v<_Er>
946*b1e83836Smrg	    && (!is_trivially_move_constructible_v<_Er>)
947*b1e83836Smrg      : _M_void(), _M_has_value(__x._M_has_value)
948*b1e83836Smrg      {
949*b1e83836Smrg	if (!_M_has_value)
950*b1e83836Smrg	  std::construct_at(__builtin_addressof(_M_unex),
951*b1e83836Smrg			    std::move(__x)._M_unex);
952*b1e83836Smrg      }
953*b1e83836Smrg
954*b1e83836Smrg      template<typename _Up, typename _Gr>
955*b1e83836Smrg	requires is_void_v<_Up>
956*b1e83836Smrg	      && is_constructible_v<_Er, const _Gr&>
957*b1e83836Smrg	      && (!__cons_from_expected<_Up, _Gr>)
958*b1e83836Smrg	constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
959*b1e83836Smrg	expected(const expected<_Up, _Gr>& __x)
960*b1e83836Smrg	noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
961*b1e83836Smrg	: _M_void(), _M_has_value(__x._M_has_value)
962*b1e83836Smrg	{
963*b1e83836Smrg	  if (!_M_has_value)
964*b1e83836Smrg	    std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
965*b1e83836Smrg	}
966*b1e83836Smrg
967*b1e83836Smrg      template<typename _Up, typename _Gr>
968*b1e83836Smrg	requires is_void_v<_Up>
969*b1e83836Smrg	      && is_constructible_v<_Er, _Gr>
970*b1e83836Smrg	      && (!__cons_from_expected<_Up, _Gr>)
971*b1e83836Smrg	constexpr explicit(!is_convertible_v<_Gr, _Er>)
972*b1e83836Smrg	expected(expected<_Up, _Gr>&& __x)
973*b1e83836Smrg	noexcept(is_nothrow_constructible_v<_Er, _Gr>)
974*b1e83836Smrg	: _M_void(), _M_has_value(__x._M_has_value)
975*b1e83836Smrg	{
976*b1e83836Smrg	  if (!_M_has_value)
977*b1e83836Smrg	    std::construct_at(__builtin_addressof(_M_unex),
978*b1e83836Smrg			      std::move(__x)._M_unex);
979*b1e83836Smrg	}
980*b1e83836Smrg
981*b1e83836Smrg      template<typename _Gr = _Er>
982*b1e83836Smrg	requires is_constructible_v<_Er, const _Gr&>
983*b1e83836Smrg	constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
984*b1e83836Smrg	expected(const unexpected<_Gr>& __u)
985*b1e83836Smrg	noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
986*b1e83836Smrg	: _M_unex(__u.error()), _M_has_value(false)
987*b1e83836Smrg	{ }
988*b1e83836Smrg
989*b1e83836Smrg      template<typename _Gr = _Er>
990*b1e83836Smrg	requires is_constructible_v<_Er, _Gr>
991*b1e83836Smrg	constexpr explicit(!is_convertible_v<_Gr, _Er>)
992*b1e83836Smrg	expected(unexpected<_Gr>&& __u)
993*b1e83836Smrg	noexcept(is_nothrow_constructible_v<_Er, _Gr>)
994*b1e83836Smrg	: _M_unex(std::move(__u).error()), _M_has_value(false)
995*b1e83836Smrg	{ }
996*b1e83836Smrg
997*b1e83836Smrg      constexpr explicit
998*b1e83836Smrg      expected(in_place_t) noexcept
999*b1e83836Smrg      : expected()
1000*b1e83836Smrg      { }
1001*b1e83836Smrg
1002*b1e83836Smrg      template<typename... _Args>
1003*b1e83836Smrg	requires is_constructible_v<_Er, _Args...>
1004*b1e83836Smrg	constexpr explicit
1005*b1e83836Smrg	expected(unexpect_t, _Args&&... __args)
1006*b1e83836Smrg	noexcept(is_nothrow_constructible_v<_Er, _Args...>)
1007*b1e83836Smrg	: _M_unex(std::forward<_Args>(__args)...), _M_has_value(false)
1008*b1e83836Smrg	{ }
1009*b1e83836Smrg
1010*b1e83836Smrg      template<typename _Up, typename... _Args>
1011*b1e83836Smrg	requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
1012*b1e83836Smrg	constexpr explicit
1013*b1e83836Smrg	expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
1014*b1e83836Smrg	noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
1015*b1e83836Smrg					    _Args...>)
1016*b1e83836Smrg	: _M_unex(__il, std::forward<_Args>(__args)...), _M_has_value(false)
1017*b1e83836Smrg	{ }
1018*b1e83836Smrg
1019*b1e83836Smrg      constexpr ~expected() = default;
1020*b1e83836Smrg
1021*b1e83836Smrg      constexpr ~expected() requires (!is_trivially_destructible_v<_Er>)
1022*b1e83836Smrg      {
1023*b1e83836Smrg	if (!_M_has_value)
1024*b1e83836Smrg	  std::destroy_at(__builtin_addressof(_M_unex));
1025*b1e83836Smrg      }
1026*b1e83836Smrg
1027*b1e83836Smrg      // assignment
1028*b1e83836Smrg
1029*b1e83836Smrg      expected& operator=(const expected&) = delete;
1030*b1e83836Smrg
1031*b1e83836Smrg      constexpr expected&
1032*b1e83836Smrg      operator=(const expected& __x)
1033*b1e83836Smrg      noexcept(__and_v<is_nothrow_copy_constructible<_Er>,
1034*b1e83836Smrg		       is_nothrow_copy_assignable<_Er>>)
1035*b1e83836Smrg      requires is_copy_constructible_v<_Er>
1036*b1e83836Smrg	    && is_copy_assignable_v<_Er>
1037*b1e83836Smrg      {
1038*b1e83836Smrg	if (__x._M_has_value)
1039*b1e83836Smrg	  emplace();
1040*b1e83836Smrg	else
1041*b1e83836Smrg	  _M_assign_unex(__x._M_unex);
1042*b1e83836Smrg	return *this;
1043*b1e83836Smrg      }
1044*b1e83836Smrg
1045*b1e83836Smrg      constexpr expected&
1046*b1e83836Smrg      operator=(expected&& __x)
1047*b1e83836Smrg      noexcept(__and_v<is_nothrow_move_constructible<_Er>,
1048*b1e83836Smrg		       is_nothrow_move_assignable<_Er>>)
1049*b1e83836Smrg      requires is_move_constructible_v<_Er>
1050*b1e83836Smrg	    && is_move_assignable_v<_Er>
1051*b1e83836Smrg      {
1052*b1e83836Smrg	if (__x._M_has_value)
1053*b1e83836Smrg	  emplace();
1054*b1e83836Smrg	else
1055*b1e83836Smrg	  _M_assign_unex(std::move(__x._M_unex));
1056*b1e83836Smrg	return *this;
1057*b1e83836Smrg      }
1058*b1e83836Smrg
1059*b1e83836Smrg      template<typename _Gr>
1060*b1e83836Smrg	requires is_constructible_v<_Er, const _Gr&>
1061*b1e83836Smrg	      && is_assignable_v<_Er&, const _Gr&>
1062*b1e83836Smrg	constexpr expected&
1063*b1e83836Smrg	operator=(const unexpected<_Gr>& __e)
1064*b1e83836Smrg	{
1065*b1e83836Smrg	  _M_assign_unex(__e.error());
1066*b1e83836Smrg	  return *this;
1067*b1e83836Smrg	}
1068*b1e83836Smrg
1069*b1e83836Smrg      template<typename _Gr>
1070*b1e83836Smrg	requires is_constructible_v<_Er, _Gr>
1071*b1e83836Smrg	      && is_assignable_v<_Er&, _Gr>
1072*b1e83836Smrg	constexpr expected&
1073*b1e83836Smrg	operator=(unexpected<_Gr>&& __e)
1074*b1e83836Smrg	{
1075*b1e83836Smrg	  _M_assign_unex(std::move(__e.error()));
1076*b1e83836Smrg	  return *this;
1077*b1e83836Smrg	}
1078*b1e83836Smrg
1079*b1e83836Smrg      // modifiers
1080*b1e83836Smrg
1081*b1e83836Smrg      constexpr void
1082*b1e83836Smrg      emplace() noexcept
1083*b1e83836Smrg      {
1084*b1e83836Smrg	if (!_M_has_value)
1085*b1e83836Smrg	  {
1086*b1e83836Smrg	    std::destroy_at(__builtin_addressof(_M_unex));
1087*b1e83836Smrg	    _M_has_value = true;
1088*b1e83836Smrg	  }
1089*b1e83836Smrg      }
1090*b1e83836Smrg
1091*b1e83836Smrg      // swap
1092*b1e83836Smrg      constexpr void
1093*b1e83836Smrg      swap(expected& __x)
1094*b1e83836Smrg      noexcept(__and_v<is_nothrow_swappable<_Er&>,
1095*b1e83836Smrg		       is_nothrow_move_constructible<_Er>>)
1096*b1e83836Smrg      requires is_swappable_v<_Er> && is_move_constructible_v<_Er>
1097*b1e83836Smrg      {
1098*b1e83836Smrg	if (_M_has_value)
1099*b1e83836Smrg	  {
1100*b1e83836Smrg	    if (!__x._M_has_value)
1101*b1e83836Smrg	      {
1102*b1e83836Smrg		std::construct_at(__builtin_addressof(_M_unex),
1103*b1e83836Smrg				  std::move(__x._M_unex)); // might throw
1104*b1e83836Smrg		std::destroy_at(__builtin_addressof(__x._M_unex));
1105*b1e83836Smrg		_M_has_value = false;
1106*b1e83836Smrg		__x._M_has_value = true;
1107*b1e83836Smrg	      }
1108*b1e83836Smrg	  }
1109*b1e83836Smrg	else
1110*b1e83836Smrg	  {
1111*b1e83836Smrg	    if (__x._M_has_value)
1112*b1e83836Smrg	      {
1113*b1e83836Smrg		std::construct_at(__builtin_addressof(__x._M_unex),
1114*b1e83836Smrg				  std::move(_M_unex)); // might throw
1115*b1e83836Smrg		std::destroy_at(__builtin_addressof(_M_unex));
1116*b1e83836Smrg		_M_has_value = true;
1117*b1e83836Smrg		__x._M_has_value = false;
1118*b1e83836Smrg	      }
1119*b1e83836Smrg	    else
1120*b1e83836Smrg	      {
1121*b1e83836Smrg		using std::swap;
1122*b1e83836Smrg		swap(_M_unex, __x._M_unex);
1123*b1e83836Smrg	      }
1124*b1e83836Smrg	  }
1125*b1e83836Smrg      }
1126*b1e83836Smrg
1127*b1e83836Smrg      // observers
1128*b1e83836Smrg
1129*b1e83836Smrg      [[nodiscard]]
1130*b1e83836Smrg      constexpr explicit
1131*b1e83836Smrg      operator bool() const noexcept { return _M_has_value; }
1132*b1e83836Smrg
1133*b1e83836Smrg      [[nodiscard]]
1134*b1e83836Smrg      constexpr bool has_value() const noexcept { return _M_has_value; }
1135*b1e83836Smrg
1136*b1e83836Smrg      constexpr void
1137*b1e83836Smrg      operator*() const noexcept { __glibcxx_assert(_M_has_value); }
1138*b1e83836Smrg
1139*b1e83836Smrg      constexpr void
1140*b1e83836Smrg      value() const&
1141*b1e83836Smrg      {
1142*b1e83836Smrg	if (_M_has_value) [[likely]]
1143*b1e83836Smrg	  return;
1144*b1e83836Smrg	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex));
1145*b1e83836Smrg      }
1146*b1e83836Smrg
1147*b1e83836Smrg      constexpr void
1148*b1e83836Smrg      value() &&
1149*b1e83836Smrg      {
1150*b1e83836Smrg	if (_M_has_value) [[likely]]
1151*b1e83836Smrg	  return;
1152*b1e83836Smrg	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex)));
1153*b1e83836Smrg      }
1154*b1e83836Smrg
1155*b1e83836Smrg      constexpr const _Er&
1156*b1e83836Smrg      error() const & noexcept
1157*b1e83836Smrg      {
1158*b1e83836Smrg	__glibcxx_assert(!_M_has_value);
1159*b1e83836Smrg	return _M_unex;
1160*b1e83836Smrg      }
1161*b1e83836Smrg
1162*b1e83836Smrg      constexpr _Er&
1163*b1e83836Smrg      error() & noexcept
1164*b1e83836Smrg      {
1165*b1e83836Smrg	__glibcxx_assert(!_M_has_value);
1166*b1e83836Smrg	return _M_unex;
1167*b1e83836Smrg      }
1168*b1e83836Smrg
1169*b1e83836Smrg      constexpr const _Er&&
1170*b1e83836Smrg      error() const && noexcept
1171*b1e83836Smrg      {
1172*b1e83836Smrg	__glibcxx_assert(!_M_has_value);
1173*b1e83836Smrg	return std::move(_M_unex);
1174*b1e83836Smrg      }
1175*b1e83836Smrg
1176*b1e83836Smrg      constexpr _Er&&
1177*b1e83836Smrg      error() && noexcept
1178*b1e83836Smrg      {
1179*b1e83836Smrg	__glibcxx_assert(!_M_has_value);
1180*b1e83836Smrg	return std::move(_M_unex);
1181*b1e83836Smrg      }
1182*b1e83836Smrg
1183*b1e83836Smrg      // equality operators
1184*b1e83836Smrg
1185*b1e83836Smrg      template<typename _Up, typename _Er2>
1186*b1e83836Smrg	requires is_void_v<_Up>
1187*b1e83836Smrg	friend constexpr bool
1188*b1e83836Smrg	operator==(const expected& __x, const expected<_Up, _Er2>& __y)
1189*b1e83836Smrg	// FIXME: noexcept(noexcept(bool(__x.error() == __y.error())))
1190*b1e83836Smrg	{
1191*b1e83836Smrg	  if (__x.has_value())
1192*b1e83836Smrg	    return __y.has_value();
1193*b1e83836Smrg	  else
1194*b1e83836Smrg	    return !__y.has_value() && bool(__x.error() == __y.error());
1195*b1e83836Smrg	}
1196*b1e83836Smrg
1197*b1e83836Smrg      template<typename _Er2>
1198*b1e83836Smrg	friend constexpr bool
1199*b1e83836Smrg	operator==(const expected& __x, const unexpected<_Er2>& __e)
1200*b1e83836Smrg	// FIXME: noexcept(noexcept(bool(__x.error() == __e.error())))
1201*b1e83836Smrg	{ return !__x.has_value() && bool(__x.error() == __e.error()); }
1202*b1e83836Smrg
1203*b1e83836Smrg      friend constexpr void
1204*b1e83836Smrg      swap(expected& __x, expected& __y)
1205*b1e83836Smrg      noexcept(noexcept(__x.swap(__y)))
1206*b1e83836Smrg      requires requires { __x.swap(__y); }
1207*b1e83836Smrg      { __x.swap(__y); }
1208*b1e83836Smrg
1209*b1e83836Smrg    private:
1210*b1e83836Smrg      template<typename, typename> friend class expected;
1211*b1e83836Smrg
1212*b1e83836Smrg      template<typename _Vp>
1213*b1e83836Smrg	constexpr void
1214*b1e83836Smrg	_M_assign_unex(_Vp&& __v)
1215*b1e83836Smrg	{
1216*b1e83836Smrg	  if (_M_has_value)
1217*b1e83836Smrg	    {
1218*b1e83836Smrg	      std::construct_at(__builtin_addressof(_M_unex),
1219*b1e83836Smrg				std::forward<_Vp>(__v));
1220*b1e83836Smrg	      _M_has_value = false;
1221*b1e83836Smrg	    }
1222*b1e83836Smrg	  else
1223*b1e83836Smrg	    _M_unex = std::forward<_Vp>(__v);
1224*b1e83836Smrg	}
1225*b1e83836Smrg
1226*b1e83836Smrg
1227*b1e83836Smrg      union {
1228*b1e83836Smrg	struct { } _M_void;
1229*b1e83836Smrg	_Er _M_unex;
1230*b1e83836Smrg      };
1231*b1e83836Smrg
1232*b1e83836Smrg      bool _M_has_value;
1233*b1e83836Smrg    };
1234*b1e83836Smrg  /// @}
1235*b1e83836Smrg
1236*b1e83836Smrg_GLIBCXX_END_NAMESPACE_VERSION
1237*b1e83836Smrg} // namespace std
1238*b1e83836Smrg
1239*b1e83836Smrg#endif // C++23
1240*b1e83836Smrg#endif // _GLIBCXX_EXPECTED
1241