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