libstdc++
expected
Go to the documentation of this file.
1 // <expected> -*- C++ -*-
2 
3 // Copyright The GNU Toolchain Authors.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /** @file include/expected
26  * This is a Standard C++ Library header.
27  */
28 
29 #ifndef _GLIBCXX_EXPECTED
30 #define _GLIBCXX_EXPECTED
31 
32 #pragma GCC system_header
33 
34 #define __glibcxx_want_expected
35 #define __glibcxx_want_freestanding_expected
36 #include <bits/version.h>
37 
38 #ifdef __cpp_lib_expected // C++ >= 23 && __cpp_concepts >= 202002L
39 #include <initializer_list>
40 #include <bits/exception.h> // exception
41 #include <bits/invoke.h> // __invoke
42 #include <bits/stl_construct.h> // construct_at
43 #include <bits/utility.h> // in_place_t
44 
45 namespace std _GLIBCXX_VISIBILITY(default)
46 {
47 _GLIBCXX_BEGIN_NAMESPACE_VERSION
48 
49  /**
50  * @defgroup expected_values Expected values
51  * @addtogroup utilities
52  * @since C++23
53  * @{
54  */
55 
56  /// Discriminated union that holds an expected value or an error value.
57  /**
58  * @since C++23
59  */
60  template<typename _Tp, typename _Er>
61  class expected;
62 
63  /// Wrapper type used to pass an error value to a `std::expected`.
64  /**
65  * @since C++23
66  */
67  template<typename _Er>
68  class unexpected;
69 
70  /// Exception thrown by std::expected when the value() is not present.
71  /**
72  * @since C++23
73  */
74  template<typename _Er>
75  class bad_expected_access;
76 
77  template<>
78  class bad_expected_access<void> : public exception
79  {
80  protected:
81  bad_expected_access() noexcept { }
82  bad_expected_access(const bad_expected_access&) = default;
83  bad_expected_access(bad_expected_access&&) = default;
84  bad_expected_access& operator=(const bad_expected_access&) = default;
85  bad_expected_access& operator=(bad_expected_access&&) = default;
86  ~bad_expected_access() = default;
87 
88  public:
89 
90  [[nodiscard]]
91  const char*
92  what() const noexcept override
93  { return "bad access to std::expected without expected value"; }
94  };
95 
96  template<typename _Er>
97  class bad_expected_access : public bad_expected_access<void> {
98  public:
99  explicit
100  bad_expected_access(_Er __e) : _M_unex(std::move(__e)) { }
101 
102  // XXX const char* what() const noexcept override;
103 
104  [[nodiscard]]
105  _Er&
106  error() & noexcept
107  { return _M_unex; }
108 
109  [[nodiscard]]
110  const _Er&
111  error() const & noexcept
112  { return _M_unex; }
113 
114  [[nodiscard]]
115  _Er&&
116  error() && noexcept
117  { return std::move(_M_unex); }
118 
119  [[nodiscard]]
120  const _Er&&
121  error() const && noexcept
122  { return std::move(_M_unex); }
123 
124  private:
125  _Er _M_unex;
126  };
127 
128  /// Tag type for constructing unexpected values in a std::expected
129  /**
130  * @since C++23
131  */
132  struct unexpect_t
133  {
134  explicit unexpect_t() = default;
135  };
136 
137  /// Tag for constructing unexpected values in a std::expected
138  /**
139  * @since C++23
140  */
141  inline constexpr unexpect_t unexpect{};
142 
143 /// @cond undocumented
144 namespace __expected
145 {
146  template<typename _Tp>
147  constexpr bool __is_expected = false;
148  template<typename _Tp, typename _Er>
149  constexpr bool __is_expected<expected<_Tp, _Er>> = true;
150 
151  template<typename _Tp>
152  constexpr bool __is_unexpected = false;
153  template<typename _Tp>
154  constexpr bool __is_unexpected<unexpected<_Tp>> = true;
155 
156  template<typename _Fn, typename _Tp>
157  using __result = remove_cvref_t<invoke_result_t<_Fn&&, _Tp&&>>;
158  template<typename _Fn, typename _Tp>
159  using __result_xform = remove_cv_t<invoke_result_t<_Fn&&, _Tp&&>>;
160  template<typename _Fn>
161  using __result0 = remove_cvref_t<invoke_result_t<_Fn&&>>;
162  template<typename _Fn>
163  using __result0_xform = remove_cv_t<invoke_result_t<_Fn&&>>;
164 
165  template<typename _Er>
166  concept __can_be_unexpected
167  = is_object_v<_Er> && (!is_array_v<_Er>)
168  && (!__expected::__is_unexpected<_Er>)
169  && (!is_const_v<_Er>) && (!is_volatile_v<_Er>);
170 
171  // Tag types for in-place construction from an invocation result.
172  struct __in_place_inv { };
173  struct __unexpect_inv { };
174 }
175 /// @endcond
176 
177  template<typename _Er>
178  class unexpected
179  {
180  static_assert( __expected::__can_be_unexpected<_Er> );
181 
182  public:
183  constexpr unexpected(const unexpected&) = default;
184  constexpr unexpected(unexpected&&) = default;
185 
186  template<typename _Err = _Er>
187  requires (!is_same_v<remove_cvref_t<_Err>, unexpected>)
188  && (!is_same_v<remove_cvref_t<_Err>, in_place_t>)
189  && is_constructible_v<_Er, _Err>
190  constexpr explicit
191  unexpected(_Err&& __e)
192  noexcept(is_nothrow_constructible_v<_Er, _Err>)
193  : _M_unex(std::forward<_Err>(__e))
194  { }
195 
196  template<typename... _Args>
197  requires is_constructible_v<_Er, _Args...>
198  constexpr explicit
199  unexpected(in_place_t, _Args&&... __args)
200  noexcept(is_nothrow_constructible_v<_Er, _Args...>)
201  : _M_unex(std::forward<_Args>(__args)...)
202  { }
203 
204  template<typename _Up, typename... _Args>
205  requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
206  constexpr explicit
207  unexpected(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
208  noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
209  _Args...>)
210  : _M_unex(__il, std::forward<_Args>(__args)...)
211  { }
212 
213  constexpr unexpected& operator=(const unexpected&) = default;
214  constexpr unexpected& operator=(unexpected&&) = default;
215 
216 
217  [[nodiscard]]
218  constexpr const _Er&
219  error() const & noexcept { return _M_unex; }
220 
221  [[nodiscard]]
222  constexpr _Er&
223  error() & noexcept { return _M_unex; }
224 
225  [[nodiscard]]
226  constexpr const _Er&&
227  error() const && noexcept { return std::move(_M_unex); }
228 
229  [[nodiscard]]
230  constexpr _Er&&
231  error() && noexcept { return std::move(_M_unex); }
232 
233  constexpr void
234  swap(unexpected& __other) noexcept(is_nothrow_swappable_v<_Er>)
235  requires is_swappable_v<_Er>
236  {
237  using std::swap;
238  swap(_M_unex, __other._M_unex);
239  }
240 
241  template<typename _Err>
242  [[nodiscard]]
243  friend constexpr bool
244  operator==(const unexpected& __x, const unexpected<_Err>& __y)
245  { return __x._M_unex == __y.error(); }
246 
247  friend constexpr void
248  swap(unexpected& __x, unexpected& __y) noexcept(noexcept(__x.swap(__y)))
249  requires is_swappable_v<_Er>
250  { __x.swap(__y); }
251 
252  private:
253  _Er _M_unex;
254  };
255 
256  template<typename _Er> unexpected(_Er) -> unexpected<_Er>;
257 
258 /// @cond undocumented
259 namespace __expected
260 {
261  template<typename _Tp>
262  struct _Guard
263  {
264  static_assert( is_nothrow_move_constructible_v<_Tp> );
265 
266  constexpr explicit
267  _Guard(_Tp& __x)
268  : _M_guarded(__builtin_addressof(__x)), _M_tmp(std::move(__x)) // nothrow
269  { std::destroy_at(_M_guarded); }
270 
271  constexpr
272  ~_Guard()
273  {
274  if (_M_guarded) [[unlikely]]
275  std::construct_at(_M_guarded, std::move(_M_tmp));
276  }
277 
278  _Guard(const _Guard&) = delete;
279  _Guard& operator=(const _Guard&) = delete;
280 
281  constexpr _Tp&&
282  release() noexcept
283  {
284  _M_guarded = nullptr;
285  return std::move(_M_tmp);
286  }
287 
288  private:
289  _Tp* _M_guarded;
290  _Tp _M_tmp;
291  };
292 
293  // reinit-expected helper from [expected.object.assign]
294  template<typename _Tp, typename _Up, typename _Vp>
295  constexpr void
296  __reinit(_Tp* __newval, _Up* __oldval, _Vp&& __arg)
297  noexcept(is_nothrow_constructible_v<_Tp, _Vp>)
298  {
299  if constexpr (is_nothrow_constructible_v<_Tp, _Vp>)
300  {
301  std::destroy_at(__oldval);
302  std::construct_at(__newval, std::forward<_Vp>(__arg));
303  }
304  else if constexpr (is_nothrow_move_constructible_v<_Tp>)
305  {
306  _Tp __tmp(std::forward<_Vp>(__arg)); // might throw
307  std::destroy_at(__oldval);
308  std::construct_at(__newval, std::move(__tmp));
309  }
310  else
311  {
312  _Guard<_Up> __guard(*__oldval);
313  std::construct_at(__newval, std::forward<_Vp>(__arg)); // might throw
314  __guard.release();
315  }
316  }
317 }
318 /// @endcond
319 
320  template<typename _Tp, typename _Er>
321  class expected
322  {
323  static_assert( ! is_reference_v<_Tp> );
324  static_assert( ! is_function_v<_Tp> );
325  static_assert( ! is_same_v<remove_cv_t<_Tp>, in_place_t> );
326  static_assert( ! is_same_v<remove_cv_t<_Tp>, unexpect_t> );
327  static_assert( ! __expected::__is_unexpected<remove_cv_t<_Tp>> );
328  static_assert( __expected::__can_be_unexpected<_Er> );
329 
330  template<typename _Up, typename _Err, typename _Unex = unexpected<_Er>>
331  static constexpr bool __cons_from_expected
332  = __or_v<is_constructible<_Tp, expected<_Up, _Err>&>,
333  is_constructible<_Tp, expected<_Up, _Err>>,
334  is_constructible<_Tp, const expected<_Up, _Err>&>,
335  is_constructible<_Tp, const expected<_Up, _Err>>,
336  is_convertible<expected<_Up, _Err>&, _Tp>,
337  is_convertible<expected<_Up, _Err>, _Tp>,
338  is_convertible<const expected<_Up, _Err>&, _Tp>,
339  is_convertible<const expected<_Up, _Err>, _Tp>,
340  is_constructible<_Unex, expected<_Up, _Err>&>,
341  is_constructible<_Unex, expected<_Up, _Err>>,
342  is_constructible<_Unex, const expected<_Up, _Err>&>,
343  is_constructible<_Unex, const expected<_Up, _Err>>
344  >;
345 
346  template<typename _Up, typename _Err>
347  constexpr static bool __explicit_conv
348  = __or_v<__not_<is_convertible<_Up, _Tp>>,
349  __not_<is_convertible<_Err, _Er>>
350  >;
351 
352  template<typename _Up>
353  static constexpr bool __same_val
354  = is_same_v<typename _Up::value_type, _Tp>;
355 
356  template<typename _Up>
357  static constexpr bool __same_err
358  = is_same_v<typename _Up::error_type, _Er>;
359 
360  public:
361  using value_type = _Tp;
362  using error_type = _Er;
363  using unexpected_type = unexpected<_Er>;
364 
365  template<typename _Up>
366  using rebind = expected<_Up, error_type>;
367 
368  constexpr
369  expected()
370  noexcept(is_nothrow_default_constructible_v<_Tp>)
371  requires is_default_constructible_v<_Tp>
372  : _M_val(), _M_has_value(true)
373  { }
374 
375  expected(const expected&) = default;
376 
377  constexpr
378  expected(const expected& __x)
379  noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
380  is_nothrow_copy_constructible<_Er>>)
381  requires is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Er>
382  && (!is_trivially_copy_constructible_v<_Tp>
383  || !is_trivially_copy_constructible_v<_Er>)
384  : _M_has_value(__x._M_has_value)
385  {
386  if (_M_has_value)
387  std::construct_at(__builtin_addressof(_M_val), __x._M_val);
388  else
389  std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
390  }
391 
392  expected(expected&&) = default;
393 
394  constexpr
395  expected(expected&& __x)
396  noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
397  is_nothrow_move_constructible<_Er>>)
398  requires is_move_constructible_v<_Tp> && is_move_constructible_v<_Er>
399  && (!is_trivially_move_constructible_v<_Tp>
400  || !is_trivially_move_constructible_v<_Er>)
401  : _M_has_value(__x._M_has_value)
402  {
403  if (_M_has_value)
404  std::construct_at(__builtin_addressof(_M_val),
405  std::move(__x)._M_val);
406  else
407  std::construct_at(__builtin_addressof(_M_unex),
408  std::move(__x)._M_unex);
409  }
410 
411  template<typename _Up, typename _Gr>
412  requires is_constructible_v<_Tp, const _Up&>
413  && is_constructible_v<_Er, const _Gr&>
414  && (!__cons_from_expected<_Up, _Gr>)
415  constexpr explicit(__explicit_conv<const _Up&, const _Gr&>)
416  expected(const expected<_Up, _Gr>& __x)
417  noexcept(__and_v<is_nothrow_constructible<_Tp, const _Up&>,
418  is_nothrow_constructible<_Er, const _Gr&>>)
419  : _M_has_value(__x._M_has_value)
420  {
421  if (_M_has_value)
422  std::construct_at(__builtin_addressof(_M_val), __x._M_val);
423  else
424  std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
425  }
426 
427  template<typename _Up, typename _Gr>
428  requires is_constructible_v<_Tp, _Up>
429  && is_constructible_v<_Er, _Gr>
430  && (!__cons_from_expected<_Up, _Gr>)
431  constexpr explicit(__explicit_conv<_Up, _Gr>)
432  expected(expected<_Up, _Gr>&& __x)
433  noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>,
434  is_nothrow_constructible<_Er, _Gr>>)
435  : _M_has_value(__x._M_has_value)
436  {
437  if (_M_has_value)
438  std::construct_at(__builtin_addressof(_M_val),
439  std::move(__x)._M_val);
440  else
441  std::construct_at(__builtin_addressof(_M_unex),
442  std::move(__x)._M_unex);
443  }
444 
445  template<typename _Up = _Tp>
446  requires (!is_same_v<remove_cvref_t<_Up>, expected>)
447  && (!is_same_v<remove_cvref_t<_Up>, in_place_t>)
448  && (!__expected::__is_unexpected<remove_cvref_t<_Up>>)
449  && is_constructible_v<_Tp, _Up>
450  constexpr explicit(!is_convertible_v<_Up, _Tp>)
451  expected(_Up&& __v)
452  noexcept(is_nothrow_constructible_v<_Tp, _Up>)
453  : _M_val(std::forward<_Up>(__v)), _M_has_value(true)
454  { }
455 
456  template<typename _Gr = _Er>
457  requires is_constructible_v<_Er, const _Gr&>
458  constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
459  expected(const unexpected<_Gr>& __u)
460  noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
461  : _M_unex(__u.error()), _M_has_value(false)
462  { }
463 
464  template<typename _Gr = _Er>
465  requires is_constructible_v<_Er, _Gr>
466  constexpr explicit(!is_convertible_v<_Gr, _Er>)
467  expected(unexpected<_Gr>&& __u)
468  noexcept(is_nothrow_constructible_v<_Er, _Gr>)
469  : _M_unex(std::move(__u).error()), _M_has_value(false)
470  { }
471 
472  template<typename... _Args>
473  requires is_constructible_v<_Tp, _Args...>
474  constexpr explicit
475  expected(in_place_t, _Args&&... __args)
476  noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
477  : _M_val(std::forward<_Args>(__args)...), _M_has_value(true)
478  { }
479 
480  template<typename _Up, typename... _Args>
481  requires is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
482  constexpr explicit
483  expected(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
484  noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
485  _Args...>)
486  : _M_val(__il, std::forward<_Args>(__args)...), _M_has_value(true)
487  { }
488 
489  template<typename... _Args>
490  requires is_constructible_v<_Er, _Args...>
491  constexpr explicit
492  expected(unexpect_t, _Args&&... __args)
493  noexcept(is_nothrow_constructible_v<_Er, _Args...>)
494  : _M_unex(std::forward<_Args>(__args)...), _M_has_value(false)
495  { }
496 
497  template<typename _Up, typename... _Args>
498  requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
499  constexpr explicit
500  expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
501  noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
502  _Args...>)
503  : _M_unex(__il, std::forward<_Args>(__args)...), _M_has_value(false)
504  { }
505 
506  constexpr ~expected() = default;
507 
508  constexpr ~expected()
509  requires (!is_trivially_destructible_v<_Tp>)
510  || (!is_trivially_destructible_v<_Er>)
511  {
512  if (_M_has_value)
513  std::destroy_at(__builtin_addressof(_M_val));
514  else
515  std::destroy_at(__builtin_addressof(_M_unex));
516  }
517 
518  // assignment
519 
520  expected& operator=(const expected&) = delete;
521 
522  constexpr expected&
523  operator=(const expected& __x)
524  noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
525  is_nothrow_copy_constructible<_Er>,
526  is_nothrow_copy_assignable<_Tp>,
527  is_nothrow_copy_assignable<_Er>>)
528  requires is_copy_assignable_v<_Tp> && is_copy_constructible_v<_Tp>
529  && is_copy_assignable_v<_Er> && is_copy_constructible_v<_Er>
530  && (is_nothrow_move_constructible_v<_Tp>
531  || is_nothrow_move_constructible_v<_Er>)
532  {
533  if (__x._M_has_value)
534  this->_M_assign_val(__x._M_val);
535  else
536  this->_M_assign_unex(__x._M_unex);
537  return *this;
538  }
539 
540  constexpr expected&
541  operator=(expected&& __x)
542  noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
543  is_nothrow_move_constructible<_Er>,
544  is_nothrow_move_assignable<_Tp>,
545  is_nothrow_move_assignable<_Er>>)
546  requires is_move_assignable_v<_Tp> && is_move_constructible_v<_Tp>
547  && is_move_assignable_v<_Er> && is_move_constructible_v<_Er>
548  && (is_nothrow_move_constructible_v<_Tp>
549  || is_nothrow_move_constructible_v<_Er>)
550  {
551  if (__x._M_has_value)
552  _M_assign_val(std::move(__x._M_val));
553  else
554  _M_assign_unex(std::move(__x._M_unex));
555  return *this;
556  }
557 
558  template<typename _Up = _Tp>
559  requires (!is_same_v<expected, remove_cvref_t<_Up>>)
560  && (!__expected::__is_unexpected<remove_cvref_t<_Up>>)
561  && is_constructible_v<_Tp, _Up> && is_assignable_v<_Tp&, _Up>
562  && (is_nothrow_constructible_v<_Tp, _Up>
563  || is_nothrow_move_constructible_v<_Tp>
564  || is_nothrow_move_constructible_v<_Er>)
565  constexpr expected&
566  operator=(_Up&& __v)
567  {
568  _M_assign_val(std::forward<_Up>(__v));
569  return *this;
570  }
571 
572  template<typename _Gr>
573  requires is_constructible_v<_Er, const _Gr&>
574  && is_assignable_v<_Er&, const _Gr&>
575  && (is_nothrow_constructible_v<_Er, const _Gr&>
576  || is_nothrow_move_constructible_v<_Tp>
577  || is_nothrow_move_constructible_v<_Er>)
578  constexpr expected&
579  operator=(const unexpected<_Gr>& __e)
580  {
581  _M_assign_unex(__e.error());
582  return *this;
583  }
584 
585  template<typename _Gr>
586  requires is_constructible_v<_Er, _Gr>
587  && is_assignable_v<_Er&, _Gr>
588  && (is_nothrow_constructible_v<_Er, _Gr>
589  || is_nothrow_move_constructible_v<_Tp>
590  || is_nothrow_move_constructible_v<_Er>)
591  constexpr expected&
592  operator=(unexpected<_Gr>&& __e)
593  {
594  _M_assign_unex(std::move(__e).error());
595  return *this;
596  }
597 
598  // modifiers
599 
600  template<typename... _Args>
601  requires is_nothrow_constructible_v<_Tp, _Args...>
602  constexpr _Tp&
603  emplace(_Args&&... __args) noexcept
604  {
605  if (_M_has_value)
606  std::destroy_at(__builtin_addressof(_M_val));
607  else
608  {
609  std::destroy_at(__builtin_addressof(_M_unex));
610  _M_has_value = true;
611  }
612  std::construct_at(__builtin_addressof(_M_val),
613  std::forward<_Args>(__args)...);
614  return _M_val;
615  }
616 
617  template<typename _Up, typename... _Args>
618  requires is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
619  _Args...>
620  constexpr _Tp&
621  emplace(initializer_list<_Up> __il, _Args&&... __args) noexcept
622  {
623  if (_M_has_value)
624  std::destroy_at(__builtin_addressof(_M_val));
625  else
626  {
627  std::destroy_at(__builtin_addressof(_M_unex));
628  _M_has_value = true;
629  }
630  std::construct_at(__builtin_addressof(_M_val),
631  __il, std::forward<_Args>(__args)...);
632  return _M_val;
633  }
634 
635  // swap
636  constexpr void
637  swap(expected& __x)
638  noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
639  is_nothrow_move_constructible<_Er>,
640  is_nothrow_swappable<_Tp&>,
641  is_nothrow_swappable<_Er&>>)
642  requires is_swappable_v<_Tp> && is_swappable_v<_Er>
643  && is_move_constructible_v<_Tp>
644  && is_move_constructible_v<_Er>
645  && (is_nothrow_move_constructible_v<_Tp>
646  || is_nothrow_move_constructible_v<_Er>)
647  {
648  if (_M_has_value)
649  {
650  if (__x._M_has_value)
651  {
652  using std::swap;
653  swap(_M_val, __x._M_val);
654  }
655  else
656  this->_M_swap_val_unex(__x);
657  }
658  else
659  {
660  if (__x._M_has_value)
661  __x._M_swap_val_unex(*this);
662  else
663  {
664  using std::swap;
665  swap(_M_unex, __x._M_unex);
666  }
667  }
668  }
669 
670  // observers
671 
672  [[nodiscard]]
673  constexpr const _Tp*
674  operator->() const noexcept
675  {
676  __glibcxx_assert(_M_has_value);
677  return __builtin_addressof(_M_val);
678  }
679 
680  [[nodiscard]]
681  constexpr _Tp*
682  operator->() noexcept
683  {
684  __glibcxx_assert(_M_has_value);
685  return __builtin_addressof(_M_val);
686  }
687 
688  [[nodiscard]]
689  constexpr const _Tp&
690  operator*() const & noexcept
691  {
692  __glibcxx_assert(_M_has_value);
693  return _M_val;
694  }
695 
696  [[nodiscard]]
697  constexpr _Tp&
698  operator*() & noexcept
699  {
700  __glibcxx_assert(_M_has_value);
701  return _M_val;
702  }
703 
704  [[nodiscard]]
705  constexpr const _Tp&&
706  operator*() const && noexcept
707  {
708  __glibcxx_assert(_M_has_value);
709  return std::move(_M_val);
710  }
711 
712  [[nodiscard]]
713  constexpr _Tp&&
714  operator*() && noexcept
715  {
716  __glibcxx_assert(_M_has_value);
717  return std::move(_M_val);
718  }
719 
720  [[nodiscard]]
721  constexpr explicit
722  operator bool() const noexcept { return _M_has_value; }
723 
724  [[nodiscard]]
725  constexpr bool has_value() const noexcept { return _M_has_value; }
726 
727  constexpr const _Tp&
728  value() const &
729  {
730  if (_M_has_value) [[likely]]
731  return _M_val;
732  _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex));
733  }
734 
735  constexpr _Tp&
736  value() &
737  {
738  if (_M_has_value) [[likely]]
739  return _M_val;
740  const auto& __unex = _M_unex;
741  _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(__unex));
742  }
743 
744  constexpr const _Tp&&
745  value() const &&
746  {
747  if (_M_has_value) [[likely]]
748  return std::move(_M_val);
749  _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex)));
750  }
751 
752  constexpr _Tp&&
753  value() &&
754  {
755  if (_M_has_value) [[likely]]
756  return std::move(_M_val);
757  _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex)));
758  }
759 
760  constexpr const _Er&
761  error() const & noexcept
762  {
763  __glibcxx_assert(!_M_has_value);
764  return _M_unex;
765  }
766 
767  constexpr _Er&
768  error() & noexcept
769  {
770  __glibcxx_assert(!_M_has_value);
771  return _M_unex;
772  }
773 
774  constexpr const _Er&&
775  error() const && noexcept
776  {
777  __glibcxx_assert(!_M_has_value);
778  return std::move(_M_unex);
779  }
780 
781  constexpr _Er&&
782  error() && noexcept
783  {
784  __glibcxx_assert(!_M_has_value);
785  return std::move(_M_unex);
786  }
787 
788  template<typename _Up>
789  constexpr _Tp
790  value_or(_Up&& __v) const &
791  noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
792  is_nothrow_convertible<_Up, _Tp>>)
793  {
794  static_assert( is_copy_constructible_v<_Tp> );
795  static_assert( is_convertible_v<_Up, _Tp> );
796 
797  if (_M_has_value)
798  return _M_val;
799  return static_cast<_Tp>(std::forward<_Up>(__v));
800  }
801 
802  template<typename _Up>
803  constexpr _Tp
804  value_or(_Up&& __v) &&
805  noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
806  is_nothrow_convertible<_Up, _Tp>>)
807  {
808  static_assert( is_move_constructible_v<_Tp> );
809  static_assert( is_convertible_v<_Up, _Tp> );
810 
811  if (_M_has_value)
812  return std::move(_M_val);
813  return static_cast<_Tp>(std::forward<_Up>(__v));
814  }
815 
816  template<typename _Gr = _Er>
817  constexpr _Er
818  error_or(_Gr&& __e) const&
819  {
820  static_assert( is_copy_constructible_v<_Er> );
821  static_assert( is_convertible_v<_Gr, _Er> );
822 
823  if (_M_has_value)
824  return std::forward<_Gr>(__e);
825  return _M_unex;
826  }
827 
828  template<typename _Gr = _Er>
829  constexpr _Er
830  error_or(_Gr&& __e) &&
831  {
832  static_assert( is_move_constructible_v<_Er> );
833  static_assert( is_convertible_v<_Gr, _Er> );
834 
835  if (_M_has_value)
836  return std::forward<_Gr>(__e);
837  return std::move(_M_unex);
838  }
839 
840  // monadic operations
841 
842  template<typename _Fn> requires is_constructible_v<_Er, _Er&>
843  constexpr auto
844  and_then(_Fn&& __f) &
845  {
846  using _Up = __expected::__result<_Fn, _Tp&>;
847  static_assert(__expected::__is_expected<_Up>,
848  "the function passed to std::expected<T, E>::and_then "
849  "must return a std::expected");
850  static_assert(is_same_v<typename _Up::error_type, _Er>,
851  "the function passed to std::expected<T, E>::and_then "
852  "must return a std::expected with the same error_type");
853 
854  if (has_value())
855  return std::__invoke(std::forward<_Fn>(__f), _M_val);
856  else
857  return _Up(unexpect, _M_unex);
858  }
859 
860  template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
861  constexpr auto
862  and_then(_Fn&& __f) const &
863  {
864  using _Up = __expected::__result<_Fn, const _Tp&>;
865  static_assert(__expected::__is_expected<_Up>,
866  "the function passed to std::expected<T, E>::and_then "
867  "must return a std::expected");
868  static_assert(is_same_v<typename _Up::error_type, _Er>,
869  "the function passed to std::expected<T, E>::and_then "
870  "must return a std::expected with the same error_type");
871 
872  if (has_value())
873  return std::__invoke(std::forward<_Fn>(__f), _M_val);
874  else
875  return _Up(unexpect, _M_unex);
876  }
877 
878  template<typename _Fn> requires is_constructible_v<_Er, _Er>
879  constexpr auto
880  and_then(_Fn&& __f) &&
881  {
882  using _Up = __expected::__result<_Fn, _Tp&&>;
883  static_assert(__expected::__is_expected<_Up>,
884  "the function passed to std::expected<T, E>::and_then "
885  "must return a std::expected");
886  static_assert(is_same_v<typename _Up::error_type, _Er>,
887  "the function passed to std::expected<T, E>::and_then "
888  "must return a std::expected with the same error_type");
889 
890  if (has_value())
891  return std::__invoke(std::forward<_Fn>(__f), std::move(_M_val));
892  else
893  return _Up(unexpect, std::move(_M_unex));
894  }
895 
896 
897  template<typename _Fn> requires is_constructible_v<_Er, const _Er>
898  constexpr auto
899  and_then(_Fn&& __f) const &&
900  {
901  using _Up = __expected::__result<_Fn, const _Tp&&>;
902  static_assert(__expected::__is_expected<_Up>,
903  "the function passed to std::expected<T, E>::and_then "
904  "must return a std::expected");
905  static_assert(is_same_v<typename _Up::error_type, _Er>,
906  "the function passed to std::expected<T, E>::and_then "
907  "must return a std::expected with the same error_type");
908 
909  if (has_value())
910  return std::__invoke(std::forward<_Fn>(__f), std::move(_M_val));
911  else
912  return _Up(unexpect, std::move(_M_unex));
913  }
914 
915  template<typename _Fn> requires is_constructible_v<_Tp, _Tp&>
916  constexpr auto
917  or_else(_Fn&& __f) &
918  {
919  using _Gr = __expected::__result<_Fn, _Er&>;
920  static_assert(__expected::__is_expected<_Gr>,
921  "the function passed to std::expected<T, E>::or_else "
922  "must return a std::expected");
923  static_assert(is_same_v<typename _Gr::value_type, _Tp>,
924  "the function passed to std::expected<T, E>::or_else "
925  "must return a std::expected with the same value_type");
926 
927  if (has_value())
928  return _Gr(in_place, _M_val);
929  else
930  return std::__invoke(std::forward<_Fn>(__f), _M_unex);
931  }
932 
933  template<typename _Fn> requires is_constructible_v<_Tp, const _Tp&>
934  constexpr auto
935  or_else(_Fn&& __f) const &
936  {
937  using _Gr = __expected::__result<_Fn, const _Er&>;
938  static_assert(__expected::__is_expected<_Gr>,
939  "the function passed to std::expected<T, E>::or_else "
940  "must return a std::expected");
941  static_assert(is_same_v<typename _Gr::value_type, _Tp>,
942  "the function passed to std::expected<T, E>::or_else "
943  "must return a std::expected with the same value_type");
944 
945  if (has_value())
946  return _Gr(in_place, _M_val);
947  else
948  return std::__invoke(std::forward<_Fn>(__f), _M_unex);
949  }
950 
951 
952  template<typename _Fn> requires is_constructible_v<_Tp, _Tp>
953  constexpr auto
954  or_else(_Fn&& __f) &&
955  {
956  using _Gr = __expected::__result<_Fn, _Er&&>;
957  static_assert(__expected::__is_expected<_Gr>,
958  "the function passed to std::expected<T, E>::or_else "
959  "must return a std::expected");
960  static_assert(is_same_v<typename _Gr::value_type, _Tp>,
961  "the function passed to std::expected<T, E>::or_else "
962  "must return a std::expected with the same value_type");
963 
964  if (has_value())
965  return _Gr(in_place, std::move(_M_val));
966  else
967  return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
968  }
969 
970  template<typename _Fn> requires is_constructible_v<_Tp, const _Tp>
971  constexpr auto
972  or_else(_Fn&& __f) const &&
973  {
974  using _Gr = __expected::__result<_Fn, const _Er&&>;
975  static_assert(__expected::__is_expected<_Gr>,
976  "the function passed to std::expected<T, E>::or_else "
977  "must return a std::expected");
978  static_assert(is_same_v<typename _Gr::value_type, _Tp>,
979  "the function passed to std::expected<T, E>::or_else "
980  "must return a std::expected with the same value_type");
981 
982  if (has_value())
983  return _Gr(in_place, std::move(_M_val));
984  else
985  return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
986  }
987 
988  template<typename _Fn> requires is_constructible_v<_Er, _Er&>
989  constexpr auto
990  transform(_Fn&& __f) &
991  {
992  using _Up = __expected::__result_xform<_Fn, _Tp&>;
993  using _Res = expected<_Up, _Er>;
994 
995  if (has_value())
996  return _Res(__in_place_inv{}, [&]() {
997  return std::__invoke(std::forward<_Fn>(__f),
998  _M_val);
999  });
1000  else
1001  return _Res(unexpect, _M_unex);
1002  }
1003 
1004  template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
1005  constexpr auto
1006  transform(_Fn&& __f) const &
1007  {
1008  using _Up = __expected::__result_xform<_Fn, const _Tp&>;
1009  using _Res = expected<_Up, _Er>;
1010 
1011  if (has_value())
1012  return _Res(__in_place_inv{}, [&]() {
1013  return std::__invoke(std::forward<_Fn>(__f),
1014  _M_val);
1015  });
1016  else
1017  return _Res(unexpect, _M_unex);
1018  }
1019 
1020  template<typename _Fn> requires is_constructible_v<_Er, _Er>
1021  constexpr auto
1022  transform(_Fn&& __f) &&
1023  {
1024  using _Up = __expected::__result_xform<_Fn, _Tp>;
1025  using _Res = expected<_Up, _Er>;
1026 
1027  if (has_value())
1028  return _Res(__in_place_inv{}, [&]() {
1029  return std::__invoke(std::forward<_Fn>(__f),
1030  std::move(_M_val));
1031  });
1032  else
1033  return _Res(unexpect, std::move(_M_unex));
1034  }
1035 
1036  template<typename _Fn> requires is_constructible_v<_Er, const _Er>
1037  constexpr auto
1038  transform(_Fn&& __f) const &&
1039  {
1040  using _Up = __expected::__result_xform<_Fn, const _Tp>;
1041  using _Res = expected<_Up, _Er>;
1042 
1043  if (has_value())
1044  return _Res(__in_place_inv{}, [&]() {
1045  return std::__invoke(std::forward<_Fn>(__f),
1046  std::move(_M_val));
1047  });
1048  else
1049  return _Res(unexpect, std::move(_M_unex));
1050  }
1051 
1052  template<typename _Fn> requires is_constructible_v<_Tp, _Tp&>
1053  constexpr auto
1054  transform_error(_Fn&& __f) &
1055  {
1056  using _Gr = __expected::__result_xform<_Fn, _Er&>;
1057  using _Res = expected<_Tp, _Gr>;
1058 
1059  if (has_value())
1060  return _Res(in_place, _M_val);
1061  else
1062  return _Res(__unexpect_inv{}, [&]() {
1063  return std::__invoke(std::forward<_Fn>(__f),
1064  _M_unex);
1065  });
1066  }
1067 
1068  template<typename _Fn> requires is_constructible_v<_Tp, const _Tp&>
1069  constexpr auto
1070  transform_error(_Fn&& __f) const &
1071  {
1072  using _Gr = __expected::__result_xform<_Fn, const _Er&>;
1073  using _Res = expected<_Tp, _Gr>;
1074 
1075  if (has_value())
1076  return _Res(in_place, _M_val);
1077  else
1078  return _Res(__unexpect_inv{}, [&]() {
1079  return std::__invoke(std::forward<_Fn>(__f),
1080  _M_unex);
1081  });
1082  }
1083 
1084  template<typename _Fn> requires is_constructible_v<_Tp, _Tp>
1085  constexpr auto
1086  transform_error(_Fn&& __f) &&
1087  {
1088  using _Gr = __expected::__result_xform<_Fn, _Er&&>;
1089  using _Res = expected<_Tp, _Gr>;
1090 
1091  if (has_value())
1092  return _Res(in_place, std::move(_M_val));
1093  else
1094  return _Res(__unexpect_inv{}, [&]() {
1095  return std::__invoke(std::forward<_Fn>(__f),
1096  std::move(_M_unex));
1097  });
1098  }
1099 
1100  template<typename _Fn> requires is_constructible_v<_Tp, const _Tp>
1101  constexpr auto
1102  transform_error(_Fn&& __f) const &&
1103  {
1104  using _Gr = __expected::__result_xform<_Fn, const _Er&&>;
1105  using _Res = expected<_Tp, _Gr>;
1106 
1107  if (has_value())
1108  return _Res(in_place, std::move(_M_val));
1109  else
1110  return _Res(__unexpect_inv{}, [&]() {
1111  return std::__invoke(std::forward<_Fn>(__f),
1112  std::move(_M_unex));
1113  });
1114  }
1115 
1116  // equality operators
1117 
1118  template<typename _Up, typename _Er2>
1119  requires (!is_void_v<_Up>)
1120  friend constexpr bool
1121  operator==(const expected& __x, const expected<_Up, _Er2>& __y)
1122  // FIXME: noexcept(noexcept(bool(*__x == *__y))
1123  // && noexcept(bool(__x.error() == __y.error())))
1124  {
1125  if (__x.has_value())
1126  return __y.has_value() && bool(*__x == *__y);
1127  else
1128  return !__y.has_value() && bool(__x.error() == __y.error());
1129  }
1130 
1131  template<typename _Up>
1132  friend constexpr bool
1133  operator==(const expected& __x, const _Up& __v)
1134  // FIXME: noexcept(noexcept(bool(*__x == __v)))
1135  { return __x.has_value() && bool(*__x == __v); }
1136 
1137  template<typename _Er2>
1138  friend constexpr bool
1139  operator==(const expected& __x, const unexpected<_Er2>& __e)
1140  // FIXME: noexcept(noexcept(bool(__x.error() == __e.error())))
1141  { return !__x.has_value() && bool(__x.error() == __e.error()); }
1142 
1143  friend constexpr void
1144  swap(expected& __x, expected& __y)
1145  noexcept(noexcept(__x.swap(__y)))
1146  requires requires {__x.swap(__y);}
1147  { __x.swap(__y); }
1148 
1149  private:
1150  template<typename, typename> friend class expected;
1151 
1152  template<typename _Vp>
1153  constexpr void
1154  _M_assign_val(_Vp&& __v)
1155  {
1156  if (_M_has_value)
1157  _M_val = std::forward<_Vp>(__v);
1158  else
1159  {
1160  __expected::__reinit(__builtin_addressof(_M_val),
1161  __builtin_addressof(_M_unex),
1162  std::forward<_Vp>(__v));
1163  _M_has_value = true;
1164  }
1165  }
1166 
1167  template<typename _Vp>
1168  constexpr void
1169  _M_assign_unex(_Vp&& __v)
1170  {
1171  if (_M_has_value)
1172  {
1173  __expected::__reinit(__builtin_addressof(_M_unex),
1174  __builtin_addressof(_M_val),
1175  std::forward<_Vp>(__v));
1176  _M_has_value = false;
1177  }
1178  else
1179  _M_unex = std::forward<_Vp>(__v);
1180  }
1181 
1182  // Swap two expected objects when only one has a value.
1183  // Precondition: this->_M_has_value && !__rhs._M_has_value
1184  constexpr void
1185  _M_swap_val_unex(expected& __rhs)
1186  noexcept(__and_v<is_nothrow_move_constructible<_Er>,
1187  is_nothrow_move_constructible<_Tp>>)
1188  {
1189  if constexpr (is_nothrow_move_constructible_v<_Er>)
1190  {
1191  __expected::_Guard<_Er> __guard(__rhs._M_unex);
1192  std::construct_at(__builtin_addressof(__rhs._M_val),
1193  std::move(_M_val)); // might throw
1194  __rhs._M_has_value = true;
1195  std::destroy_at(__builtin_addressof(_M_val));
1196  std::construct_at(__builtin_addressof(_M_unex),
1197  __guard.release());
1198  _M_has_value = false;
1199  }
1200  else
1201  {
1202  __expected::_Guard<_Tp> __guard(_M_val);
1203  std::construct_at(__builtin_addressof(_M_unex),
1204  std::move(__rhs._M_unex)); // might throw
1205  _M_has_value = false;
1206  std::destroy_at(__builtin_addressof(__rhs._M_unex));
1207  std::construct_at(__builtin_addressof(__rhs._M_val),
1208  __guard.release());
1209  __rhs._M_has_value = true;
1210  }
1211  }
1212 
1213  using __in_place_inv = __expected::__in_place_inv;
1214  using __unexpect_inv = __expected::__unexpect_inv;
1215 
1216  template<typename _Fn>
1217  explicit constexpr
1218  expected(__in_place_inv, _Fn&& __fn)
1219  : _M_val(std::forward<_Fn>(__fn)()), _M_has_value(true)
1220  { }
1221 
1222  template<typename _Fn>
1223  explicit constexpr
1224  expected(__unexpect_inv, _Fn&& __fn)
1225  : _M_unex(std::forward<_Fn>(__fn)()), _M_has_value(false)
1226  { }
1227 
1228  union {
1229  _Tp _M_val;
1230  _Er _M_unex;
1231  };
1232 
1233  bool _M_has_value;
1234  };
1235 
1236  // Partial specialization for std::expected<cv void, E>
1237  template<typename _Tp, typename _Er> requires is_void_v<_Tp>
1238  class expected<_Tp, _Er>
1239  {
1240  static_assert( __expected::__can_be_unexpected<_Er> );
1241 
1242  template<typename _Up, typename _Err, typename _Unex = unexpected<_Er>>
1243  static constexpr bool __cons_from_expected
1244  = __or_v<is_constructible<_Unex, expected<_Up, _Err>&>,
1245  is_constructible<_Unex, expected<_Up, _Err>>,
1246  is_constructible<_Unex, const expected<_Up, _Err>&>,
1247  is_constructible<_Unex, const expected<_Up, _Err>>
1248  >;
1249 
1250  template<typename _Up>
1251  static constexpr bool __same_val
1252  = is_same_v<typename _Up::value_type, _Tp>;
1253 
1254  template<typename _Up>
1255  static constexpr bool __same_err
1256  = is_same_v<typename _Up::error_type, _Er>;
1257 
1258  public:
1259  using value_type = _Tp;
1260  using error_type = _Er;
1261  using unexpected_type = unexpected<_Er>;
1262 
1263  template<typename _Up>
1264  using rebind = expected<_Up, error_type>;
1265 
1266  constexpr
1267  expected() noexcept
1268  : _M_void(), _M_has_value(true)
1269  { }
1270 
1271  expected(const expected&) = default;
1272 
1273  constexpr
1274  expected(const expected& __x)
1275  noexcept(is_nothrow_copy_constructible_v<_Er>)
1276  requires is_copy_constructible_v<_Er>
1277  && (!is_trivially_copy_constructible_v<_Er>)
1278  : _M_void(), _M_has_value(__x._M_has_value)
1279  {
1280  if (!_M_has_value)
1281  std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
1282  }
1283 
1284  expected(expected&&) = default;
1285 
1286  constexpr
1287  expected(expected&& __x)
1288  noexcept(is_nothrow_move_constructible_v<_Er>)
1289  requires is_move_constructible_v<_Er>
1290  && (!is_trivially_move_constructible_v<_Er>)
1291  : _M_void(), _M_has_value(__x._M_has_value)
1292  {
1293  if (!_M_has_value)
1294  std::construct_at(__builtin_addressof(_M_unex),
1295  std::move(__x)._M_unex);
1296  }
1297 
1298  template<typename _Up, typename _Gr>
1299  requires is_void_v<_Up>
1300  && is_constructible_v<_Er, const _Gr&>
1301  && (!__cons_from_expected<_Up, _Gr>)
1302  constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
1303  expected(const expected<_Up, _Gr>& __x)
1304  noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
1305  : _M_void(), _M_has_value(__x._M_has_value)
1306  {
1307  if (!_M_has_value)
1308  std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
1309  }
1310 
1311  template<typename _Up, typename _Gr>
1312  requires is_void_v<_Up>
1313  && is_constructible_v<_Er, _Gr>
1314  && (!__cons_from_expected<_Up, _Gr>)
1315  constexpr explicit(!is_convertible_v<_Gr, _Er>)
1316  expected(expected<_Up, _Gr>&& __x)
1317  noexcept(is_nothrow_constructible_v<_Er, _Gr>)
1318  : _M_void(), _M_has_value(__x._M_has_value)
1319  {
1320  if (!_M_has_value)
1321  std::construct_at(__builtin_addressof(_M_unex),
1322  std::move(__x)._M_unex);
1323  }
1324 
1325  template<typename _Gr = _Er>
1326  requires is_constructible_v<_Er, const _Gr&>
1327  constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
1328  expected(const unexpected<_Gr>& __u)
1329  noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
1330  : _M_unex(__u.error()), _M_has_value(false)
1331  { }
1332 
1333  template<typename _Gr = _Er>
1334  requires is_constructible_v<_Er, _Gr>
1335  constexpr explicit(!is_convertible_v<_Gr, _Er>)
1336  expected(unexpected<_Gr>&& __u)
1337  noexcept(is_nothrow_constructible_v<_Er, _Gr>)
1338  : _M_unex(std::move(__u).error()), _M_has_value(false)
1339  { }
1340 
1341  constexpr explicit
1342  expected(in_place_t) noexcept
1343  : expected()
1344  { }
1345 
1346  template<typename... _Args>
1347  requires is_constructible_v<_Er, _Args...>
1348  constexpr explicit
1349  expected(unexpect_t, _Args&&... __args)
1350  noexcept(is_nothrow_constructible_v<_Er, _Args...>)
1351  : _M_unex(std::forward<_Args>(__args)...), _M_has_value(false)
1352  { }
1353 
1354  template<typename _Up, typename... _Args>
1355  requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
1356  constexpr explicit
1357  expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
1358  noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
1359  _Args...>)
1360  : _M_unex(__il, std::forward<_Args>(__args)...), _M_has_value(false)
1361  { }
1362 
1363  constexpr ~expected() = default;
1364 
1365  constexpr ~expected() requires (!is_trivially_destructible_v<_Er>)
1366  {
1367  if (!_M_has_value)
1368  std::destroy_at(__builtin_addressof(_M_unex));
1369  }
1370 
1371  // assignment
1372 
1373  expected& operator=(const expected&) = delete;
1374 
1375  constexpr expected&
1376  operator=(const expected& __x)
1377  noexcept(__and_v<is_nothrow_copy_constructible<_Er>,
1378  is_nothrow_copy_assignable<_Er>>)
1379  requires is_copy_constructible_v<_Er>
1380  && is_copy_assignable_v<_Er>
1381  {
1382  if (__x._M_has_value)
1383  emplace();
1384  else
1385  _M_assign_unex(__x._M_unex);
1386  return *this;
1387  }
1388 
1389  constexpr expected&
1390  operator=(expected&& __x)
1391  noexcept(__and_v<is_nothrow_move_constructible<_Er>,
1392  is_nothrow_move_assignable<_Er>>)
1393  requires is_move_constructible_v<_Er>
1394  && is_move_assignable_v<_Er>
1395  {
1396  if (__x._M_has_value)
1397  emplace();
1398  else
1399  _M_assign_unex(std::move(__x._M_unex));
1400  return *this;
1401  }
1402 
1403  template<typename _Gr>
1404  requires is_constructible_v<_Er, const _Gr&>
1405  && is_assignable_v<_Er&, const _Gr&>
1406  constexpr expected&
1407  operator=(const unexpected<_Gr>& __e)
1408  {
1409  _M_assign_unex(__e.error());
1410  return *this;
1411  }
1412 
1413  template<typename _Gr>
1414  requires is_constructible_v<_Er, _Gr>
1415  && is_assignable_v<_Er&, _Gr>
1416  constexpr expected&
1417  operator=(unexpected<_Gr>&& __e)
1418  {
1419  _M_assign_unex(std::move(__e.error()));
1420  return *this;
1421  }
1422 
1423  // modifiers
1424 
1425  constexpr void
1426  emplace() noexcept
1427  {
1428  if (!_M_has_value)
1429  {
1430  std::destroy_at(__builtin_addressof(_M_unex));
1431  _M_has_value = true;
1432  }
1433  }
1434 
1435  // swap
1436  constexpr void
1437  swap(expected& __x)
1438  noexcept(__and_v<is_nothrow_swappable<_Er&>,
1439  is_nothrow_move_constructible<_Er>>)
1440  requires is_swappable_v<_Er> && is_move_constructible_v<_Er>
1441  {
1442  if (_M_has_value)
1443  {
1444  if (!__x._M_has_value)
1445  {
1446  std::construct_at(__builtin_addressof(_M_unex),
1447  std::move(__x._M_unex)); // might throw
1448  std::destroy_at(__builtin_addressof(__x._M_unex));
1449  _M_has_value = false;
1450  __x._M_has_value = true;
1451  }
1452  }
1453  else
1454  {
1455  if (__x._M_has_value)
1456  {
1457  std::construct_at(__builtin_addressof(__x._M_unex),
1458  std::move(_M_unex)); // might throw
1459  std::destroy_at(__builtin_addressof(_M_unex));
1460  _M_has_value = true;
1461  __x._M_has_value = false;
1462  }
1463  else
1464  {
1465  using std::swap;
1466  swap(_M_unex, __x._M_unex);
1467  }
1468  }
1469  }
1470 
1471  // observers
1472 
1473  [[nodiscard]]
1474  constexpr explicit
1475  operator bool() const noexcept { return _M_has_value; }
1476 
1477  [[nodiscard]]
1478  constexpr bool has_value() const noexcept { return _M_has_value; }
1479 
1480  constexpr void
1481  operator*() const noexcept { __glibcxx_assert(_M_has_value); }
1482 
1483  constexpr void
1484  value() const&
1485  {
1486  if (_M_has_value) [[likely]]
1487  return;
1488  _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex));
1489  }
1490 
1491  constexpr void
1492  value() &&
1493  {
1494  if (_M_has_value) [[likely]]
1495  return;
1496  _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex)));
1497  }
1498 
1499  constexpr const _Er&
1500  error() const & noexcept
1501  {
1502  __glibcxx_assert(!_M_has_value);
1503  return _M_unex;
1504  }
1505 
1506  constexpr _Er&
1507  error() & noexcept
1508  {
1509  __glibcxx_assert(!_M_has_value);
1510  return _M_unex;
1511  }
1512 
1513  constexpr const _Er&&
1514  error() const && noexcept
1515  {
1516  __glibcxx_assert(!_M_has_value);
1517  return std::move(_M_unex);
1518  }
1519 
1520  constexpr _Er&&
1521  error() && noexcept
1522  {
1523  __glibcxx_assert(!_M_has_value);
1524  return std::move(_M_unex);
1525  }
1526 
1527  template<typename _Gr = _Er>
1528  constexpr _Er
1529  error_or(_Gr&& __e) const&
1530  {
1531  static_assert( is_copy_constructible_v<_Er> );
1532  static_assert( is_convertible_v<_Gr, _Er> );
1533 
1534  if (_M_has_value)
1535  return std::forward<_Gr>(__e);
1536  return _M_unex;
1537  }
1538 
1539  template<typename _Gr = _Er>
1540  constexpr _Er
1541  error_or(_Gr&& __e) &&
1542  {
1543  static_assert( is_move_constructible_v<_Er> );
1544  static_assert( is_convertible_v<_Gr, _Er> );
1545 
1546  if (_M_has_value)
1547  return std::forward<_Gr>(__e);
1548  return std::move(_M_unex);
1549  }
1550 
1551  // monadic operations
1552 
1553  template<typename _Fn> requires is_constructible_v<_Er, _Er&>
1554  constexpr auto
1555  and_then(_Fn&& __f) &
1556  {
1557  using _Up = __expected::__result0<_Fn>;
1558  static_assert(__expected::__is_expected<_Up>);
1559  static_assert(is_same_v<typename _Up::error_type, _Er>);
1560 
1561  if (has_value())
1562  return std::__invoke(std::forward<_Fn>(__f));
1563  else
1564  return _Up(unexpect, _M_unex);
1565  }
1566 
1567  template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
1568  constexpr auto
1569  and_then(_Fn&& __f) const &
1570  {
1571  using _Up = __expected::__result0<_Fn>;
1572  static_assert(__expected::__is_expected<_Up>);
1573  static_assert(is_same_v<typename _Up::error_type, _Er>);
1574 
1575  if (has_value())
1576  return std::__invoke(std::forward<_Fn>(__f));
1577  else
1578  return _Up(unexpect, _M_unex);
1579  }
1580 
1581  template<typename _Fn> requires is_constructible_v<_Er, _Er>
1582  constexpr auto
1583  and_then(_Fn&& __f) &&
1584  {
1585  using _Up = __expected::__result0<_Fn>;
1586  static_assert(__expected::__is_expected<_Up>);
1587  static_assert(is_same_v<typename _Up::error_type, _Er>);
1588 
1589  if (has_value())
1590  return std::__invoke(std::forward<_Fn>(__f));
1591  else
1592  return _Up(unexpect, std::move(_M_unex));
1593  }
1594 
1595  template<typename _Fn> requires is_constructible_v<_Er, const _Er>
1596  constexpr auto
1597  and_then(_Fn&& __f) const &&
1598  {
1599  using _Up = __expected::__result0<_Fn>;
1600  static_assert(__expected::__is_expected<_Up>);
1601  static_assert(is_same_v<typename _Up::error_type, _Er>);
1602 
1603  if (has_value())
1604  return std::__invoke(std::forward<_Fn>(__f));
1605  else
1606  return _Up(unexpect, std::move(_M_unex));
1607  }
1608 
1609  template<typename _Fn>
1610  constexpr auto
1611  or_else(_Fn&& __f) &
1612  {
1613  using _Gr = __expected::__result<_Fn, _Er&>;
1614  static_assert(__expected::__is_expected<_Gr>);
1615  static_assert(is_same_v<typename _Gr::value_type, _Tp>);
1616 
1617  if (has_value())
1618  return _Gr();
1619  else
1620  return std::__invoke(std::forward<_Fn>(__f), _M_unex);
1621  }
1622 
1623  template<typename _Fn>
1624  constexpr auto
1625  or_else(_Fn&& __f) const &
1626  {
1627  using _Gr = __expected::__result<_Fn, const _Er&>;
1628  static_assert(__expected::__is_expected<_Gr>);
1629  static_assert(is_same_v<typename _Gr::value_type, _Tp>);
1630 
1631  if (has_value())
1632  return _Gr();
1633  else
1634  return std::__invoke(std::forward<_Fn>(__f), _M_unex);
1635  }
1636 
1637  template<typename _Fn>
1638  constexpr auto
1639  or_else(_Fn&& __f) &&
1640  {
1641  using _Gr = __expected::__result<_Fn, _Er&&>;
1642  static_assert(__expected::__is_expected<_Gr>);
1643  static_assert(is_same_v<typename _Gr::value_type, _Tp>);
1644 
1645  if (has_value())
1646  return _Gr();
1647  else
1648  return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
1649  }
1650 
1651  template<typename _Fn>
1652  constexpr auto
1653  or_else(_Fn&& __f) const &&
1654  {
1655  using _Gr = __expected::__result<_Fn, const _Er&&>;
1656  static_assert(__expected::__is_expected<_Gr>);
1657  static_assert(is_same_v<typename _Gr::value_type, _Tp>);
1658 
1659  if (has_value())
1660  return _Gr();
1661  else
1662  return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
1663  }
1664 
1665  template<typename _Fn> requires is_constructible_v<_Er, _Er&>
1666  constexpr auto
1667  transform(_Fn&& __f) &
1668  {
1669  using _Up = __expected::__result0_xform<_Fn>;
1670  using _Res = expected<_Up, _Er>;
1671 
1672  if (has_value())
1673  return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
1674  else
1675  return _Res(unexpect, _M_unex);
1676  }
1677 
1678  template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
1679  constexpr auto
1680  transform(_Fn&& __f) const &
1681  {
1682  using _Up = __expected::__result0_xform<_Fn>;
1683  using _Res = expected<_Up, _Er>;
1684 
1685  if (has_value())
1686  return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
1687  else
1688  return _Res(unexpect, _M_unex);
1689  }
1690 
1691  template<typename _Fn> requires is_constructible_v<_Er, _Er>
1692  constexpr auto
1693  transform(_Fn&& __f) &&
1694  {
1695  using _Up = __expected::__result0_xform<_Fn>;
1696  using _Res = expected<_Up, _Er>;
1697 
1698  if (has_value())
1699  return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
1700  else
1701  return _Res(unexpect, std::move(_M_unex));
1702  }
1703 
1704  template<typename _Fn> requires is_constructible_v<_Er, const _Er>
1705  constexpr auto
1706  transform(_Fn&& __f) const &&
1707  {
1708  using _Up = __expected::__result0_xform<_Fn>;
1709  using _Res = expected<_Up, _Er>;
1710 
1711  if (has_value())
1712  return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
1713  else
1714  return _Res(unexpect, std::move(_M_unex));
1715  }
1716 
1717  template<typename _Fn>
1718  constexpr auto
1719  transform_error(_Fn&& __f) &
1720  {
1721  using _Gr = __expected::__result_xform<_Fn, _Er&>;
1722  using _Res = expected<_Tp, _Gr>;
1723 
1724  if (has_value())
1725  return _Res();
1726  else
1727  return _Res(__unexpect_inv{}, [&]() {
1728  return std::__invoke(std::forward<_Fn>(__f),
1729  _M_unex);
1730  });
1731  }
1732 
1733  template<typename _Fn>
1734  constexpr auto
1735  transform_error(_Fn&& __f) const &
1736  {
1737  using _Gr = __expected::__result_xform<_Fn, const _Er&>;
1738  using _Res = expected<_Tp, _Gr>;
1739 
1740  if (has_value())
1741  return _Res();
1742  else
1743  return _Res(__unexpect_inv{}, [&]() {
1744  return std::__invoke(std::forward<_Fn>(__f),
1745  _M_unex);
1746  });
1747  }
1748 
1749  template<typename _Fn>
1750  constexpr auto
1751  transform_error(_Fn&& __f) &&
1752  {
1753  using _Gr = __expected::__result_xform<_Fn, _Er&&>;
1754  using _Res = expected<_Tp, _Gr>;
1755 
1756  if (has_value())
1757  return _Res();
1758  else
1759  return _Res(__unexpect_inv{}, [&]() {
1760  return std::__invoke(std::forward<_Fn>(__f),
1761  std::move(_M_unex));
1762  });
1763  }
1764 
1765  template<typename _Fn>
1766  constexpr auto
1767  transform_error(_Fn&& __f) const &&
1768  {
1769  using _Gr = __expected::__result_xform<_Fn, const _Er&&>;
1770  using _Res = expected<_Tp, _Gr>;
1771 
1772  if (has_value())
1773  return _Res();
1774  else
1775  return _Res(__unexpect_inv{}, [&]() {
1776  return std::__invoke(std::forward<_Fn>(__f),
1777  std::move(_M_unex));
1778  });
1779  }
1780 
1781  // equality operators
1782 
1783  template<typename _Up, typename _Er2>
1784  requires is_void_v<_Up>
1785  friend constexpr bool
1786  operator==(const expected& __x, const expected<_Up, _Er2>& __y)
1787  // FIXME: noexcept(noexcept(bool(__x.error() == __y.error())))
1788  {
1789  if (__x.has_value())
1790  return __y.has_value();
1791  else
1792  return !__y.has_value() && bool(__x.error() == __y.error());
1793  }
1794 
1795  template<typename _Er2>
1796  friend constexpr bool
1797  operator==(const expected& __x, const unexpected<_Er2>& __e)
1798  // FIXME: noexcept(noexcept(bool(__x.error() == __e.error())))
1799  { return !__x.has_value() && bool(__x.error() == __e.error()); }
1800 
1801  friend constexpr void
1802  swap(expected& __x, expected& __y)
1803  noexcept(noexcept(__x.swap(__y)))
1804  requires requires { __x.swap(__y); }
1805  { __x.swap(__y); }
1806 
1807  private:
1808  template<typename, typename> friend class expected;
1809 
1810  template<typename _Vp>
1811  constexpr void
1812  _M_assign_unex(_Vp&& __v)
1813  {
1814  if (_M_has_value)
1815  {
1816  std::construct_at(__builtin_addressof(_M_unex),
1817  std::forward<_Vp>(__v));
1818  _M_has_value = false;
1819  }
1820  else
1821  _M_unex = std::forward<_Vp>(__v);
1822  }
1823 
1824  using __in_place_inv = __expected::__in_place_inv;
1825  using __unexpect_inv = __expected::__unexpect_inv;
1826 
1827  template<typename _Fn>
1828  explicit constexpr
1829  expected(__in_place_inv, _Fn&& __fn)
1830  : _M_void(), _M_has_value(true)
1831  { std::forward<_Fn>(__fn)(); }
1832 
1833  template<typename _Fn>
1834  explicit constexpr
1835  expected(__unexpect_inv, _Fn&& __fn)
1836  : _M_unex(std::forward<_Fn>(__fn)()), _M_has_value(false)
1837  { }
1838 
1839  union {
1840  struct { } _M_void;
1841  _Er _M_unex;
1842  };
1843 
1844  bool _M_has_value;
1845  };
1846  /// @}
1847 
1848 _GLIBCXX_END_NAMESPACE_VERSION
1849 } // namespace std
1850 
1851 #endif // __cpp_lib_expected
1852 #endif // _GLIBCXX_EXPECTED