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