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  // _GLIBCXX_RESOLVE_LIB_DEFECTS
319  // 3836. std::expected<bool, E1> conversion constructor
320  // expected(const expected<U, G>&) should take precedence over
321  // expected(U&&) with operator bool
322 
323  // If T is cv bool, remove_cvref_t<U> is not a specialization of expected.
324  template<typename _Tp, typename _Up>
325  concept __not_constructing_bool_from_expected
326  = ! is_same_v<remove_cv_t<_Tp>, bool>
327  || ! __is_expected<remove_cvref_t<_Up>>;
328 }
329 /// @endcond
330 
331  template<typename _Tp, typename _Er>
332  class expected
333  {
334  static_assert( ! is_reference_v<_Tp> );
335  static_assert( ! is_function_v<_Tp> );
336  static_assert( ! is_same_v<remove_cv_t<_Tp>, in_place_t> );
337  static_assert( ! is_same_v<remove_cv_t<_Tp>, unexpect_t> );
338  static_assert( ! __expected::__is_unexpected<remove_cv_t<_Tp>> );
339  static_assert( __expected::__can_be_unexpected<_Er> );
340 
341  // If T is not cv bool, converts-from-any-cvref<T, expected<U, G>> and
342  // is_constructible<unexpected<E>, cv expected<U, G> ref-qual> are false.
343  template<typename _Up, typename _Gr, typename _Unex = unexpected<_Er>,
344  typename = remove_cv_t<_Tp>>
345  static constexpr bool __cons_from_expected
346  = __or_v<is_constructible<_Tp, expected<_Up, _Gr>&>,
347  is_constructible<_Tp, expected<_Up, _Gr>>,
348  is_constructible<_Tp, const expected<_Up, _Gr>&>,
349  is_constructible<_Tp, const expected<_Up, _Gr>>,
350  is_convertible<expected<_Up, _Gr>&, _Tp>,
351  is_convertible<expected<_Up, _Gr>, _Tp>,
352  is_convertible<const expected<_Up, _Gr>&, _Tp>,
353  is_convertible<const expected<_Up, _Gr>, _Tp>,
354  is_constructible<_Unex, expected<_Up, _Gr>&>,
355  is_constructible<_Unex, expected<_Up, _Gr>>,
356  is_constructible<_Unex, const expected<_Up, _Gr>&>,
357  is_constructible<_Unex, const expected<_Up, _Gr>>
358  >;
359 
360  // _GLIBCXX_RESOLVE_LIB_DEFECTS
361  // If t is cv bool, we know it can be constructed from expected<U, G>,
362  // but we don't want to cause the expected(U&&) constructor to be used,
363  // so we only check the is_constructible<unexpected<E>, ...> cases.
364  template<typename _Up, typename _Gr, typename _Unex>
365  static constexpr bool __cons_from_expected<_Up, _Gr, _Unex, bool>
366  = __or_v<is_constructible<_Unex, expected<_Up, _Gr>&>,
367  is_constructible<_Unex, expected<_Up, _Gr>>,
368  is_constructible<_Unex, const expected<_Up, _Gr>&>,
369  is_constructible<_Unex, const expected<_Up, _Gr>>
370  >;
371 
372  template<typename _Up, typename _Gr>
373  constexpr static bool __explicit_conv
374  = __or_v<__not_<is_convertible<_Up, _Tp>>,
375  __not_<is_convertible<_Gr, _Er>>
376  >;
377 
378  template<typename _Up>
379  static constexpr bool __same_val
380  = is_same_v<typename _Up::value_type, _Tp>;
381 
382  template<typename _Up>
383  static constexpr bool __same_err
384  = is_same_v<typename _Up::error_type, _Er>;
385 
386  public:
387  using value_type = _Tp;
388  using error_type = _Er;
389  using unexpected_type = unexpected<_Er>;
390 
391  template<typename _Up>
392  using rebind = expected<_Up, error_type>;
393 
394  constexpr
395  expected()
396  noexcept(is_nothrow_default_constructible_v<_Tp>)
397  requires is_default_constructible_v<_Tp>
398  : _M_val(), _M_has_value(true)
399  { }
400 
401  expected(const expected&) = default;
402 
403  constexpr
404  expected(const expected& __x)
405  noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
406  is_nothrow_copy_constructible<_Er>>)
407  requires is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Er>
408  && (!is_trivially_copy_constructible_v<_Tp>
409  || !is_trivially_copy_constructible_v<_Er>)
410  : _M_has_value(__x._M_has_value)
411  {
412  if (_M_has_value)
413  std::construct_at(__builtin_addressof(_M_val), __x._M_val);
414  else
415  std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
416  }
417 
418  expected(expected&&) = default;
419 
420  constexpr
421  expected(expected&& __x)
422  noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
423  is_nothrow_move_constructible<_Er>>)
424  requires is_move_constructible_v<_Tp> && is_move_constructible_v<_Er>
425  && (!is_trivially_move_constructible_v<_Tp>
426  || !is_trivially_move_constructible_v<_Er>)
427  : _M_has_value(__x._M_has_value)
428  {
429  if (_M_has_value)
430  std::construct_at(__builtin_addressof(_M_val),
431  std::move(__x)._M_val);
432  else
433  std::construct_at(__builtin_addressof(_M_unex),
434  std::move(__x)._M_unex);
435  }
436 
437  template<typename _Up, typename _Gr>
438  requires is_constructible_v<_Tp, const _Up&>
439  && is_constructible_v<_Er, const _Gr&>
440  && (!__cons_from_expected<_Up, _Gr>)
441  constexpr explicit(__explicit_conv<const _Up&, const _Gr&>)
442  expected(const expected<_Up, _Gr>& __x)
443  noexcept(__and_v<is_nothrow_constructible<_Tp, const _Up&>,
444  is_nothrow_constructible<_Er, const _Gr&>>)
445  : _M_has_value(__x._M_has_value)
446  {
447  if (_M_has_value)
448  std::construct_at(__builtin_addressof(_M_val), __x._M_val);
449  else
450  std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
451  }
452 
453  template<typename _Up, typename _Gr>
454  requires is_constructible_v<_Tp, _Up>
455  && is_constructible_v<_Er, _Gr>
456  && (!__cons_from_expected<_Up, _Gr>)
457  constexpr explicit(__explicit_conv<_Up, _Gr>)
458  expected(expected<_Up, _Gr>&& __x)
459  noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>,
460  is_nothrow_constructible<_Er, _Gr>>)
461  : _M_has_value(__x._M_has_value)
462  {
463  if (_M_has_value)
464  std::construct_at(__builtin_addressof(_M_val),
465  std::move(__x)._M_val);
466  else
467  std::construct_at(__builtin_addressof(_M_unex),
468  std::move(__x)._M_unex);
469  }
470 
471  template<typename _Up = _Tp>
472  requires (!is_same_v<remove_cvref_t<_Up>, expected>)
473  && (!is_same_v<remove_cvref_t<_Up>, in_place_t>)
474  && (!is_same_v<remove_cvref_t<_Up>, unexpect_t>)
475  && is_constructible_v<_Tp, _Up>
476  && (!__expected::__is_unexpected<remove_cvref_t<_Up>>)
477  && __expected::__not_constructing_bool_from_expected<_Tp, _Up>
478  constexpr explicit(!is_convertible_v<_Up, _Tp>)
479  expected(_Up&& __v)
480  noexcept(is_nothrow_constructible_v<_Tp, _Up>)
481  : _M_val(std::forward<_Up>(__v)), _M_has_value(true)
482  { }
483 
484  template<typename _Gr = _Er>
485  requires is_constructible_v<_Er, const _Gr&>
486  constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
487  expected(const unexpected<_Gr>& __u)
488  noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
489  : _M_unex(__u.error()), _M_has_value(false)
490  { }
491 
492  template<typename _Gr = _Er>
493  requires is_constructible_v<_Er, _Gr>
494  constexpr explicit(!is_convertible_v<_Gr, _Er>)
495  expected(unexpected<_Gr>&& __u)
496  noexcept(is_nothrow_constructible_v<_Er, _Gr>)
497  : _M_unex(std::move(__u).error()), _M_has_value(false)
498  { }
499 
500  template<typename... _Args>
501  requires is_constructible_v<_Tp, _Args...>
502  constexpr explicit
503  expected(in_place_t, _Args&&... __args)
504  noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
505  : _M_val(std::forward<_Args>(__args)...), _M_has_value(true)
506  { }
507 
508  template<typename _Up, typename... _Args>
509  requires is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
510  constexpr explicit
511  expected(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
512  noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
513  _Args...>)
514  : _M_val(__il, std::forward<_Args>(__args)...), _M_has_value(true)
515  { }
516 
517  template<typename... _Args>
518  requires is_constructible_v<_Er, _Args...>
519  constexpr explicit
520  expected(unexpect_t, _Args&&... __args)
521  noexcept(is_nothrow_constructible_v<_Er, _Args...>)
522  : _M_unex(std::forward<_Args>(__args)...), _M_has_value(false)
523  { }
524 
525  template<typename _Up, typename... _Args>
526  requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
527  constexpr explicit
528  expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
529  noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
530  _Args...>)
531  : _M_unex(__il, std::forward<_Args>(__args)...), _M_has_value(false)
532  { }
533 
534  constexpr ~expected() = default;
535 
536  constexpr ~expected()
537  requires (!is_trivially_destructible_v<_Tp>)
538  || (!is_trivially_destructible_v<_Er>)
539  {
540  if (_M_has_value)
541  std::destroy_at(__builtin_addressof(_M_val));
542  else
543  std::destroy_at(__builtin_addressof(_M_unex));
544  }
545 
546  // assignment
547 
548  expected& operator=(const expected&) = delete;
549 
550  constexpr expected&
551  operator=(const expected& __x)
552  noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
553  is_nothrow_copy_constructible<_Er>,
554  is_nothrow_copy_assignable<_Tp>,
555  is_nothrow_copy_assignable<_Er>>)
556  requires is_copy_assignable_v<_Tp> && is_copy_constructible_v<_Tp>
557  && is_copy_assignable_v<_Er> && is_copy_constructible_v<_Er>
558  && (is_nothrow_move_constructible_v<_Tp>
559  || is_nothrow_move_constructible_v<_Er>)
560  {
561  if (__x._M_has_value)
562  this->_M_assign_val(__x._M_val);
563  else
564  this->_M_assign_unex(__x._M_unex);
565  return *this;
566  }
567 
568  constexpr expected&
569  operator=(expected&& __x)
570  noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
571  is_nothrow_move_constructible<_Er>,
572  is_nothrow_move_assignable<_Tp>,
573  is_nothrow_move_assignable<_Er>>)
574  requires is_move_assignable_v<_Tp> && is_move_constructible_v<_Tp>
575  && is_move_assignable_v<_Er> && is_move_constructible_v<_Er>
576  && (is_nothrow_move_constructible_v<_Tp>
577  || is_nothrow_move_constructible_v<_Er>)
578  {
579  if (__x._M_has_value)
580  _M_assign_val(std::move(__x._M_val));
581  else
582  _M_assign_unex(std::move(__x._M_unex));
583  return *this;
584  }
585 
586  template<typename _Up = _Tp>
587  requires (!is_same_v<expected, remove_cvref_t<_Up>>)
588  && (!__expected::__is_unexpected<remove_cvref_t<_Up>>)
589  && is_constructible_v<_Tp, _Up> && is_assignable_v<_Tp&, _Up>
590  && (is_nothrow_constructible_v<_Tp, _Up>
591  || is_nothrow_move_constructible_v<_Tp>
592  || is_nothrow_move_constructible_v<_Er>)
593  constexpr expected&
594  operator=(_Up&& __v)
595  {
596  _M_assign_val(std::forward<_Up>(__v));
597  return *this;
598  }
599 
600  template<typename _Gr>
601  requires is_constructible_v<_Er, const _Gr&>
602  && is_assignable_v<_Er&, const _Gr&>
603  && (is_nothrow_constructible_v<_Er, const _Gr&>
604  || is_nothrow_move_constructible_v<_Tp>
605  || is_nothrow_move_constructible_v<_Er>)
606  constexpr expected&
607  operator=(const unexpected<_Gr>& __e)
608  {
609  _M_assign_unex(__e.error());
610  return *this;
611  }
612 
613  template<typename _Gr>
614  requires is_constructible_v<_Er, _Gr>
615  && is_assignable_v<_Er&, _Gr>
616  && (is_nothrow_constructible_v<_Er, _Gr>
617  || is_nothrow_move_constructible_v<_Tp>
618  || is_nothrow_move_constructible_v<_Er>)
619  constexpr expected&
620  operator=(unexpected<_Gr>&& __e)
621  {
622  _M_assign_unex(std::move(__e).error());
623  return *this;
624  }
625 
626  // modifiers
627 
628  template<typename... _Args>
629  requires is_nothrow_constructible_v<_Tp, _Args...>
630  constexpr _Tp&
631  emplace(_Args&&... __args) noexcept
632  {
633  if (_M_has_value)
634  std::destroy_at(__builtin_addressof(_M_val));
635  else
636  {
637  std::destroy_at(__builtin_addressof(_M_unex));
638  _M_has_value = true;
639  }
640  std::construct_at(__builtin_addressof(_M_val),
641  std::forward<_Args>(__args)...);
642  return _M_val;
643  }
644 
645  template<typename _Up, typename... _Args>
646  requires is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
647  _Args...>
648  constexpr _Tp&
649  emplace(initializer_list<_Up> __il, _Args&&... __args) noexcept
650  {
651  if (_M_has_value)
652  std::destroy_at(__builtin_addressof(_M_val));
653  else
654  {
655  std::destroy_at(__builtin_addressof(_M_unex));
656  _M_has_value = true;
657  }
658  std::construct_at(__builtin_addressof(_M_val),
659  __il, std::forward<_Args>(__args)...);
660  return _M_val;
661  }
662 
663  // swap
664  constexpr void
665  swap(expected& __x)
666  noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
667  is_nothrow_move_constructible<_Er>,
668  is_nothrow_swappable<_Tp&>,
669  is_nothrow_swappable<_Er&>>)
670  requires is_swappable_v<_Tp> && is_swappable_v<_Er>
671  && is_move_constructible_v<_Tp>
672  && is_move_constructible_v<_Er>
673  && (is_nothrow_move_constructible_v<_Tp>
674  || is_nothrow_move_constructible_v<_Er>)
675  {
676  if (_M_has_value)
677  {
678  if (__x._M_has_value)
679  {
680  using std::swap;
681  swap(_M_val, __x._M_val);
682  }
683  else
684  this->_M_swap_val_unex(__x);
685  }
686  else
687  {
688  if (__x._M_has_value)
689  __x._M_swap_val_unex(*this);
690  else
691  {
692  using std::swap;
693  swap(_M_unex, __x._M_unex);
694  }
695  }
696  }
697 
698  // observers
699 
700  [[nodiscard]]
701  constexpr const _Tp*
702  operator->() const noexcept
703  {
704  __glibcxx_assert(_M_has_value);
705  return __builtin_addressof(_M_val);
706  }
707 
708  [[nodiscard]]
709  constexpr _Tp*
710  operator->() noexcept
711  {
712  __glibcxx_assert(_M_has_value);
713  return __builtin_addressof(_M_val);
714  }
715 
716  [[nodiscard]]
717  constexpr const _Tp&
718  operator*() const & noexcept
719  {
720  __glibcxx_assert(_M_has_value);
721  return _M_val;
722  }
723 
724  [[nodiscard]]
725  constexpr _Tp&
726  operator*() & noexcept
727  {
728  __glibcxx_assert(_M_has_value);
729  return _M_val;
730  }
731 
732  [[nodiscard]]
733  constexpr const _Tp&&
734  operator*() const && noexcept
735  {
736  __glibcxx_assert(_M_has_value);
737  return std::move(_M_val);
738  }
739 
740  [[nodiscard]]
741  constexpr _Tp&&
742  operator*() && noexcept
743  {
744  __glibcxx_assert(_M_has_value);
745  return std::move(_M_val);
746  }
747 
748  [[nodiscard]]
749  constexpr explicit
750  operator bool() const noexcept { return _M_has_value; }
751 
752  [[nodiscard]]
753  constexpr bool has_value() const noexcept { return _M_has_value; }
754 
755  constexpr const _Tp&
756  value() const &
757  {
758  if (_M_has_value) [[likely]]
759  return _M_val;
760  _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex));
761  }
762 
763  constexpr _Tp&
764  value() &
765  {
766  if (_M_has_value) [[likely]]
767  return _M_val;
768  const auto& __unex = _M_unex;
769  _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(__unex));
770  }
771 
772  constexpr const _Tp&&
773  value() const &&
774  {
775  if (_M_has_value) [[likely]]
776  return std::move(_M_val);
777  _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex)));
778  }
779 
780  constexpr _Tp&&
781  value() &&
782  {
783  if (_M_has_value) [[likely]]
784  return std::move(_M_val);
785  _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex)));
786  }
787 
788  constexpr const _Er&
789  error() const & noexcept
790  {
791  __glibcxx_assert(!_M_has_value);
792  return _M_unex;
793  }
794 
795  constexpr _Er&
796  error() & noexcept
797  {
798  __glibcxx_assert(!_M_has_value);
799  return _M_unex;
800  }
801 
802  constexpr const _Er&&
803  error() const && noexcept
804  {
805  __glibcxx_assert(!_M_has_value);
806  return std::move(_M_unex);
807  }
808 
809  constexpr _Er&&
810  error() && noexcept
811  {
812  __glibcxx_assert(!_M_has_value);
813  return std::move(_M_unex);
814  }
815 
816  template<typename _Up>
817  constexpr _Tp
818  value_or(_Up&& __v) const &
819  noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
820  is_nothrow_convertible<_Up, _Tp>>)
821  {
822  static_assert( is_copy_constructible_v<_Tp> );
823  static_assert( is_convertible_v<_Up, _Tp> );
824 
825  if (_M_has_value)
826  return _M_val;
827  return static_cast<_Tp>(std::forward<_Up>(__v));
828  }
829 
830  template<typename _Up>
831  constexpr _Tp
832  value_or(_Up&& __v) &&
833  noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
834  is_nothrow_convertible<_Up, _Tp>>)
835  {
836  static_assert( is_move_constructible_v<_Tp> );
837  static_assert( is_convertible_v<_Up, _Tp> );
838 
839  if (_M_has_value)
840  return std::move(_M_val);
841  return static_cast<_Tp>(std::forward<_Up>(__v));
842  }
843 
844  template<typename _Gr = _Er>
845  constexpr _Er
846  error_or(_Gr&& __e) const&
847  {
848  static_assert( is_copy_constructible_v<_Er> );
849  static_assert( is_convertible_v<_Gr, _Er> );
850 
851  if (_M_has_value)
852  return std::forward<_Gr>(__e);
853  return _M_unex;
854  }
855 
856  template<typename _Gr = _Er>
857  constexpr _Er
858  error_or(_Gr&& __e) &&
859  {
860  static_assert( is_move_constructible_v<_Er> );
861  static_assert( is_convertible_v<_Gr, _Er> );
862 
863  if (_M_has_value)
864  return std::forward<_Gr>(__e);
865  return std::move(_M_unex);
866  }
867 
868  // monadic operations
869 
870  template<typename _Fn> requires is_constructible_v<_Er, _Er&>
871  constexpr auto
872  and_then(_Fn&& __f) &
873  {
874  using _Up = __expected::__result<_Fn, _Tp&>;
875  static_assert(__expected::__is_expected<_Up>,
876  "the function passed to std::expected<T, E>::and_then "
877  "must return a std::expected");
878  static_assert(is_same_v<typename _Up::error_type, _Er>,
879  "the function passed to std::expected<T, E>::and_then "
880  "must return a std::expected with the same error_type");
881 
882  if (has_value())
883  return std::__invoke(std::forward<_Fn>(__f), _M_val);
884  else
885  return _Up(unexpect, _M_unex);
886  }
887 
888  template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
889  constexpr auto
890  and_then(_Fn&& __f) const &
891  {
892  using _Up = __expected::__result<_Fn, const _Tp&>;
893  static_assert(__expected::__is_expected<_Up>,
894  "the function passed to std::expected<T, E>::and_then "
895  "must return a std::expected");
896  static_assert(is_same_v<typename _Up::error_type, _Er>,
897  "the function passed to std::expected<T, E>::and_then "
898  "must return a std::expected with the same error_type");
899 
900  if (has_value())
901  return std::__invoke(std::forward<_Fn>(__f), _M_val);
902  else
903  return _Up(unexpect, _M_unex);
904  }
905 
906  template<typename _Fn> requires is_constructible_v<_Er, _Er>
907  constexpr auto
908  and_then(_Fn&& __f) &&
909  {
910  using _Up = __expected::__result<_Fn, _Tp&&>;
911  static_assert(__expected::__is_expected<_Up>,
912  "the function passed to std::expected<T, E>::and_then "
913  "must return a std::expected");
914  static_assert(is_same_v<typename _Up::error_type, _Er>,
915  "the function passed to std::expected<T, E>::and_then "
916  "must return a std::expected with the same error_type");
917 
918  if (has_value())
919  return std::__invoke(std::forward<_Fn>(__f), std::move(_M_val));
920  else
921  return _Up(unexpect, std::move(_M_unex));
922  }
923 
924 
925  template<typename _Fn> requires is_constructible_v<_Er, const _Er>
926  constexpr auto
927  and_then(_Fn&& __f) const &&
928  {
929  using _Up = __expected::__result<_Fn, const _Tp&&>;
930  static_assert(__expected::__is_expected<_Up>,
931  "the function passed to std::expected<T, E>::and_then "
932  "must return a std::expected");
933  static_assert(is_same_v<typename _Up::error_type, _Er>,
934  "the function passed to std::expected<T, E>::and_then "
935  "must return a std::expected with the same error_type");
936 
937  if (has_value())
938  return std::__invoke(std::forward<_Fn>(__f), std::move(_M_val));
939  else
940  return _Up(unexpect, std::move(_M_unex));
941  }
942 
943  template<typename _Fn> requires is_constructible_v<_Tp, _Tp&>
944  constexpr auto
945  or_else(_Fn&& __f) &
946  {
947  using _Gr = __expected::__result<_Fn, _Er&>;
948  static_assert(__expected::__is_expected<_Gr>,
949  "the function passed to std::expected<T, E>::or_else "
950  "must return a std::expected");
951  static_assert(is_same_v<typename _Gr::value_type, _Tp>,
952  "the function passed to std::expected<T, E>::or_else "
953  "must return a std::expected with the same value_type");
954 
955  if (has_value())
956  return _Gr(in_place, _M_val);
957  else
958  return std::__invoke(std::forward<_Fn>(__f), _M_unex);
959  }
960 
961  template<typename _Fn> requires is_constructible_v<_Tp, const _Tp&>
962  constexpr auto
963  or_else(_Fn&& __f) const &
964  {
965  using _Gr = __expected::__result<_Fn, const _Er&>;
966  static_assert(__expected::__is_expected<_Gr>,
967  "the function passed to std::expected<T, E>::or_else "
968  "must return a std::expected");
969  static_assert(is_same_v<typename _Gr::value_type, _Tp>,
970  "the function passed to std::expected<T, E>::or_else "
971  "must return a std::expected with the same value_type");
972 
973  if (has_value())
974  return _Gr(in_place, _M_val);
975  else
976  return std::__invoke(std::forward<_Fn>(__f), _M_unex);
977  }
978 
979 
980  template<typename _Fn> requires is_constructible_v<_Tp, _Tp>
981  constexpr auto
982  or_else(_Fn&& __f) &&
983  {
984  using _Gr = __expected::__result<_Fn, _Er&&>;
985  static_assert(__expected::__is_expected<_Gr>,
986  "the function passed to std::expected<T, E>::or_else "
987  "must return a std::expected");
988  static_assert(is_same_v<typename _Gr::value_type, _Tp>,
989  "the function passed to std::expected<T, E>::or_else "
990  "must return a std::expected with the same value_type");
991 
992  if (has_value())
993  return _Gr(in_place, std::move(_M_val));
994  else
995  return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
996  }
997 
998  template<typename _Fn> requires is_constructible_v<_Tp, const _Tp>
999  constexpr auto
1000  or_else(_Fn&& __f) const &&
1001  {
1002  using _Gr = __expected::__result<_Fn, const _Er&&>;
1003  static_assert(__expected::__is_expected<_Gr>,
1004  "the function passed to std::expected<T, E>::or_else "
1005  "must return a std::expected");
1006  static_assert(is_same_v<typename _Gr::value_type, _Tp>,
1007  "the function passed to std::expected<T, E>::or_else "
1008  "must return a std::expected with the same value_type");
1009 
1010  if (has_value())
1011  return _Gr(in_place, std::move(_M_val));
1012  else
1013  return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
1014  }
1015 
1016  template<typename _Fn> requires is_constructible_v<_Er, _Er&>
1017  constexpr auto
1018  transform(_Fn&& __f) &
1019  {
1020  using _Up = __expected::__result_xform<_Fn, _Tp&>;
1021  using _Res = expected<_Up, _Er>;
1022 
1023  if (has_value())
1024  return _Res(__in_place_inv{}, [&]() {
1025  return std::__invoke(std::forward<_Fn>(__f),
1026  _M_val);
1027  });
1028  else
1029  return _Res(unexpect, _M_unex);
1030  }
1031 
1032  template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
1033  constexpr auto
1034  transform(_Fn&& __f) const &
1035  {
1036  using _Up = __expected::__result_xform<_Fn, const _Tp&>;
1037  using _Res = expected<_Up, _Er>;
1038 
1039  if (has_value())
1040  return _Res(__in_place_inv{}, [&]() {
1041  return std::__invoke(std::forward<_Fn>(__f),
1042  _M_val);
1043  });
1044  else
1045  return _Res(unexpect, _M_unex);
1046  }
1047 
1048  template<typename _Fn> requires is_constructible_v<_Er, _Er>
1049  constexpr auto
1050  transform(_Fn&& __f) &&
1051  {
1052  using _Up = __expected::__result_xform<_Fn, _Tp>;
1053  using _Res = expected<_Up, _Er>;
1054 
1055  if (has_value())
1056  return _Res(__in_place_inv{}, [&]() {
1057  return std::__invoke(std::forward<_Fn>(__f),
1058  std::move(_M_val));
1059  });
1060  else
1061  return _Res(unexpect, std::move(_M_unex));
1062  }
1063 
1064  template<typename _Fn> requires is_constructible_v<_Er, const _Er>
1065  constexpr auto
1066  transform(_Fn&& __f) const &&
1067  {
1068  using _Up = __expected::__result_xform<_Fn, const _Tp>;
1069  using _Res = expected<_Up, _Er>;
1070 
1071  if (has_value())
1072  return _Res(__in_place_inv{}, [&]() {
1073  return std::__invoke(std::forward<_Fn>(__f),
1074  std::move(_M_val));
1075  });
1076  else
1077  return _Res(unexpect, std::move(_M_unex));
1078  }
1079 
1080  template<typename _Fn> requires is_constructible_v<_Tp, _Tp&>
1081  constexpr auto
1082  transform_error(_Fn&& __f) &
1083  {
1084  using _Gr = __expected::__result_xform<_Fn, _Er&>;
1085  using _Res = expected<_Tp, _Gr>;
1086 
1087  if (has_value())
1088  return _Res(in_place, _M_val);
1089  else
1090  return _Res(__unexpect_inv{}, [&]() {
1091  return std::__invoke(std::forward<_Fn>(__f),
1092  _M_unex);
1093  });
1094  }
1095 
1096  template<typename _Fn> requires is_constructible_v<_Tp, const _Tp&>
1097  constexpr auto
1098  transform_error(_Fn&& __f) const &
1099  {
1100  using _Gr = __expected::__result_xform<_Fn, const _Er&>;
1101  using _Res = expected<_Tp, _Gr>;
1102 
1103  if (has_value())
1104  return _Res(in_place, _M_val);
1105  else
1106  return _Res(__unexpect_inv{}, [&]() {
1107  return std::__invoke(std::forward<_Fn>(__f),
1108  _M_unex);
1109  });
1110  }
1111 
1112  template<typename _Fn> requires is_constructible_v<_Tp, _Tp>
1113  constexpr auto
1114  transform_error(_Fn&& __f) &&
1115  {
1116  using _Gr = __expected::__result_xform<_Fn, _Er&&>;
1117  using _Res = expected<_Tp, _Gr>;
1118 
1119  if (has_value())
1120  return _Res(in_place, std::move(_M_val));
1121  else
1122  return _Res(__unexpect_inv{}, [&]() {
1123  return std::__invoke(std::forward<_Fn>(__f),
1124  std::move(_M_unex));
1125  });
1126  }
1127 
1128  template<typename _Fn> requires is_constructible_v<_Tp, const _Tp>
1129  constexpr auto
1130  transform_error(_Fn&& __f) const &&
1131  {
1132  using _Gr = __expected::__result_xform<_Fn, const _Er&&>;
1133  using _Res = expected<_Tp, _Gr>;
1134 
1135  if (has_value())
1136  return _Res(in_place, std::move(_M_val));
1137  else
1138  return _Res(__unexpect_inv{}, [&]() {
1139  return std::__invoke(std::forward<_Fn>(__f),
1140  std::move(_M_unex));
1141  });
1142  }
1143 
1144  // equality operators
1145 
1146  template<typename _Up, typename _Er2>
1147  requires (!is_void_v<_Up>)
1148  friend constexpr bool
1149  operator==(const expected& __x, const expected<_Up, _Er2>& __y)
1150  // FIXME: noexcept(noexcept(bool(*__x == *__y))
1151  // && noexcept(bool(__x.error() == __y.error())))
1152  {
1153  if (__x.has_value())
1154  return __y.has_value() && bool(*__x == *__y);
1155  else
1156  return !__y.has_value() && bool(__x.error() == __y.error());
1157  }
1158 
1159  template<typename _Up>
1160  friend constexpr bool
1161  operator==(const expected& __x, const _Up& __v)
1162  // FIXME: noexcept(noexcept(bool(*__x == __v)))
1163  { return __x.has_value() && bool(*__x == __v); }
1164 
1165  template<typename _Er2>
1166  friend constexpr bool
1167  operator==(const expected& __x, const unexpected<_Er2>& __e)
1168  // FIXME: noexcept(noexcept(bool(__x.error() == __e.error())))
1169  { return !__x.has_value() && bool(__x.error() == __e.error()); }
1170 
1171  friend constexpr void
1172  swap(expected& __x, expected& __y)
1173  noexcept(noexcept(__x.swap(__y)))
1174  requires requires {__x.swap(__y);}
1175  { __x.swap(__y); }
1176 
1177  private:
1178  template<typename, typename> friend class expected;
1179 
1180  template<typename _Vp>
1181  constexpr void
1182  _M_assign_val(_Vp&& __v)
1183  {
1184  if (_M_has_value)
1185  _M_val = std::forward<_Vp>(__v);
1186  else
1187  {
1188  __expected::__reinit(__builtin_addressof(_M_val),
1189  __builtin_addressof(_M_unex),
1190  std::forward<_Vp>(__v));
1191  _M_has_value = true;
1192  }
1193  }
1194 
1195  template<typename _Vp>
1196  constexpr void
1197  _M_assign_unex(_Vp&& __v)
1198  {
1199  if (_M_has_value)
1200  {
1201  __expected::__reinit(__builtin_addressof(_M_unex),
1202  __builtin_addressof(_M_val),
1203  std::forward<_Vp>(__v));
1204  _M_has_value = false;
1205  }
1206  else
1207  _M_unex = std::forward<_Vp>(__v);
1208  }
1209 
1210  // Swap two expected objects when only one has a value.
1211  // Precondition: this->_M_has_value && !__rhs._M_has_value
1212  constexpr void
1213  _M_swap_val_unex(expected& __rhs)
1214  noexcept(__and_v<is_nothrow_move_constructible<_Er>,
1215  is_nothrow_move_constructible<_Tp>>)
1216  {
1217  if constexpr (is_nothrow_move_constructible_v<_Er>)
1218  {
1219  __expected::_Guard<_Er> __guard(__rhs._M_unex);
1220  std::construct_at(__builtin_addressof(__rhs._M_val),
1221  std::move(_M_val)); // might throw
1222  __rhs._M_has_value = true;
1223  std::destroy_at(__builtin_addressof(_M_val));
1224  std::construct_at(__builtin_addressof(_M_unex),
1225  __guard.release());
1226  _M_has_value = false;
1227  }
1228  else
1229  {
1230  __expected::_Guard<_Tp> __guard(_M_val);
1231  std::construct_at(__builtin_addressof(_M_unex),
1232  std::move(__rhs._M_unex)); // might throw
1233  _M_has_value = false;
1234  std::destroy_at(__builtin_addressof(__rhs._M_unex));
1235  std::construct_at(__builtin_addressof(__rhs._M_val),
1236  __guard.release());
1237  __rhs._M_has_value = true;
1238  }
1239  }
1240 
1241  using __in_place_inv = __expected::__in_place_inv;
1242  using __unexpect_inv = __expected::__unexpect_inv;
1243 
1244  template<typename _Fn>
1245  explicit constexpr
1246  expected(__in_place_inv, _Fn&& __fn)
1247  : _M_val(std::forward<_Fn>(__fn)()), _M_has_value(true)
1248  { }
1249 
1250  template<typename _Fn>
1251  explicit constexpr
1252  expected(__unexpect_inv, _Fn&& __fn)
1253  : _M_unex(std::forward<_Fn>(__fn)()), _M_has_value(false)
1254  { }
1255 
1256  union {
1257  _Tp _M_val;
1258  _Er _M_unex;
1259  };
1260 
1261  bool _M_has_value;
1262  };
1263 
1264  // Partial specialization for std::expected<cv void, E>
1265  template<typename _Tp, typename _Er> requires is_void_v<_Tp>
1266  class expected<_Tp, _Er>
1267  {
1268  static_assert( __expected::__can_be_unexpected<_Er> );
1269 
1270  template<typename _Up, typename _Err, typename _Unex = unexpected<_Er>>
1271  static constexpr bool __cons_from_expected
1272  = __or_v<is_constructible<_Unex, expected<_Up, _Err>&>,
1273  is_constructible<_Unex, expected<_Up, _Err>>,
1274  is_constructible<_Unex, const expected<_Up, _Err>&>,
1275  is_constructible<_Unex, const expected<_Up, _Err>>
1276  >;
1277 
1278  template<typename _Up>
1279  static constexpr bool __same_val
1280  = is_same_v<typename _Up::value_type, _Tp>;
1281 
1282  template<typename _Up>
1283  static constexpr bool __same_err
1284  = is_same_v<typename _Up::error_type, _Er>;
1285 
1286  public:
1287  using value_type = _Tp;
1288  using error_type = _Er;
1289  using unexpected_type = unexpected<_Er>;
1290 
1291  template<typename _Up>
1292  using rebind = expected<_Up, error_type>;
1293 
1294  constexpr
1295  expected() noexcept
1296  : _M_void(), _M_has_value(true)
1297  { }
1298 
1299  expected(const expected&) = default;
1300 
1301  constexpr
1302  expected(const expected& __x)
1303  noexcept(is_nothrow_copy_constructible_v<_Er>)
1304  requires is_copy_constructible_v<_Er>
1305  && (!is_trivially_copy_constructible_v<_Er>)
1306  : _M_void(), _M_has_value(__x._M_has_value)
1307  {
1308  if (!_M_has_value)
1309  std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
1310  }
1311 
1312  expected(expected&&) = default;
1313 
1314  constexpr
1315  expected(expected&& __x)
1316  noexcept(is_nothrow_move_constructible_v<_Er>)
1317  requires is_move_constructible_v<_Er>
1318  && (!is_trivially_move_constructible_v<_Er>)
1319  : _M_void(), _M_has_value(__x._M_has_value)
1320  {
1321  if (!_M_has_value)
1322  std::construct_at(__builtin_addressof(_M_unex),
1323  std::move(__x)._M_unex);
1324  }
1325 
1326  template<typename _Up, typename _Gr>
1327  requires is_void_v<_Up>
1328  && is_constructible_v<_Er, const _Gr&>
1329  && (!__cons_from_expected<_Up, _Gr>)
1330  constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
1331  expected(const expected<_Up, _Gr>& __x)
1332  noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
1333  : _M_void(), _M_has_value(__x._M_has_value)
1334  {
1335  if (!_M_has_value)
1336  std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
1337  }
1338 
1339  template<typename _Up, typename _Gr>
1340  requires is_void_v<_Up>
1341  && is_constructible_v<_Er, _Gr>
1342  && (!__cons_from_expected<_Up, _Gr>)
1343  constexpr explicit(!is_convertible_v<_Gr, _Er>)
1344  expected(expected<_Up, _Gr>&& __x)
1345  noexcept(is_nothrow_constructible_v<_Er, _Gr>)
1346  : _M_void(), _M_has_value(__x._M_has_value)
1347  {
1348  if (!_M_has_value)
1349  std::construct_at(__builtin_addressof(_M_unex),
1350  std::move(__x)._M_unex);
1351  }
1352 
1353  template<typename _Gr = _Er>
1354  requires is_constructible_v<_Er, const _Gr&>
1355  constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
1356  expected(const unexpected<_Gr>& __u)
1357  noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
1358  : _M_unex(__u.error()), _M_has_value(false)
1359  { }
1360 
1361  template<typename _Gr = _Er>
1362  requires is_constructible_v<_Er, _Gr>
1363  constexpr explicit(!is_convertible_v<_Gr, _Er>)
1364  expected(unexpected<_Gr>&& __u)
1365  noexcept(is_nothrow_constructible_v<_Er, _Gr>)
1366  : _M_unex(std::move(__u).error()), _M_has_value(false)
1367  { }
1368 
1369  constexpr explicit
1370  expected(in_place_t) noexcept
1371  : expected()
1372  { }
1373 
1374  template<typename... _Args>
1375  requires is_constructible_v<_Er, _Args...>
1376  constexpr explicit
1377  expected(unexpect_t, _Args&&... __args)
1378  noexcept(is_nothrow_constructible_v<_Er, _Args...>)
1379  : _M_unex(std::forward<_Args>(__args)...), _M_has_value(false)
1380  { }
1381 
1382  template<typename _Up, typename... _Args>
1383  requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
1384  constexpr explicit
1385  expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
1386  noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
1387  _Args...>)
1388  : _M_unex(__il, std::forward<_Args>(__args)...), _M_has_value(false)
1389  { }
1390 
1391  constexpr ~expected() = default;
1392 
1393  constexpr ~expected() requires (!is_trivially_destructible_v<_Er>)
1394  {
1395  if (!_M_has_value)
1396  std::destroy_at(__builtin_addressof(_M_unex));
1397  }
1398 
1399  // assignment
1400 
1401  expected& operator=(const expected&) = delete;
1402 
1403  constexpr expected&
1404  operator=(const expected& __x)
1405  noexcept(__and_v<is_nothrow_copy_constructible<_Er>,
1406  is_nothrow_copy_assignable<_Er>>)
1407  requires is_copy_constructible_v<_Er>
1408  && is_copy_assignable_v<_Er>
1409  {
1410  if (__x._M_has_value)
1411  emplace();
1412  else
1413  _M_assign_unex(__x._M_unex);
1414  return *this;
1415  }
1416 
1417  constexpr expected&
1418  operator=(expected&& __x)
1419  noexcept(__and_v<is_nothrow_move_constructible<_Er>,
1420  is_nothrow_move_assignable<_Er>>)
1421  requires is_move_constructible_v<_Er>
1422  && is_move_assignable_v<_Er>
1423  {
1424  if (__x._M_has_value)
1425  emplace();
1426  else
1427  _M_assign_unex(std::move(__x._M_unex));
1428  return *this;
1429  }
1430 
1431  template<typename _Gr>
1432  requires is_constructible_v<_Er, const _Gr&>
1433  && is_assignable_v<_Er&, const _Gr&>
1434  constexpr expected&
1435  operator=(const unexpected<_Gr>& __e)
1436  {
1437  _M_assign_unex(__e.error());
1438  return *this;
1439  }
1440 
1441  template<typename _Gr>
1442  requires is_constructible_v<_Er, _Gr>
1443  && is_assignable_v<_Er&, _Gr>
1444  constexpr expected&
1445  operator=(unexpected<_Gr>&& __e)
1446  {
1447  _M_assign_unex(std::move(__e.error()));
1448  return *this;
1449  }
1450 
1451  // modifiers
1452 
1453  constexpr void
1454  emplace() noexcept
1455  {
1456  if (!_M_has_value)
1457  {
1458  std::destroy_at(__builtin_addressof(_M_unex));
1459  _M_has_value = true;
1460  }
1461  }
1462 
1463  // swap
1464  constexpr void
1465  swap(expected& __x)
1466  noexcept(__and_v<is_nothrow_swappable<_Er&>,
1467  is_nothrow_move_constructible<_Er>>)
1468  requires is_swappable_v<_Er> && is_move_constructible_v<_Er>
1469  {
1470  if (_M_has_value)
1471  {
1472  if (!__x._M_has_value)
1473  {
1474  std::construct_at(__builtin_addressof(_M_unex),
1475  std::move(__x._M_unex)); // might throw
1476  std::destroy_at(__builtin_addressof(__x._M_unex));
1477  _M_has_value = false;
1478  __x._M_has_value = true;
1479  }
1480  }
1481  else
1482  {
1483  if (__x._M_has_value)
1484  {
1485  std::construct_at(__builtin_addressof(__x._M_unex),
1486  std::move(_M_unex)); // might throw
1487  std::destroy_at(__builtin_addressof(_M_unex));
1488  _M_has_value = true;
1489  __x._M_has_value = false;
1490  }
1491  else
1492  {
1493  using std::swap;
1494  swap(_M_unex, __x._M_unex);
1495  }
1496  }
1497  }
1498 
1499  // observers
1500 
1501  [[nodiscard]]
1502  constexpr explicit
1503  operator bool() const noexcept { return _M_has_value; }
1504 
1505  [[nodiscard]]
1506  constexpr bool has_value() const noexcept { return _M_has_value; }
1507 
1508  constexpr void
1509  operator*() const noexcept { __glibcxx_assert(_M_has_value); }
1510 
1511  constexpr void
1512  value() const&
1513  {
1514  if (_M_has_value) [[likely]]
1515  return;
1516  _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex));
1517  }
1518 
1519  constexpr void
1520  value() &&
1521  {
1522  if (_M_has_value) [[likely]]
1523  return;
1524  _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex)));
1525  }
1526 
1527  constexpr const _Er&
1528  error() const & noexcept
1529  {
1530  __glibcxx_assert(!_M_has_value);
1531  return _M_unex;
1532  }
1533 
1534  constexpr _Er&
1535  error() & noexcept
1536  {
1537  __glibcxx_assert(!_M_has_value);
1538  return _M_unex;
1539  }
1540 
1541  constexpr const _Er&&
1542  error() const && noexcept
1543  {
1544  __glibcxx_assert(!_M_has_value);
1545  return std::move(_M_unex);
1546  }
1547 
1548  constexpr _Er&&
1549  error() && noexcept
1550  {
1551  __glibcxx_assert(!_M_has_value);
1552  return std::move(_M_unex);
1553  }
1554 
1555  template<typename _Gr = _Er>
1556  constexpr _Er
1557  error_or(_Gr&& __e) const&
1558  {
1559  static_assert( is_copy_constructible_v<_Er> );
1560  static_assert( is_convertible_v<_Gr, _Er> );
1561 
1562  if (_M_has_value)
1563  return std::forward<_Gr>(__e);
1564  return _M_unex;
1565  }
1566 
1567  template<typename _Gr = _Er>
1568  constexpr _Er
1569  error_or(_Gr&& __e) &&
1570  {
1571  static_assert( is_move_constructible_v<_Er> );
1572  static_assert( is_convertible_v<_Gr, _Er> );
1573 
1574  if (_M_has_value)
1575  return std::forward<_Gr>(__e);
1576  return std::move(_M_unex);
1577  }
1578 
1579  // monadic operations
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, _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, _M_unex);
1607  }
1608 
1609  template<typename _Fn> requires is_constructible_v<_Er, _Er>
1610  constexpr auto
1611  and_then(_Fn&& __f) &&
1612  {
1613  using _Up = __expected::__result0<_Fn>;
1614  static_assert(__expected::__is_expected<_Up>);
1615  static_assert(is_same_v<typename _Up::error_type, _Er>);
1616 
1617  if (has_value())
1618  return std::__invoke(std::forward<_Fn>(__f));
1619  else
1620  return _Up(unexpect, std::move(_M_unex));
1621  }
1622 
1623  template<typename _Fn> requires is_constructible_v<_Er, const _Er>
1624  constexpr auto
1625  and_then(_Fn&& __f) const &&
1626  {
1627  using _Up = __expected::__result0<_Fn>;
1628  static_assert(__expected::__is_expected<_Up>);
1629  static_assert(is_same_v<typename _Up::error_type, _Er>);
1630 
1631  if (has_value())
1632  return std::__invoke(std::forward<_Fn>(__f));
1633  else
1634  return _Up(unexpect, std::move(_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), _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), _M_unex);
1663  }
1664 
1665  template<typename _Fn>
1666  constexpr auto
1667  or_else(_Fn&& __f) &&
1668  {
1669  using _Gr = __expected::__result<_Fn, _Er&&>;
1670  static_assert(__expected::__is_expected<_Gr>);
1671  static_assert(is_same_v<typename _Gr::value_type, _Tp>);
1672 
1673  if (has_value())
1674  return _Gr();
1675  else
1676  return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
1677  }
1678 
1679  template<typename _Fn>
1680  constexpr auto
1681  or_else(_Fn&& __f) const &&
1682  {
1683  using _Gr = __expected::__result<_Fn, const _Er&&>;
1684  static_assert(__expected::__is_expected<_Gr>);
1685  static_assert(is_same_v<typename _Gr::value_type, _Tp>);
1686 
1687  if (has_value())
1688  return _Gr();
1689  else
1690  return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
1691  }
1692 
1693  template<typename _Fn> requires is_constructible_v<_Er, _Er&>
1694  constexpr auto
1695  transform(_Fn&& __f) &
1696  {
1697  using _Up = __expected::__result0_xform<_Fn>;
1698  using _Res = expected<_Up, _Er>;
1699 
1700  if (has_value())
1701  return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
1702  else
1703  return _Res(unexpect, _M_unex);
1704  }
1705 
1706  template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
1707  constexpr auto
1708  transform(_Fn&& __f) const &
1709  {
1710  using _Up = __expected::__result0_xform<_Fn>;
1711  using _Res = expected<_Up, _Er>;
1712 
1713  if (has_value())
1714  return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
1715  else
1716  return _Res(unexpect, _M_unex);
1717  }
1718 
1719  template<typename _Fn> requires is_constructible_v<_Er, _Er>
1720  constexpr auto
1721  transform(_Fn&& __f) &&
1722  {
1723  using _Up = __expected::__result0_xform<_Fn>;
1724  using _Res = expected<_Up, _Er>;
1725 
1726  if (has_value())
1727  return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
1728  else
1729  return _Res(unexpect, std::move(_M_unex));
1730  }
1731 
1732  template<typename _Fn> requires is_constructible_v<_Er, const _Er>
1733  constexpr auto
1734  transform(_Fn&& __f) const &&
1735  {
1736  using _Up = __expected::__result0_xform<_Fn>;
1737  using _Res = expected<_Up, _Er>;
1738 
1739  if (has_value())
1740  return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
1741  else
1742  return _Res(unexpect, std::move(_M_unex));
1743  }
1744 
1745  template<typename _Fn>
1746  constexpr auto
1747  transform_error(_Fn&& __f) &
1748  {
1749  using _Gr = __expected::__result_xform<_Fn, _Er&>;
1750  using _Res = expected<_Tp, _Gr>;
1751 
1752  if (has_value())
1753  return _Res();
1754  else
1755  return _Res(__unexpect_inv{}, [&]() {
1756  return std::__invoke(std::forward<_Fn>(__f),
1757  _M_unex);
1758  });
1759  }
1760 
1761  template<typename _Fn>
1762  constexpr auto
1763  transform_error(_Fn&& __f) const &
1764  {
1765  using _Gr = __expected::__result_xform<_Fn, const _Er&>;
1766  using _Res = expected<_Tp, _Gr>;
1767 
1768  if (has_value())
1769  return _Res();
1770  else
1771  return _Res(__unexpect_inv{}, [&]() {
1772  return std::__invoke(std::forward<_Fn>(__f),
1773  _M_unex);
1774  });
1775  }
1776 
1777  template<typename _Fn>
1778  constexpr auto
1779  transform_error(_Fn&& __f) &&
1780  {
1781  using _Gr = __expected::__result_xform<_Fn, _Er&&>;
1782  using _Res = expected<_Tp, _Gr>;
1783 
1784  if (has_value())
1785  return _Res();
1786  else
1787  return _Res(__unexpect_inv{}, [&]() {
1788  return std::__invoke(std::forward<_Fn>(__f),
1789  std::move(_M_unex));
1790  });
1791  }
1792 
1793  template<typename _Fn>
1794  constexpr auto
1795  transform_error(_Fn&& __f) const &&
1796  {
1797  using _Gr = __expected::__result_xform<_Fn, const _Er&&>;
1798  using _Res = expected<_Tp, _Gr>;
1799 
1800  if (has_value())
1801  return _Res();
1802  else
1803  return _Res(__unexpect_inv{}, [&]() {
1804  return std::__invoke(std::forward<_Fn>(__f),
1805  std::move(_M_unex));
1806  });
1807  }
1808 
1809  // equality operators
1810 
1811  template<typename _Up, typename _Er2>
1812  requires is_void_v<_Up>
1813  friend constexpr bool
1814  operator==(const expected& __x, const expected<_Up, _Er2>& __y)
1815  // FIXME: noexcept(noexcept(bool(__x.error() == __y.error())))
1816  {
1817  if (__x.has_value())
1818  return __y.has_value();
1819  else
1820  return !__y.has_value() && bool(__x.error() == __y.error());
1821  }
1822 
1823  template<typename _Er2>
1824  friend constexpr bool
1825  operator==(const expected& __x, const unexpected<_Er2>& __e)
1826  // FIXME: noexcept(noexcept(bool(__x.error() == __e.error())))
1827  { return !__x.has_value() && bool(__x.error() == __e.error()); }
1828 
1829  friend constexpr void
1830  swap(expected& __x, expected& __y)
1831  noexcept(noexcept(__x.swap(__y)))
1832  requires requires { __x.swap(__y); }
1833  { __x.swap(__y); }
1834 
1835  private:
1836  template<typename, typename> friend class expected;
1837 
1838  template<typename _Vp>
1839  constexpr void
1840  _M_assign_unex(_Vp&& __v)
1841  {
1842  if (_M_has_value)
1843  {
1844  std::construct_at(__builtin_addressof(_M_unex),
1845  std::forward<_Vp>(__v));
1846  _M_has_value = false;
1847  }
1848  else
1849  _M_unex = std::forward<_Vp>(__v);
1850  }
1851 
1852  using __in_place_inv = __expected::__in_place_inv;
1853  using __unexpect_inv = __expected::__unexpect_inv;
1854 
1855  template<typename _Fn>
1856  explicit constexpr
1857  expected(__in_place_inv, _Fn&& __fn)
1858  : _M_void(), _M_has_value(true)
1859  { std::forward<_Fn>(__fn)(); }
1860 
1861  template<typename _Fn>
1862  explicit constexpr
1863  expected(__unexpect_inv, _Fn&& __fn)
1864  : _M_unex(std::forward<_Fn>(__fn)()), _M_has_value(false)
1865  { }
1866 
1867  union {
1868  struct { } _M_void;
1869  _Er _M_unex;
1870  };
1871 
1872  bool _M_has_value;
1873  };
1874  /// @}
1875 
1876 _GLIBCXX_END_NAMESPACE_VERSION
1877 } // namespace std
1878 
1879 #endif // __cpp_lib_expected
1880 #endif // _GLIBCXX_EXPECTED