libstdc++
optional
Go to the documentation of this file.
1 // <optional> -*- C++ -*-
2 
3 // Copyright (C) 2013-2026 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_optional_range_support
40 #define __glibcxx_want_constrained_equality
41 #define __glibcxx_want_constexpr_exceptions
42 #include <bits/version.h>
43 
44 #ifdef __cpp_lib_optional // C++ >= 17
45 
46 #include <type_traits>
47 #include <exception>
48 #include <new>
49 #include <initializer_list>
50 #include <bits/enable_special_members.h>
51 #include <bits/exception_defines.h>
52 #include <bits/functional_hash.h>
53 #include <bits/stl_construct.h> // _Construct
54 #include <bits/utility.h> // in_place_t
55 #if __cplusplus > 201703L
56 # include <compare>
57 # include <bits/invoke.h> // std::__invoke
58 #endif
59 #if __cplusplus > 202002L
60 # include <concepts>
61 #endif
62 #ifdef __cpp_lib_optional_range_support // C++ >= 26
63 # if _GLIBCXX_HOSTED
64 # include <bits/formatfwd.h>
65 # endif
66 # include <bits/ranges_base.h>
67 # include <bits/stl_iterator.h>
68 #endif
69 
70 namespace std _GLIBCXX_VISIBILITY(default)
71 {
72 _GLIBCXX_BEGIN_NAMESPACE_VERSION
73 
74  /**
75  * @addtogroup utilities
76  * @{
77  */
78 
79  template<typename _Tp>
80  class optional;
81 
82  /// Tag type to disengage optional objects.
83  struct nullopt_t
84  {
85  // Do not user-declare default constructor at all for
86  // optional_value = {} syntax to work.
87  // nullopt_t() = delete;
88 
89  // Used for constructing nullopt.
90  enum class _Construct { _Token };
91 
92  // Must be constexpr for nullopt_t to be literal.
93  explicit constexpr nullopt_t(_Construct) noexcept { }
94  };
95 
96  /// Tag to disengage optional objects.
97  inline constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token };
98 
99  template<typename _Fn> struct _Optional_func { _Fn& _M_f; };
100 
101  /**
102  * @brief Exception class thrown when a disengaged optional object is
103  * dereferenced.
104  * @ingroup exceptions
105  */
106  class bad_optional_access : public exception
107  {
108  public:
109  bad_optional_access() = default;
110  virtual ~bad_optional_access() = default;
111 
112 #if __cpp_lib_constexpr_exceptions >= 202502L
113  constexpr
114 #endif
115  const char* what() const noexcept override
116  { return "bad optional access"; }
117  };
118 
119  // XXX Does not belong here.
120  [[__noreturn__]]
121 #if __cpp_lib_constexpr_exceptions >= 202502L
122  constexpr
123 #else
124  inline
125 #endif
126  void
127  __throw_bad_optional_access()
128  { _GLIBCXX_THROW_OR_ABORT(bad_optional_access()); }
129 
130  // This class template manages construction/destruction of
131  // the contained value for a std::optional.
132  template <typename _Tp>
133  struct _Optional_payload_base
134  {
135  using _Stored_type = remove_const_t<_Tp>;
136 
137  _Optional_payload_base() = default;
138  ~_Optional_payload_base() = default;
139 
140  template<typename... _Args>
141  constexpr
142  _Optional_payload_base(in_place_t __tag, _Args&&... __args)
143  : _M_payload(__tag, std::forward<_Args>(__args)...),
144  _M_engaged(true)
145  { }
146 
147  template<typename _Up, typename... _Args>
148  constexpr
149  _Optional_payload_base(std::initializer_list<_Up> __il,
150  _Args&&... __args)
151  : _M_payload(__il, std::forward<_Args>(__args)...),
152  _M_engaged(true)
153  { }
154 
155  // Constructor used by _Optional_base copy constructor when the
156  // contained value is not trivially copy constructible.
157  constexpr
158  _Optional_payload_base(bool /* __engaged */,
159  const _Optional_payload_base& __other)
160  {
161  if (__other._M_engaged)
162  this->_M_construct(__other._M_get());
163  }
164 
165  // Constructor used by _Optional_base move constructor when the
166  // contained value is not trivially move constructible.
167  constexpr
168  _Optional_payload_base(bool /* __engaged */,
169  _Optional_payload_base&& __other)
170  {
171  if (__other._M_engaged)
172  this->_M_construct(std::move(__other._M_get()));
173  }
174 
175  // Copy constructor is only used to when the contained value is
176  // trivially copy constructible.
177  _Optional_payload_base(const _Optional_payload_base&) = default;
178 
179  // Move constructor is only used to when the contained value is
180  // trivially copy constructible.
181  _Optional_payload_base(_Optional_payload_base&&) = default;
182 
183  _Optional_payload_base&
184  operator=(const _Optional_payload_base&) = default;
185 
186  _Optional_payload_base&
187  operator=(_Optional_payload_base&&) = default;
188 
189  // used to perform non-trivial copy assignment.
190  constexpr void
191  _M_copy_assign(const _Optional_payload_base& __other)
192  {
193  if (this->_M_engaged && __other._M_engaged)
194  this->_M_get() = __other._M_get();
195  else
196  {
197  if (__other._M_engaged)
198  this->_M_construct(__other._M_get());
199  else
200  this->_M_reset();
201  }
202  }
203 
204  // used to perform non-trivial move assignment.
205  constexpr void
206  _M_move_assign(_Optional_payload_base&& __other)
207  noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
208  is_nothrow_move_assignable<_Tp>>)
209  {
210  if (this->_M_engaged && __other._M_engaged)
211  this->_M_get() = std::move(__other._M_get());
212  else
213  {
214  if (__other._M_engaged)
215  this->_M_construct(std::move(__other._M_get()));
216  else
217  this->_M_reset();
218  }
219  }
220 
221  struct _Empty_byte { };
222 
223  template<typename _Up, bool = is_trivially_destructible_v<_Up>>
224  union _Storage
225  {
226  constexpr _Storage() noexcept : _M_empty() { }
227 
228  template<typename... _Args>
229  constexpr
230  _Storage(in_place_t, _Args&&... __args)
231  : _M_value(std::forward<_Args>(__args)...)
232  { }
233 
234  template<typename _Vp, typename... _Args>
235  constexpr
236  _Storage(std::initializer_list<_Vp> __il, _Args&&... __args)
237  : _M_value(__il, std::forward<_Args>(__args)...)
238  { }
239 
240 #if __cplusplus >= 202002L
241  template<typename _Fn, typename _Arg>
242  constexpr
243  _Storage(_Optional_func<_Fn> __f, _Arg&& __arg)
244  : _M_value(std::__invoke(std::forward<_Fn>(__f._M_f),
245  std::forward<_Arg>(__arg)))
246  { }
247 #endif
248 
249 #if __cpp_concepts >= 202002L // Conditionally trivial special member functions
250  ~_Storage() = default;
251 
252  // User-provided destructor is needed when _Up has non-trivial dtor.
253  _GLIBCXX20_CONSTEXPR
254  ~_Storage() requires (!is_trivially_destructible_v<_Up>)
255  { }
256 
257  _Storage(const _Storage&) = default;
258  _Storage(_Storage&&) = default;
259  _Storage& operator=(const _Storage&) = default;
260  _Storage& operator=(_Storage&&) = default;
261 #endif
262 
263  _Empty_byte _M_empty;
264  _Up _M_value;
265  };
266 
267 #if __cpp_concepts < 202002L
268  template<typename _Up>
269  union _Storage<_Up, false>
270  {
271  constexpr _Storage() noexcept : _M_empty() { }
272 
273  template<typename... _Args>
274  constexpr
275  _Storage(in_place_t, _Args&&... __args)
276  : _M_value(std::forward<_Args>(__args)...)
277  { }
278 
279  template<typename _Vp, typename... _Args>
280  constexpr
281  _Storage(std::initializer_list<_Vp> __il, _Args&&... __args)
282  : _M_value(__il, std::forward<_Args>(__args)...)
283  { }
284 
285 #if __cplusplus >= 202002L
286  template<typename _Fn, typename _Arg>
287  constexpr
288  _Storage(_Optional_func<_Fn> __f, _Arg&& __arg)
289  : _M_value(std::__invoke(std::forward<_Fn>(__f._M_f),
290  std::forward<_Arg>(__arg)))
291  { }
292 #endif
293 
294  // User-provided destructor is needed when _Up has non-trivial dtor.
295  _GLIBCXX20_CONSTEXPR ~_Storage() { }
296 
297  _Storage(const _Storage&) = default;
298  _Storage(_Storage&&) = default;
299  _Storage& operator=(const _Storage&) = default;
300  _Storage& operator=(_Storage&&) = default;
301 
302  _Empty_byte _M_empty;
303  _Up _M_value;
304  };
305 #endif
306 
307  _Storage<_Stored_type> _M_payload;
308 
309  bool _M_engaged = false;
310 
311  template<typename... _Args>
312  constexpr void
313  _M_construct(_Args&&... __args)
314  noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
315  {
316  std::_Construct(std::__addressof(this->_M_payload._M_value),
317  std::forward<_Args>(__args)...);
318  this->_M_engaged = true;
319  }
320 
321  constexpr void
322  _M_destroy() noexcept
323  {
324  _M_engaged = false;
325  _M_payload._M_value.~_Stored_type();
326 #if defined(__clang__) && __cpp_lib_optional >= 202106L // full constexpr support
327  if (std::is_constant_evaluated())
328  // Work around PR124910 for Clang.
329  std::construct_at(std::__addressof(_M_payload._M_empty));
330 #endif
331  }
332 
333 #if __cplusplus >= 202002L
334  template<typename _Fn, typename _Up>
335  constexpr void
336  _M_apply(_Optional_func<_Fn> __f, _Up&& __x)
337  {
338  std::construct_at(std::__addressof(this->_M_payload),
339  __f, std::forward<_Up>(__x));
340  _M_engaged = true;
341  }
342 #endif
343 
344  // The _M_get() operations have _M_engaged as a precondition.
345  // They exist to access the contained value with the appropriate
346  // const-qualification, because _M_payload has had the const removed.
347 
348  constexpr _Tp&
349  _M_get() noexcept
350  { return this->_M_payload._M_value; }
351 
352  constexpr const _Tp&
353  _M_get() const noexcept
354  { return this->_M_payload._M_value; }
355 
356  // _M_reset is a 'safe' operation with no precondition.
357  constexpr void
358  _M_reset() noexcept
359  {
360  if (this->_M_engaged)
361  _M_destroy();
362  else // This seems redundant but improves codegen, see PR 112480.
363  this->_M_engaged = false;
364  }
365  };
366 
367  // Class template that manages the payload for optionals.
368  template <typename _Tp,
369  bool /*_HasTrivialDestructor*/ =
370  is_trivially_destructible_v<_Tp>,
371  bool /*_HasTrivialCopy */ =
372  is_trivially_copy_assignable_v<_Tp>
373  && is_trivially_copy_constructible_v<_Tp>,
374  bool /*_HasTrivialMove */ =
375  is_trivially_move_assignable_v<_Tp>
376  && is_trivially_move_constructible_v<_Tp>>
377  struct _Optional_payload;
378 
379  // Payload for potentially-constexpr optionals (trivial copy/move/destroy).
380  template <typename _Tp>
381  struct _Optional_payload<_Tp, true, true, true>
382  : _Optional_payload_base<_Tp>
383  {
384  using _Optional_payload_base<_Tp>::_Optional_payload_base;
385 
386  _Optional_payload() = default;
387  };
388 
389  // Payload for optionals with non-trivial copy construction/assignment.
390  template <typename _Tp>
391  struct _Optional_payload<_Tp, true, false, true>
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=(_Optional_payload&&) = default;
401 
402  // Non-trivial copy assignment.
403  constexpr
404  _Optional_payload&
405  operator=(const _Optional_payload& __other)
406  {
407  this->_M_copy_assign(__other);
408  return *this;
409  }
410  };
411 
412  // Payload for optionals with non-trivial move construction/assignment.
413  template <typename _Tp>
414  struct _Optional_payload<_Tp, true, true, false>
415  : _Optional_payload_base<_Tp>
416  {
417  using _Optional_payload_base<_Tp>::_Optional_payload_base;
418 
419  _Optional_payload() = default;
420  ~_Optional_payload() = default;
421  _Optional_payload(const _Optional_payload&) = default;
422  _Optional_payload(_Optional_payload&&) = default;
423  _Optional_payload& operator=(const _Optional_payload&) = default;
424 
425  // Non-trivial move assignment.
426  constexpr
427  _Optional_payload&
428  operator=(_Optional_payload&& __other)
429  noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
430  is_nothrow_move_assignable<_Tp>>)
431  {
432  this->_M_move_assign(std::move(__other));
433  return *this;
434  }
435  };
436 
437  // Payload for optionals with non-trivial copy and move assignment.
438  template <typename _Tp>
439  struct _Optional_payload<_Tp, true, false, false>
440  : _Optional_payload_base<_Tp>
441  {
442  using _Optional_payload_base<_Tp>::_Optional_payload_base;
443 
444  _Optional_payload() = default;
445  ~_Optional_payload() = default;
446  _Optional_payload(const _Optional_payload&) = default;
447  _Optional_payload(_Optional_payload&&) = default;
448 
449  // Non-trivial copy assignment.
450  constexpr
451  _Optional_payload&
452  operator=(const _Optional_payload& __other)
453  {
454  this->_M_copy_assign(__other);
455  return *this;
456  }
457 
458  // Non-trivial move assignment.
459  constexpr
460  _Optional_payload&
461  operator=(_Optional_payload&& __other)
462  noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
463  is_nothrow_move_assignable<_Tp>>)
464  {
465  this->_M_move_assign(std::move(__other));
466  return *this;
467  }
468  };
469 
470  // Payload for optionals with non-trivial destructors.
471  template <typename _Tp, bool _Copy, bool _Move>
472  struct _Optional_payload<_Tp, false, _Copy, _Move>
473  : _Optional_payload<_Tp, true, false, false>
474  {
475  // Base class implements all the constructors and assignment operators:
476  using _Optional_payload<_Tp, true, false, false>::_Optional_payload;
477  _Optional_payload() = default;
478  _Optional_payload(const _Optional_payload&) = default;
479  _Optional_payload(_Optional_payload&&) = default;
480  _Optional_payload& operator=(const _Optional_payload&) = default;
481  _Optional_payload& operator=(_Optional_payload&&) = default;
482 
483  // Destructor needs to destroy the contained value:
484  _GLIBCXX20_CONSTEXPR ~_Optional_payload() { this->_M_reset(); }
485  };
486 
487  /**
488  * @brief Class template that provides copy/move constructors of optional.
489  *
490  * Such a separate base class template is necessary in order to
491  * conditionally make copy/move constructors trivial.
492  *
493  * When the contained value is trivially copy/move constructible,
494  * the copy/move constructors of _Optional_base will invoke the
495  * trivial copy/move constructor of _Optional_payload. Otherwise,
496  * they will invoke _Optional_payload(bool, const _Optional_payload&)
497  * or _Optional_payload(bool, _Optional_payload&&) to initialize
498  * the contained value, if copying/moving an engaged optional.
499  *
500  * Whether the other special members are trivial is determined by the
501  * _Optional_payload<_Tp> specialization used for the _M_payload member.
502  *
503  * @see optional, _Enable_special_members
504  */
505  template<typename _Tp,
506  bool = is_trivially_copy_constructible_v<_Tp>,
507  bool = is_trivially_move_constructible_v<_Tp>>
508  struct _Optional_base
509  {
510  // Constructors for disengaged optionals.
511  constexpr _Optional_base() = default;
512 
513  // Constructors for engaged optionals.
514  template<typename... _Args,
515  enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
516  constexpr explicit
517  _Optional_base(in_place_t, _Args&&... __args)
518  : _M_payload(in_place, std::forward<_Args>(__args)...)
519  { }
520 
521  template<typename _Up, typename... _Args,
522  enable_if_t<is_constructible_v<_Tp,
523  initializer_list<_Up>&,
524  _Args...>, bool> = false>
525  constexpr explicit
526  _Optional_base(in_place_t,
527  initializer_list<_Up> __il,
528  _Args&&... __args)
529  : _M_payload(in_place, __il, std::forward<_Args>(__args)...)
530  { }
531 
532  // Copy and move constructors.
533  constexpr
534  _Optional_base(const _Optional_base& __other)
535  noexcept(is_nothrow_copy_constructible_v<_Tp>)
536  : _M_payload(__other._M_payload._M_engaged, __other._M_payload)
537  { }
538 
539  constexpr
540  _Optional_base(_Optional_base&& __other)
541  noexcept(is_nothrow_move_constructible_v<_Tp>)
542  : _M_payload(__other._M_payload._M_engaged,
543  std::move(__other._M_payload))
544  { }
545 
546 #if __cpp_concepts >= 202002L // Conditionally trivial special member functions
547  // Define these in the primary template if possible, so that we don't
548  // need to use partial specializations of this class template.
549  constexpr _Optional_base(const _Optional_base&)
550  requires is_trivially_copy_constructible_v<_Tp> = default;
551 
552  constexpr _Optional_base(_Optional_base&&)
553  requires is_trivially_move_constructible_v<_Tp> = default;
554 #endif
555 
556  // Assignment operators.
557  _Optional_base& operator=(const _Optional_base&) = default;
558  _Optional_base& operator=(_Optional_base&&) = default;
559 
560  _Optional_payload<_Tp> _M_payload;
561 
562  protected:
563  // For the primary template, we define these functions here.
564  using _Stored_type = remove_const_t<_Tp>;
565 
566  // The _M_construct operation has !_M_engaged as a precondition
567  // while _M_destruct has _M_engaged as a precondition.
568  template<typename... _Args>
569  constexpr void
570  _M_construct(_Args&&... __args)
571  noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
572  {
573  _M_payload._M_construct(std::forward<_Args>(__args)...);
574  }
575 
576  constexpr void
577  _M_destruct() noexcept
578  { _M_payload._M_destroy(); }
579 
580  // _M_reset is a 'safe' operation with no precondition.
581  constexpr void
582  _M_reset() noexcept
583  { _M_payload._M_reset(); }
584 
585  constexpr bool _M_is_engaged() const noexcept
586  { return _M_payload._M_engaged; }
587 
588  // The _M_get operations have _M_engaged as a precondition.
589  constexpr _Tp&
590  _M_get() noexcept
591  { return _M_payload._M_get(); }
592 
593  constexpr const _Tp&
594  _M_get() const noexcept
595  { return _M_payload._M_get(); }
596  };
597 
598 #if __cpp_concepts < 202002L
599  // If P0848R3 "Conditionally Trivial Special Member Functions" is not
600  // supported (as determined from the __cpp_concepts macro value), the
601  // _Optional_base primary template only has non-trivial copy and move
602  // constructors. Use partial specializations of _Optional_base<T, C, M>
603  // that have a trivial copy and/or move constructor.
604 
605  // Common base class for _Optional_base<T> to avoid repeating these
606  // member functions in each partial specialization.
607  // Only used if P0848R3 "Conditionally Trivial Special Member Functions"
608  // is not supported, as indicated by the __cpp_concepts value.
609  template<typename _Tp, typename _Dp>
610  class _Optional_base_impl
611  {
612  protected:
613  using _Stored_type = remove_const_t<_Tp>;
614 
615  // The _M_construct operation has !_M_engaged as a precondition
616  // while _M_destruct has _M_engaged as a precondition.
617  template<typename... _Args>
618  constexpr void
619  _M_construct(_Args&&... __args)
620  noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
621  {
622  static_cast<_Dp*>(this)->_M_payload._M_construct(
623  std::forward<_Args>(__args)...);
624  }
625 
626  constexpr void
627  _M_destruct() noexcept
628  { static_cast<_Dp*>(this)->_M_payload._M_destroy(); }
629 
630  // _M_reset is a 'safe' operation with no precondition.
631  constexpr void
632  _M_reset() noexcept
633  { static_cast<_Dp*>(this)->_M_payload._M_reset(); }
634 
635  constexpr bool _M_is_engaged() const noexcept
636  { return static_cast<const _Dp*>(this)->_M_payload._M_engaged; }
637 
638  // The _M_get operations have _M_engaged as a precondition.
639  constexpr _Tp&
640  _M_get() noexcept
641  { return static_cast<_Dp*>(this)->_M_payload._M_get(); }
642 
643  constexpr const _Tp&
644  _M_get() const noexcept
645  { return static_cast<const _Dp*>(this)->_M_payload._M_get(); }
646  };
647 
648  template<typename _Tp>
649  struct _Optional_base<_Tp, false, true> // trivial move ctor
650  : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
651  {
652  // Constructors for disengaged optionals.
653  constexpr _Optional_base() = default;
654 
655  // Constructors for engaged optionals.
656  template<typename... _Args,
657  enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
658  constexpr explicit
659  _Optional_base(in_place_t, _Args&&... __args)
660  : _M_payload(in_place, std::forward<_Args>(__args)...)
661  { }
662 
663  template<typename _Up, typename... _Args,
664  enable_if_t<is_constructible_v<_Tp,
665  initializer_list<_Up>&,
666  _Args...>, bool> = false>
667  constexpr explicit
668  _Optional_base(in_place_t,
669  initializer_list<_Up> __il,
670  _Args... __args)
671  : _M_payload(in_place, __il, std::forward<_Args>(__args)...)
672  { }
673 
674  // Copy and move constructors.
675  constexpr _Optional_base(const _Optional_base& __other)
676  : _M_payload(__other._M_payload._M_engaged, __other._M_payload)
677  { }
678 
679  constexpr _Optional_base(_Optional_base&& __other) = default;
680 
681  // Assignment operators.
682  _Optional_base& operator=(const _Optional_base&) = default;
683  _Optional_base& operator=(_Optional_base&&) = default;
684 
685  _Optional_payload<_Tp> _M_payload;
686  };
687 
688  template<typename _Tp>
689  struct _Optional_base<_Tp, true, false> // trivial copy ctor
690  : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
691  {
692  // Constructors for disengaged optionals.
693  constexpr _Optional_base() = default;
694 
695  // Constructors for engaged optionals.
696  template<typename... _Args,
697  enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
698  constexpr explicit
699  _Optional_base(in_place_t, _Args&&... __args)
700  : _M_payload(in_place, std::forward<_Args>(__args)...)
701  { }
702 
703  template<typename _Up, typename... _Args,
704  enable_if_t<is_constructible_v<_Tp,
705  initializer_list<_Up>&,
706  _Args...>, bool> = false>
707  constexpr explicit
708  _Optional_base(in_place_t,
709  initializer_list<_Up> __il,
710  _Args&&... __args)
711  : _M_payload(in_place, __il, std::forward<_Args>(__args)...)
712  { }
713 
714  // Copy and move constructors.
715  constexpr _Optional_base(const _Optional_base& __other) = default;
716 
717  constexpr
718  _Optional_base(_Optional_base&& __other)
719  noexcept(is_nothrow_move_constructible_v<_Tp>)
720  : _M_payload(__other._M_payload._M_engaged,
721  std::move(__other._M_payload))
722  { }
723 
724  // Assignment operators.
725  _Optional_base& operator=(const _Optional_base&) = default;
726  _Optional_base& operator=(_Optional_base&&) = default;
727 
728  _Optional_payload<_Tp> _M_payload;
729  };
730 
731  template<typename _Tp>
732  struct _Optional_base<_Tp, true, true> // trivial copy and move ctors
733  : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
734  {
735  // Constructors for disengaged optionals.
736  constexpr _Optional_base() = default;
737 
738  // Constructors for engaged optionals.
739  template<typename... _Args,
740  enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
741  constexpr explicit
742  _Optional_base(in_place_t, _Args&&... __args)
743  : _M_payload(in_place, std::forward<_Args>(__args)...)
744  { }
745 
746  template<typename _Up, typename... _Args,
747  enable_if_t<is_constructible_v<_Tp,
748  initializer_list<_Up>&,
749  _Args...>, bool> = false>
750  constexpr explicit
751  _Optional_base(in_place_t,
752  initializer_list<_Up> __il,
753  _Args&&... __args)
754  : _M_payload(in_place, __il, std::forward<_Args>(__args)...)
755  { }
756 
757  // Copy and move constructors.
758  constexpr _Optional_base(const _Optional_base& __other) = default;
759  constexpr _Optional_base(_Optional_base&& __other) = default;
760 
761  // Assignment operators.
762  _Optional_base& operator=(const _Optional_base&) = default;
763  _Optional_base& operator=(_Optional_base&&) = default;
764 
765  _Optional_payload<_Tp> _M_payload;
766  };
767 #endif // __cpp_concepts
768 
769  template<typename _Tp>
770  inline constexpr bool __is_optional_v = false;
771  template<typename _Tp>
772  inline constexpr bool __is_optional_v<optional<_Tp>> = true;
773 
774  template<typename _Tp, typename _Wp>
775  using __converts_from_any_cvref = __or_<
776  is_constructible<_Tp, _Wp&>, is_convertible<_Wp&, _Tp>,
777  is_constructible<_Tp, _Wp>, is_convertible<_Wp, _Tp>,
778  is_constructible<_Tp, const _Wp&>, is_convertible<const _Wp&, _Tp>,
779  is_constructible<_Tp, const _Wp>, is_convertible<const _Wp, _Tp>
780  >;
781 
782  template<typename _Tp, typename _Up>
783  using __converts_from_optional
784  = __converts_from_any_cvref<_Tp, optional<_Up>>;
785 
786  template<typename _Tp, typename _Up>
787  using __assigns_from_optional =
788  __or_<is_assignable<_Tp&, const optional<_Up>&>,
789  is_assignable<_Tp&, optional<_Up>&>,
790  is_assignable<_Tp&, const optional<_Up>&&>,
791  is_assignable<_Tp&, optional<_Up>&&>>;
792 
793 #if __cpp_concepts && __cpp_conditional_explicit && __glibcxx_remove_cvref
794 # define _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL 1
795 #endif
796 
797  template<typename _Tp>
798  inline constexpr bool __is_valid_contained_type_for_optional =
799  (
800 #if __cpp_lib_optional >= 202506L
801  is_lvalue_reference_v<_Tp> ||
802 #endif
803  (is_object_v<_Tp> && is_destructible_v<_Tp> && !is_array_v<_Tp>)
804  )
805  && !is_same_v<remove_cv_t<remove_reference_t<_Tp>>, nullopt_t>
806  && !is_same_v<remove_cv_t<remove_reference_t<_Tp>>, in_place_t>;
807 
808  /**
809  * @brief Class template for optional values.
810  */
811  template<typename _Tp>
812  class optional
813  : private _Optional_base<_Tp>,
814  private _Enable_copy_move<
815  // Copy constructor.
816  is_copy_constructible_v<_Tp>,
817  // Copy assignment.
818  __and_v<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>,
819  // Move constructor.
820  is_move_constructible_v<_Tp>,
821  // Move assignment.
822  __and_v<is_move_constructible<_Tp>, is_move_assignable<_Tp>>,
823  // Unique tag type.
824  optional<_Tp>>
825  {
826  static_assert(__is_valid_contained_type_for_optional<_Tp>);
827 
828  private:
829  using _Base = _Optional_base<_Tp>;
830 
831  // SFINAE helpers
832 
833  // _GLIBCXX_RESOLVE_LIB_DEFECTS
834  // 3836. std::expected<bool, E1> conversion constructor
835  // expected(const expected<U, G>&) should take precedence over
836  // expected(U&&) with operator bool
837 #ifdef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL
838  template<typename _From, typename = remove_cv_t<_Tp>>
839  static constexpr bool __not_constructing_bool_from_optional
840  = true;
841 
842  // If T is cv bool, remove_cvref_t<U> is not a specialization of optional
843  // i.e. do not initialize a bool from optional<U>::operator bool().
844  template<typename _From>
845  static constexpr bool
846  __not_constructing_bool_from_optional<_From, bool>
847  = !__is_optional_v<remove_cvref_t<_From>>;
848 
849  // If T is not cv bool, converts-from-any-cvref<T, optional<U>> is false.
850  // The constructor that converts from optional<U> is disabled if the
851  // contained value can be initialized from optional<U>, so that the
852  // optional(U&&) constructor can be used instead.
853  template<typename _From, typename = remove_cv_t<_Tp>>
854  static constexpr bool __construct_from_contained_value
855  = !__converts_from_optional<_Tp, _From>::value;
856 
857  // However, optional<U> can always be converted to bool, so don't apply
858  // this constraint when T is cv bool.
859  template<typename _From>
860  static constexpr bool __construct_from_contained_value<_From, bool>
861  = true;
862 #else
863  template<typename _From, typename = remove_cv_t<_Tp>>
864  struct __not_constructing_bool_from_optional
865  : true_type
866  { };
867 
868  template<typename _From>
869  struct __not_constructing_bool_from_optional<_From, bool>
870  : bool_constant<!__is_optional_v<__remove_cvref_t<_From>>>
871  { };
872 
873  template<typename _From, typename = remove_cv_t<_Tp>>
874  struct __construct_from_contained_value
875  : __not_<__converts_from_optional<_Tp, _From>>
876  { };
877 
878  template<typename _From>
879  struct __construct_from_contained_value<_From, bool>
880  : true_type
881  { };
882 
883  template<typename _Up>
884  using __not_self = __not_<is_same<optional, __remove_cvref_t<_Up>>>;
885  template<typename _Up>
886  using __not_tag = __not_<is_same<in_place_t, __remove_cvref_t<_Up>>>;
887  template<typename... _Cond>
888  using _Requires = enable_if_t<__and_v<_Cond...>, bool>;
889 #endif
890 
891  public:
892  using value_type = _Tp;
893 #ifdef __cpp_lib_optional_range_support // >= C++26
894  using iterator = __gnu_cxx::__normal_iterator<_Tp*, optional>;
895  using const_iterator = __gnu_cxx::__normal_iterator<const _Tp*, optional>;
896 #endif
897 
898  constexpr optional() noexcept { }
899 
900  constexpr optional(nullopt_t) noexcept { }
901 
902  // Converting constructors for engaged optionals.
903 #ifdef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL
904  template<typename _Up = remove_cv_t<_Tp>>
905  requires (!is_same_v<optional, remove_cvref_t<_Up>>)
906  && (!is_same_v<in_place_t, remove_cvref_t<_Up>>)
907  && is_constructible_v<_Tp, _Up>
908  && __not_constructing_bool_from_optional<_Up>
909  constexpr explicit(!is_convertible_v<_Up, _Tp>)
910  optional(_Up&& __t)
911  noexcept(is_nothrow_constructible_v<_Tp, _Up>)
912  : _Base(std::in_place, std::forward<_Up>(__t)) { }
913 
914  template<typename _Up>
915  requires (!is_same_v<_Tp, _Up>)
916  && is_constructible_v<_Tp, const _Up&>
917  && __construct_from_contained_value<_Up>
918  constexpr explicit(!is_convertible_v<const _Up&, _Tp>)
919  optional(const optional<_Up>& __t)
920  noexcept(is_nothrow_constructible_v<_Tp, const _Up&>)
921  {
922  if (__t)
923  emplace(__t._M_fwd());
924  }
925 
926  template<typename _Up>
927  requires (!is_same_v<_Tp, _Up>)
928  && is_constructible_v<_Tp, _Up>
929  && __construct_from_contained_value<_Up>
930  constexpr explicit(!is_convertible_v<_Up, _Tp>)
931  optional(optional<_Up>&& __t)
932  noexcept(is_nothrow_constructible_v<_Tp, _Up>)
933  {
934  if (__t)
935  emplace(std::move(__t)._M_fwd());
936  }
937 
938  template<typename... _Args>
939  requires is_constructible_v<_Tp, _Args...>
940  explicit constexpr
941  optional(in_place_t, _Args&&... __args)
942  noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
943  : _Base(std::in_place, std::forward<_Args>(__args)...)
944  { }
945 
946  template<typename _Up, typename... _Args>
947  requires is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
948  explicit constexpr
949  optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
950  noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
951  _Args...>)
952  : _Base(std::in_place, __il, std::forward<_Args>(__args)...)
953  { }
954 #else
955  template<typename _Up = remove_cv_t<_Tp>,
956  _Requires<__not_self<_Up>, __not_tag<_Up>,
957  is_constructible<_Tp, _Up>,
958  is_convertible<_Up, _Tp>,
959  __not_constructing_bool_from_optional<_Up>> = true>
960  constexpr
961  optional(_Up&& __t)
962  noexcept(is_nothrow_constructible_v<_Tp, _Up>)
963  : _Base(std::in_place, std::forward<_Up>(__t)) { }
964 
965  template<typename _Up = remove_cv_t<_Tp>,
966  _Requires<__not_self<_Up>, __not_tag<_Up>,
967  is_constructible<_Tp, _Up>,
968  __not_<is_convertible<_Up, _Tp>>,
969  __not_constructing_bool_from_optional<_Up>> = false>
970  explicit constexpr
971  optional(_Up&& __t)
972  noexcept(is_nothrow_constructible_v<_Tp, _Up>)
973  : _Base(std::in_place, std::forward<_Up>(__t)) { }
974 
975  template<typename _Up,
976  _Requires<__not_<is_same<_Tp, _Up>>,
977  is_constructible<_Tp, const _Up&>,
978  is_convertible<const _Up&, _Tp>,
979  __construct_from_contained_value<_Up>> = true>
980  constexpr
981  optional(const optional<_Up>& __t)
982  noexcept(is_nothrow_constructible_v<_Tp, const _Up&>)
983  {
984  if (__t)
985  emplace(__t._M_fwd());
986  }
987 
988  template<typename _Up,
989  _Requires<__not_<is_same<_Tp, _Up>>,
990  is_constructible<_Tp, const _Up&>,
991  __not_<is_convertible<const _Up&, _Tp>>,
992  __construct_from_contained_value<_Up>> = false>
993  explicit constexpr
994  optional(const optional<_Up>& __t)
995  noexcept(is_nothrow_constructible_v<_Tp, const _Up&>)
996  {
997  if (__t)
998  emplace(__t._M_fwd());
999  }
1000 
1001  template<typename _Up,
1002  _Requires<__not_<is_same<_Tp, _Up>>,
1003  is_constructible<_Tp, _Up>,
1004  is_convertible<_Up, _Tp>,
1005  __construct_from_contained_value<_Up>> = true>
1006  constexpr
1007  optional(optional<_Up>&& __t)
1008  noexcept(is_nothrow_constructible_v<_Tp, _Up>)
1009  {
1010  if (__t)
1011  emplace(std::move(__t)._M_fwd());
1012  }
1013 
1014  template<typename _Up,
1015  _Requires<__not_<is_same<_Tp, _Up>>,
1016  is_constructible<_Tp, _Up>,
1017  __not_<is_convertible<_Up, _Tp>>,
1018  __construct_from_contained_value<_Up>> = false>
1019  explicit constexpr
1020  optional(optional<_Up>&& __t)
1021  noexcept(is_nothrow_constructible_v<_Tp, _Up>)
1022  {
1023  if (__t)
1024  emplace(std::move(__t)._M_fwd());
1025  }
1026 
1027  template<typename... _Args,
1028  _Requires<is_constructible<_Tp, _Args...>> = false>
1029  explicit constexpr
1030  optional(in_place_t, _Args&&... __args)
1031  noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
1032  : _Base(std::in_place, std::forward<_Args>(__args)...) { }
1033 
1034  template<typename _Up, typename... _Args,
1035  _Requires<is_constructible<_Tp,
1036  initializer_list<_Up>&,
1037  _Args...>> = false>
1038  explicit constexpr
1039  optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
1040  noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
1041  _Args...>)
1042  : _Base(std::in_place, __il, std::forward<_Args>(__args)...) { }
1043 #endif
1044 
1045  // Assignment operators.
1046  _GLIBCXX20_CONSTEXPR optional&
1047  operator=(nullopt_t) noexcept
1048  {
1049  this->_M_reset();
1050  return *this;
1051  }
1052 
1053  template<typename _Up = remove_cv_t<_Tp>>
1054 #ifdef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL
1055  requires (!is_same_v<optional, remove_cvref_t<_Up>>)
1056  && (!(is_scalar_v<_Tp> && is_same_v<_Tp, decay_t<_Up>>))
1057  && is_constructible_v<_Tp, _Up>
1058  && is_assignable_v<_Tp&, _Up>
1059  constexpr optional&
1060 #else
1061  enable_if_t<__and_v<__not_self<_Up>,
1062  __not_<__and_<is_scalar<_Tp>,
1063  is_same<_Tp, decay_t<_Up>>>>,
1064  is_constructible<_Tp, _Up>,
1065  is_assignable<_Tp&, _Up>>,
1066  optional&>
1067 #endif
1068  operator=(_Up&& __u)
1069  noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>,
1070  is_nothrow_assignable<_Tp&, _Up>>)
1071  {
1072  if (this->_M_is_engaged())
1073  this->_M_get() = std::forward<_Up>(__u);
1074  else
1075  this->_M_construct(std::forward<_Up>(__u));
1076 
1077  return *this;
1078  }
1079 
1080  template<typename _Up>
1081 #ifdef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL
1082  requires (!is_same_v<_Tp, _Up>)
1083  && is_constructible_v<_Tp, const _Up&>
1084  && is_assignable_v<_Tp&, const _Up&>
1085  && (!__converts_from_optional<_Tp, _Up>::value)
1086  && (!__assigns_from_optional<_Tp, _Up>::value)
1087  constexpr optional&
1088 #else
1089  enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
1090  is_constructible<_Tp, const _Up&>,
1091  is_assignable<_Tp&, const _Up&>,
1092  __not_<__converts_from_optional<_Tp, _Up>>,
1093  __not_<__assigns_from_optional<_Tp, _Up>>>,
1094  optional&>
1095 #endif
1096  operator=(const optional<_Up>& __u)
1097  noexcept(__and_v<is_nothrow_constructible<_Tp, const _Up&>,
1098  is_nothrow_assignable<_Tp&, const _Up&>>)
1099  {
1100  if (__u)
1101  {
1102  if (this->_M_is_engaged())
1103  this->_M_get() = __u._M_fwd();
1104  else
1105  this->_M_construct(__u._M_fwd());
1106  }
1107  else
1108  {
1109  this->_M_reset();
1110  }
1111  return *this;
1112  }
1113 
1114  template<typename _Up>
1115 #ifdef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL
1116  requires (!is_same_v<_Tp, _Up>)
1117  && is_constructible_v<_Tp, _Up>
1118  && is_assignable_v<_Tp&, _Up>
1119  && (!__converts_from_optional<_Tp, _Up>::value)
1120  && (!__assigns_from_optional<_Tp, _Up>::value)
1121  constexpr optional&
1122 #else
1123  enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
1124  is_constructible<_Tp, _Up>,
1125  is_assignable<_Tp&, _Up>,
1126  __not_<__converts_from_optional<_Tp, _Up>>,
1127  __not_<__assigns_from_optional<_Tp, _Up>>>,
1128  optional&>
1129 #endif
1130  operator=(optional<_Up>&& __u)
1131  noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>,
1132  is_nothrow_assignable<_Tp&, _Up>>)
1133  {
1134  if (__u)
1135  {
1136  if (this->_M_is_engaged())
1137  this->_M_get() = std::move(__u)._M_fwd();
1138  else
1139  this->_M_construct(std::move(__u)._M_fwd());
1140  }
1141  else
1142  {
1143  this->_M_reset();
1144  }
1145 
1146  return *this;
1147  }
1148 
1149  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1150  // 2746. Inconsistency between requirements for emplace between optional and variant
1151  template<typename... _Args>
1152  _GLIBCXX20_CONSTEXPR
1153  enable_if_t<is_constructible_v<_Tp, _Args...>, _Tp&>
1154  emplace(_Args&&... __args)
1155  noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
1156  {
1157  this->_M_reset();
1158  this->_M_construct(std::forward<_Args>(__args)...);
1159  return this->_M_get();
1160  }
1161 
1162  template<typename _Up, typename... _Args>
1163  _GLIBCXX20_CONSTEXPR
1164  enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1165  _Tp&>
1166  emplace(initializer_list<_Up> __il, _Args&&... __args)
1167  noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
1168  _Args...>)
1169  {
1170  this->_M_reset();
1171  this->_M_construct(__il, std::forward<_Args>(__args)...);
1172  return this->_M_get();
1173  }
1174 
1175  // Destructor is implicit, implemented in _Optional_base.
1176 
1177  // Swap.
1178  _GLIBCXX20_CONSTEXPR void
1179  swap(optional& __other)
1180  noexcept(is_nothrow_move_constructible_v<_Tp>
1181  && is_nothrow_swappable_v<_Tp>)
1182  {
1183  using std::swap;
1184 
1185  if (this->_M_is_engaged() && __other._M_is_engaged())
1186  swap(this->_M_get(), __other._M_get());
1187  else if (this->_M_is_engaged())
1188  {
1189  __other._M_construct(std::move(this->_M_get()));
1190  this->_M_destruct();
1191  }
1192  else if (__other._M_is_engaged())
1193  {
1194  this->_M_construct(std::move(__other._M_get()));
1195  __other._M_destruct();
1196  }
1197  }
1198 
1199 #ifdef __cpp_lib_optional_range_support // >= C++26
1200  // Iterator support.
1201  constexpr iterator begin() noexcept
1202  {
1203  return iterator(
1204  this->_M_is_engaged() ? std::addressof(this->_M_get()) : nullptr
1205  );
1206  }
1207 
1208  constexpr const_iterator begin() const noexcept
1209  {
1210  return const_iterator(
1211  this->_M_is_engaged() ? std::addressof(this->_M_get()) : nullptr
1212  );
1213  }
1214 
1215  constexpr iterator end() noexcept
1216  {
1217  return begin() + has_value();
1218  }
1219 
1220  constexpr const_iterator end() const noexcept
1221  {
1222  return begin() + has_value();
1223  }
1224 #endif // __cpp_lib_optional_range_support
1225 
1226  // Observers.
1227  constexpr const _Tp*
1228  operator->() const noexcept
1229  {
1230  __glibcxx_assert(this->_M_is_engaged());
1231  return std::__addressof(this->_M_get());
1232  }
1233 
1234  constexpr _Tp*
1235  operator->() noexcept
1236  {
1237  __glibcxx_assert(this->_M_is_engaged());
1238  return std::__addressof(this->_M_get());
1239  }
1240 
1241  constexpr const _Tp&
1242  operator*() const& noexcept
1243  {
1244  __glibcxx_assert(this->_M_is_engaged());
1245  return this->_M_get();
1246  }
1247 
1248  constexpr _Tp&
1249  operator*()& noexcept
1250  {
1251  __glibcxx_assert(this->_M_is_engaged());
1252  return this->_M_get();
1253  }
1254 
1255  constexpr _Tp&&
1256  operator*()&& noexcept
1257  {
1258  __glibcxx_assert(this->_M_is_engaged());
1259  return std::move(this->_M_get());
1260  }
1261 
1262  constexpr const _Tp&&
1263  operator*() const&& noexcept
1264  {
1265  __glibcxx_assert(this->_M_is_engaged());
1266  return std::move(this->_M_get());
1267  }
1268 
1269  constexpr explicit operator bool() const noexcept
1270  { return this->_M_is_engaged(); }
1271 
1272  constexpr bool has_value() const noexcept
1273  { return this->_M_is_engaged(); }
1274 
1275  constexpr const _Tp&
1276  value() const&
1277  {
1278  if (this->_M_is_engaged())
1279  return this->_M_get();
1280  __throw_bad_optional_access();
1281  }
1282 
1283  constexpr _Tp&
1284  value()&
1285  {
1286  if (this->_M_is_engaged())
1287  return this->_M_get();
1288  __throw_bad_optional_access();
1289  }
1290 
1291  constexpr _Tp&&
1292  value()&&
1293  {
1294  if (this->_M_is_engaged())
1295  return std::move(this->_M_get());
1296  __throw_bad_optional_access();
1297  }
1298 
1299  constexpr const _Tp&&
1300  value() const&&
1301  {
1302  if (this->_M_is_engaged())
1303  return std::move(this->_M_get());
1304  __throw_bad_optional_access();
1305  }
1306 
1307  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1308  // 4406. value_or return statement is inconsistent with Mandates
1309  template<typename _Up = remove_cv_t<_Tp>>
1310  constexpr remove_cv_t<_Tp>
1311  value_or(_Up&& __u) const&
1312  {
1313  using _Xp = remove_cv_t<_Tp>;
1314  static_assert(is_convertible_v<const _Tp&, _Xp>);
1315  static_assert(is_convertible_v<_Up, _Xp>);
1316 
1317  if (this->_M_is_engaged())
1318  return this->_M_get();
1319  return std::forward<_Up>(__u);
1320  }
1321 
1322  template<typename _Up = remove_cv_t<_Tp>>
1323  constexpr remove_cv_t<_Tp>
1324  value_or(_Up&& __u) &&
1325  {
1326  using _Xp = remove_cv_t<_Tp>;
1327  static_assert(is_convertible_v<_Tp, _Xp>);
1328  static_assert(is_convertible_v<_Up, _Xp>);
1329 
1330  if (this->_M_is_engaged())
1331  return std::move(this->_M_get());
1332  return std::forward<_Up>(__u);
1333  }
1334 
1335 #if __cpp_lib_optional >= 202110L // C++23
1336  // [optional.monadic]
1337 
1338  template<typename _Fn>
1339  constexpr auto
1340  and_then(_Fn&& __f) &
1341  {
1342  using _Up = remove_cvref_t<invoke_result_t<_Fn, _Tp&>>;
1343  static_assert(__is_optional_v<_Up>,
1344  "the function passed to std::optional<T>::and_then "
1345  "must return a std::optional");
1346  if (has_value())
1347  return std::__invoke(std::forward<_Fn>(__f), _M_get());
1348  else
1349  return _Up();
1350  }
1351 
1352  template<typename _Fn>
1353  constexpr auto
1354  and_then(_Fn&& __f) const &
1355  {
1356  using _Up = remove_cvref_t<invoke_result_t<_Fn, const _Tp&>>;
1357  static_assert(__is_optional_v<_Up>,
1358  "the function passed to std::optional<T>::and_then "
1359  "must return a std::optional");
1360  if (has_value())
1361  return std::__invoke(std::forward<_Fn>(__f), _M_get());
1362  else
1363  return _Up();
1364  }
1365 
1366  template<typename _Fn>
1367  constexpr auto
1368  and_then(_Fn&& __f) &&
1369  {
1370  using _Up = remove_cvref_t<invoke_result_t<_Fn, _Tp>>;
1371  static_assert(__is_optional_v<_Up>,
1372  "the function passed to std::optional<T>::and_then "
1373  "must return a std::optional");
1374  if (has_value())
1375  return std::__invoke(std::forward<_Fn>(__f), std::move(_M_get()));
1376  else
1377  return _Up();
1378  }
1379 
1380  template<typename _Fn>
1381  constexpr auto
1382  and_then(_Fn&& __f) const &&
1383  {
1384  using _Up = remove_cvref_t<invoke_result_t<_Fn, const _Tp>>;
1385  static_assert(__is_optional_v<_Up>,
1386  "the function passed to std::optional<T>::and_then "
1387  "must return a std::optional");
1388  if (has_value())
1389  return std::__invoke(std::forward<_Fn>(__f), std::move(_M_get()));
1390  else
1391  return _Up();
1392  }
1393 
1394  template<typename _Fn>
1395  constexpr auto
1396  transform(_Fn&& __f) &
1397  {
1398  using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp&>>;
1399  if (has_value())
1400  return optional<_Up>(_Optional_func<_Fn>{__f}, _M_get());
1401  else
1402  return optional<_Up>();
1403  }
1404 
1405  template<typename _Fn>
1406  constexpr auto
1407  transform(_Fn&& __f) const &
1408  {
1409  using _Up = remove_cv_t<invoke_result_t<_Fn, const _Tp&>>;
1410  if (has_value())
1411  return optional<_Up>(_Optional_func<_Fn>{__f}, _M_get());
1412  else
1413  return optional<_Up>();
1414  }
1415 
1416  template<typename _Fn>
1417  constexpr auto
1418  transform(_Fn&& __f) &&
1419  {
1420  using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp>>;
1421  if (has_value())
1422  return optional<_Up>(_Optional_func<_Fn>{__f}, std::move(_M_get()));
1423  else
1424  return optional<_Up>();
1425  }
1426 
1427  template<typename _Fn>
1428  constexpr auto
1429  transform(_Fn&& __f) const &&
1430  {
1431  using _Up = remove_cv_t<invoke_result_t<_Fn, const _Tp>>;
1432  if (has_value())
1433  return optional<_Up>(_Optional_func<_Fn>{__f}, std::move(_M_get()));
1434  else
1435  return optional<_Up>();
1436  }
1437 
1438  template<typename _Fn> requires invocable<_Fn> && copy_constructible<_Tp>
1439  constexpr optional
1440  or_else(_Fn&& __f) const&
1441  {
1442  using _Up = invoke_result_t<_Fn>;
1443  static_assert(is_same_v<remove_cvref_t<_Up>, optional>,
1444  "the function passed to std::optional<T>::or_else "
1445  "must return a std::optional<T>");
1446 
1447  if (has_value())
1448  return *this;
1449  else
1450  return std::forward<_Fn>(__f)();
1451  }
1452 
1453  template<typename _Fn> requires invocable<_Fn> && move_constructible<_Tp>
1454  constexpr optional
1455  or_else(_Fn&& __f) &&
1456  {
1457  using _Up = invoke_result_t<_Fn>;
1458  static_assert(is_same_v<remove_cvref_t<_Up>, optional>,
1459  "the function passed to std::optional<T>::or_else "
1460  "must return a std::optional<T>");
1461 
1462  if (has_value())
1463  return std::move(*this);
1464  else
1465  return std::forward<_Fn>(__f)();
1466  }
1467 #endif
1468 
1469  _GLIBCXX20_CONSTEXPR void reset() noexcept { this->_M_reset(); }
1470 
1471  private:
1472  using _Base::_M_get;
1473 
1474  [[__gnu__::__always_inline__]]
1475  constexpr _Tp&
1476  _M_fwd() & noexcept
1477  { return _M_get(); }
1478 
1479  [[__gnu__::__always_inline__]]
1480  constexpr _Tp&&
1481  _M_fwd() && noexcept
1482  { return std::move(_M_get()); }
1483 
1484  [[__gnu__::__always_inline__]]
1485  constexpr const _Tp&
1486  _M_fwd() const& noexcept
1487  { return _M_get(); }
1488 
1489  [[__gnu__::__always_inline__]]
1490  constexpr const _Tp&&
1491  _M_fwd() const&& noexcept
1492  { return std::move(_M_get()); }
1493 
1494  template<typename _Up> friend class optional;
1495 
1496 #if __cpp_lib_optional >= 202110L // C++23
1497  template<typename _Fn, typename _Value>
1498  explicit constexpr
1499  optional(_Optional_func<_Fn> __f, _Value&& __v)
1500  {
1501  this->_M_payload._M_apply(__f, std::forward<_Value>(__v));
1502  }
1503 #endif
1504  };
1505 
1506 #if __cpp_lib_optional >= 202506L // C++26
1507  template<typename _Tp>
1508  class optional<_Tp&>;
1509 
1510  template<typename _Tp>
1511  constexpr bool __is_optional_ref_v = false;
1512 
1513  template<typename _Tp>
1514  constexpr bool __is_optional_ref_v<optional<_Tp&>> = true;
1515 
1516  template<typename _Tp>
1517  struct __optional_ref_base
1518  {};
1519 
1520 #ifdef __cpp_lib_optional_range_support // >= C++26
1521  template<typename _Tp>
1522  struct __optional_ref_base<_Tp[]>
1523  {};
1524 
1525  template<typename _Tp>
1526  requires is_object_v<_Tp>
1527  struct __optional_ref_base<_Tp>
1528  {
1529  using iterator = __gnu_cxx::__normal_iterator<_Tp*, optional<_Tp&>>;
1530  };
1531 #endif // __cpp_lib_optional_range_support
1532 
1533  template<typename _Tp>
1534  class optional<_Tp&> : public __optional_ref_base<_Tp>
1535  {
1536  static_assert(__is_valid_contained_type_for_optional<_Tp&>);
1537 
1538  public:
1539  using value_type = _Tp;
1540 
1541  // Constructors.
1542  constexpr optional() noexcept = default;
1543  constexpr optional(nullopt_t) noexcept : optional() {}
1544  constexpr optional(const optional&) noexcept = default;
1545 
1546  template<typename _Arg>
1547  requires is_constructible_v<_Tp&, _Arg>
1548  && (!reference_constructs_from_temporary_v<_Tp&, _Arg>)
1549  explicit constexpr
1550  optional(in_place_t, _Arg&& __arg)
1551  {
1552  __convert_ref_init_val(std::forward<_Arg>(__arg));
1553  }
1554 
1555  template<typename _Up>
1556  requires (!is_same_v<remove_cvref_t<_Up>, optional>)
1557  && (!is_same_v<remove_cvref_t<_Up>, in_place_t>)
1558  && is_constructible_v<_Tp&, _Up>
1559  && (!reference_constructs_from_temporary_v<_Tp&, _Up>)
1560  explicit(!is_convertible_v<_Up, _Tp&>)
1561  constexpr
1562  optional(_Up&& __u)
1563  noexcept(is_nothrow_constructible_v<_Tp&, _Up>)
1564  {
1565  __convert_ref_init_val(std::forward<_Up>(__u));
1566  }
1567 
1568  template<typename _Up>
1569  requires (!is_same_v<remove_cvref_t<_Up>, optional>)
1570  && (!is_same_v<remove_cvref_t<_Up>, in_place_t>)
1571  && is_constructible_v<_Tp&, _Up>
1572  && reference_constructs_from_temporary_v<_Tp&, _Up>
1573  explicit(!is_convertible_v<_Up, _Tp&>)
1574  constexpr
1575  optional(_Up&& __u) = delete;
1576 
1577  // optional<U> &
1578  template<typename _Up>
1579  requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
1580  && (!is_same_v<_Tp&, _Up>)
1581  && is_constructible_v<_Tp&, _Up&>
1582  && (!reference_constructs_from_temporary_v<_Tp&, _Up&>)
1583  explicit(!is_convertible_v<_Up&, _Tp&>)
1584  constexpr
1585  optional(optional<_Up>& __rhs)
1586  noexcept(is_nothrow_constructible_v<_Tp&, _Up&>)
1587  {
1588  if (__rhs)
1589  __convert_ref_init_val(__rhs._M_fwd());
1590  }
1591 
1592  template<typename _Up>
1593  requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
1594  && (!is_same_v<_Tp&, _Up>)
1595  && is_constructible_v<_Tp&, _Up&>
1596  && reference_constructs_from_temporary_v<_Tp&, _Up&>
1597  explicit(!is_convertible_v<_Up&, _Tp&>)
1598  constexpr
1599  optional(optional<_Up>& __rhs) = delete;
1600 
1601  // const optional<U>&
1602  template<typename _Up>
1603  requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
1604  && (!is_same_v<_Tp&, _Up>)
1605  && is_constructible_v<_Tp&, const _Up&>
1606  && (!reference_constructs_from_temporary_v<_Tp&, const _Up&>)
1607  explicit(!is_convertible_v<const _Up&, _Tp&>)
1608  constexpr
1609  optional(const optional<_Up>& __rhs)
1610  noexcept(is_nothrow_constructible_v<_Tp&, _Up&>)
1611  {
1612  if (__rhs)
1613  __convert_ref_init_val(__rhs._M_fwd());
1614  }
1615 
1616  template<typename _Up>
1617  requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
1618  && (!is_same_v<_Tp&, _Up>)
1619  && is_constructible_v<_Tp&, const _Up&>
1620  && reference_constructs_from_temporary_v<_Tp&, const _Up&>
1621  explicit(!is_convertible_v<const _Up&, _Tp&>)
1622  constexpr
1623  optional(const optional<_Up>& __rhs) = delete;
1624 
1625  // optional<U>&&
1626  template<typename _Up>
1627  requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
1628  && (!is_same_v<_Tp&, _Up>)
1629  && is_constructible_v<_Tp&, _Up>
1630  && (!reference_constructs_from_temporary_v<_Tp&, _Up>)
1631  explicit(!is_convertible_v<_Up, _Tp&>)
1632  constexpr
1633  optional(optional<_Up>&& __rhs)
1634  noexcept(is_nothrow_constructible_v<_Tp&, _Up>)
1635  {
1636  if (__rhs)
1637  __convert_ref_init_val(std::move(__rhs)._M_fwd());
1638  }
1639 
1640  template<typename _Up>
1641  requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
1642  && (!is_same_v<_Tp&, _Up>)
1643  && is_constructible_v<_Tp&, _Up>
1644  && reference_constructs_from_temporary_v<_Tp&, _Up>
1645  explicit(!is_convertible_v<_Up, _Tp&>)
1646  constexpr
1647  optional(optional<_Up>&& __rhs) = delete;
1648 
1649  // const optional<U>&&
1650  template<typename _Up>
1651  requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
1652  && (!is_same_v<_Tp&, _Up>)
1653  && is_constructible_v<_Tp&, const _Up>
1654  && (!reference_constructs_from_temporary_v<_Tp&, _Up>)
1655  explicit(!is_convertible_v<const _Up, _Tp&>)
1656  constexpr
1657  optional(const optional<_Up>&& __rhs)
1658  noexcept(is_nothrow_constructible_v<_Tp&, const _Up>)
1659  {
1660  if (__rhs)
1661  __convert_ref_init_val(std::move(__rhs)._M_fwd());
1662  }
1663 
1664  template<typename _Up>
1665  requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
1666  && (!is_same_v<_Tp&, _Up>)
1667  && is_constructible_v<_Tp&, const _Up>
1668  && reference_constructs_from_temporary_v<_Tp&, const _Up>
1669  explicit(!is_convertible_v<const _Up, _Tp&>)
1670  constexpr
1671  optional(const optional<_Up>&& __rhs) = delete;
1672 
1673  constexpr ~optional() = default;
1674 
1675  // Assignment.
1676  constexpr optional& operator=(nullopt_t) noexcept
1677  {
1678  _M_val = nullptr;
1679  return *this;
1680  }
1681 
1682  constexpr optional& operator=(const optional&) noexcept = default;
1683 
1684  template<typename _Up>
1685  requires is_constructible_v<_Tp&, _Up>
1686  && (!reference_constructs_from_temporary_v<_Tp&, _Up>)
1687  constexpr _Tp&
1688  emplace(_Up&& __u)
1689  noexcept(is_nothrow_constructible_v<_Tp&, _Up>)
1690  {
1691  __convert_ref_init_val(std::forward<_Up>(__u));
1692  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1693  // 4300. Missing Returns: element in optional<T&>::emplace
1694  return *_M_val;
1695  }
1696 
1697  // Swap.
1698  constexpr void swap(optional& __rhs) noexcept
1699  { std::swap(_M_val, __rhs._M_val); }
1700 
1701 #ifdef __cpp_lib_optional_range_support // >= C++26
1702  // Iterator support.
1703  constexpr auto begin() const noexcept
1704  requires is_object_v<_Tp> && (!is_unbounded_array_v<_Tp>)
1705  { return __gnu_cxx::__normal_iterator<_Tp*, optional>(_M_val); }
1706 
1707  constexpr auto end() const noexcept
1708  requires is_object_v<_Tp> && (!is_unbounded_array_v<_Tp>)
1709  { return begin() + has_value(); }
1710 #endif // __cpp_lib_optional_range_support
1711 
1712  // Observers.
1713  constexpr _Tp* operator->() const noexcept
1714  {
1715  __glibcxx_assert(_M_val); // hardened precondition
1716  return _M_val;
1717  }
1718 
1719  constexpr _Tp& operator*() const noexcept
1720  {
1721  __glibcxx_assert(_M_val); // hardened precondition
1722  return *_M_val;
1723  }
1724 
1725  constexpr explicit operator bool() const noexcept
1726  {
1727  return _M_val;
1728  }
1729 
1730  constexpr bool has_value() const noexcept
1731  {
1732  return _M_val;
1733  }
1734 
1735  constexpr _Tp& value() const
1736  {
1737  if (_M_val)
1738  return *_M_val;
1739  __throw_bad_optional_access();
1740  }
1741 
1742  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1743  // 4304. std::optional<NonReturnable&> is ill-formed due to value_or
1744  template<typename _Up = remove_cv_t<_Tp>>
1745  requires is_object_v<_Tp> && (!is_array_v<_Tp>)
1746  constexpr decay_t<_Tp>
1747  value_or(_Up&& __u) const
1748  {
1749  using _Xp = remove_cv_t<_Tp>;
1750  static_assert(is_convertible_v<_Tp&, _Xp>);
1751  static_assert(is_convertible_v<_Up, _Xp>);
1752  if (_M_val)
1753  return *_M_val;
1754  return std::forward<_Up>(__u);
1755  }
1756 
1757  // Monadic operations.
1758  template<typename _Fn>
1759  constexpr auto
1760  and_then(_Fn&& __f) const
1761  {
1762  using _Up = remove_cvref_t<invoke_result_t<_Fn, _Tp&>>;
1763  static_assert(__is_optional_v<_Up>,
1764  "the function passed to std::optional<T&>::and_then "
1765  "must return a std::optional");
1766  if (has_value())
1767  return std::__invoke(std::forward<_Fn>(__f), *_M_val);
1768  else
1769  return _Up();
1770  }
1771 
1772  template<typename _Fn>
1773  constexpr
1774  optional<remove_cv_t<invoke_result_t<_Fn, _Tp&>>>
1775  transform(_Fn&& __f) const
1776  {
1777  using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp&>>;
1778  if (has_value())
1779  return optional<_Up>(_Optional_func<_Fn>{__f}, *_M_val);
1780  else
1781  return optional<_Up>();
1782  }
1783 
1784  template<typename _Fn>
1785  requires invocable<_Fn>
1786  constexpr
1787  optional
1788  or_else(_Fn&& __f) const
1789  {
1790  static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Fn>>, optional>,
1791  "the function passed to std::optional<T&>::or_else "
1792  "must return a std::optional<T&>");
1793  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1794  // 4367. Improve optional<T&>::or_else
1795  if (has_value())
1796  return *this;
1797  else
1798  return std::forward<_Fn>(__f)();
1799  }
1800 
1801  // Modifiers.
1802  constexpr void reset() noexcept
1803  {
1804  _M_val = nullptr;
1805  }
1806 
1807  private:
1808  _Tp *_M_val = nullptr;
1809 
1810  [[__gnu__::__always_inline__]]
1811  constexpr _Tp&
1812  _M_fwd() const noexcept
1813  { return *_M_val; }
1814 
1815  template<typename _Up> friend class optional;
1816 
1817  template<typename _Up>
1818  constexpr
1819  void
1820  __convert_ref_init_val(_Up&& __u)
1821  noexcept
1822  {
1823  _Tp& __r(std::forward<_Up>(__u));
1824  _M_val = std::addressof(__r);
1825  }
1826 
1827  template<typename _Fn, typename _Value>
1828  explicit constexpr
1829  optional(_Optional_func<_Fn> __f, _Value&& __v)
1830  {
1831  _Tp& __r = std::__invoke(std::forward<_Fn>(__f._M_f), std::forward<_Value>(__v));
1832  _M_val = std::addressof(__r);
1833  }
1834  };
1835 #endif // __cpp_lib_optional >= 202506L
1836 
1837  template<typename _Tp>
1838  using __optional_relop_t =
1839  enable_if_t<is_convertible_v<_Tp, bool>, bool>;
1840 
1841  template<typename _Tp, typename _Up>
1842  using __optional_eq_t = __optional_relop_t<
1843  decltype(std::declval<const _Tp&>() == std::declval<const _Up&>())
1844  >;
1845 
1846  template<typename _Tp, typename _Up>
1847  using __optional_ne_t = __optional_relop_t<
1848  decltype(std::declval<const _Tp&>() != std::declval<const _Up&>())
1849  >;
1850 
1851  template<typename _Tp, typename _Up>
1852  using __optional_lt_t = __optional_relop_t<
1853  decltype(std::declval<const _Tp&>() < std::declval<const _Up&>())
1854  >;
1855 
1856  template<typename _Tp, typename _Up>
1857  using __optional_gt_t = __optional_relop_t<
1858  decltype(std::declval<const _Tp&>() > std::declval<const _Up&>())
1859  >;
1860 
1861  template<typename _Tp, typename _Up>
1862  using __optional_le_t = __optional_relop_t<
1863  decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>())
1864  >;
1865 
1866  template<typename _Tp, typename _Up>
1867  using __optional_ge_t = __optional_relop_t<
1868  decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>())
1869  >;
1870 
1871  // Comparisons between optional values.
1872  template<typename _Tp, typename _Up>
1873  constexpr auto
1874  operator==(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1875  -> __optional_eq_t<_Tp, _Up>
1876  {
1877  if (__lhs.has_value() != __rhs.has_value())
1878  return false;
1879  if (!__lhs.has_value())
1880  return true;
1881  return *__lhs == *__rhs;
1882  }
1883 
1884  template<typename _Tp, typename _Up>
1885  constexpr auto
1886  operator!=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1887  -> __optional_ne_t<_Tp, _Up>
1888  {
1889  if (__lhs.has_value() != __rhs.has_value())
1890  return true;
1891  if (!__lhs.has_value())
1892  return false;
1893  return *__lhs != *__rhs;
1894  }
1895 
1896  template<typename _Tp, typename _Up>
1897  constexpr auto
1898  operator<(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1899  -> __optional_lt_t<_Tp, _Up>
1900  {
1901  if (!__rhs.has_value())
1902  return false;
1903  if (!__lhs.has_value())
1904  return true;
1905  return *__lhs < *__rhs;
1906  }
1907 
1908  template<typename _Tp, typename _Up>
1909  constexpr auto
1910  operator>(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1911  -> __optional_gt_t<_Tp, _Up>
1912  {
1913  if (!__lhs.has_value())
1914  return false;
1915  if (!__rhs.has_value())
1916  return true;
1917  return *__lhs > *__rhs;
1918  }
1919 
1920  template<typename _Tp, typename _Up>
1921  constexpr auto
1922  operator<=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1923  -> __optional_le_t<_Tp, _Up>
1924  {
1925  if (!__lhs.has_value())
1926  return true;
1927  if (!__rhs.has_value())
1928  return false;
1929  return *__lhs <= *__rhs;
1930  }
1931 
1932  template<typename _Tp, typename _Up>
1933  constexpr auto
1934  operator>=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1935  -> __optional_ge_t<_Tp, _Up>
1936  {
1937  if (!__rhs.has_value())
1938  return true;
1939  if (!__lhs.has_value())
1940  return false;
1941  return *__lhs >= *__rhs;
1942  }
1943 
1944 #ifdef __cpp_lib_three_way_comparison
1945  template<typename _Tp, three_way_comparable_with<_Tp> _Up>
1946  [[nodiscard]]
1947  constexpr compare_three_way_result_t<_Tp, _Up>
1948  operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y)
1949  {
1950  return __x && __y ? *__x <=> *__y : bool(__x) <=> bool(__y);
1951  }
1952 #endif
1953 
1954  // Comparisons with nullopt.
1955  template<typename _Tp>
1956  [[nodiscard]]
1957  constexpr bool
1958  operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept
1959  { return !__lhs; }
1960 
1961 #ifdef __cpp_lib_three_way_comparison
1962  template<typename _Tp>
1963  [[nodiscard]]
1964  constexpr strong_ordering
1965  operator<=>(const optional<_Tp>& __x, nullopt_t) noexcept
1966  { return bool(__x) <=> false; }
1967 #else
1968  template<typename _Tp>
1969  constexpr bool
1970  operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept
1971  { return !__rhs; }
1972 
1973  template<typename _Tp>
1974  constexpr bool
1975  operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept
1976  { return static_cast<bool>(__lhs); }
1977 
1978  template<typename _Tp>
1979  constexpr bool
1980  operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept
1981  { return static_cast<bool>(__rhs); }
1982 
1983  template<typename _Tp>
1984  constexpr bool
1985  operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
1986  { return false; }
1987 
1988  template<typename _Tp>
1989  constexpr bool
1990  operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
1991  { return static_cast<bool>(__rhs); }
1992 
1993  template<typename _Tp>
1994  constexpr bool
1995  operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept
1996  { return static_cast<bool>(__lhs); }
1997 
1998  template<typename _Tp>
1999  constexpr bool
2000  operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
2001  { return false; }
2002 
2003  template<typename _Tp>
2004  constexpr bool
2005  operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept
2006  { return !__lhs; }
2007 
2008  template<typename _Tp>
2009  constexpr bool
2010  operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
2011  { return true; }
2012 
2013  template<typename _Tp>
2014  constexpr bool
2015  operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
2016  { return true; }
2017 
2018  template<typename _Tp>
2019  constexpr bool
2020  operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept
2021  { return !__rhs; }
2022 #endif // three-way-comparison
2023 
2024 #if __cpp_lib_concepts
2025  // _GLIBCXX_RESOLVE_LIB_DEFECTS
2026  // 4072. std::optional comparisons: constrain harder
2027 # define _REQUIRES_NOT_OPTIONAL(T) requires (!__is_optional_v<T>)
2028 #else
2029 # define _REQUIRES_NOT_OPTIONAL(T)
2030 #endif
2031 
2032  // Comparisons with value type.
2033  template<typename _Tp, typename _Up>
2034  _REQUIRES_NOT_OPTIONAL(_Up)
2035  constexpr auto
2036  operator== [[nodiscard]] (const optional<_Tp>& __lhs, const _Up& __rhs)
2037  -> __optional_eq_t<_Tp, _Up>
2038  {
2039  if (__lhs.has_value())
2040  return *__lhs == __rhs;
2041  return false;
2042  }
2043 
2044  template<typename _Tp, typename _Up>
2045  _REQUIRES_NOT_OPTIONAL(_Tp)
2046  constexpr auto
2047  operator== [[nodiscard]] (const _Tp& __lhs, const optional<_Up>& __rhs)
2048  -> __optional_eq_t<_Tp, _Up>
2049  {
2050  if (__rhs.has_value())
2051  return __lhs == *__rhs;
2052  return false;
2053  }
2054 
2055  template<typename _Tp, typename _Up>
2056  _REQUIRES_NOT_OPTIONAL(_Up)
2057  constexpr auto
2058  operator!= [[nodiscard]] (const optional<_Tp>& __lhs, const _Up& __rhs)
2059  -> __optional_ne_t<_Tp, _Up>
2060  {
2061  if (__lhs.has_value())
2062  return *__lhs != __rhs;
2063  return true;
2064  }
2065 
2066  template<typename _Tp, typename _Up>
2067  _REQUIRES_NOT_OPTIONAL(_Tp)
2068  constexpr auto
2069  operator!= [[nodiscard]] (const _Tp& __lhs, const optional<_Up>& __rhs)
2070  -> __optional_ne_t<_Tp, _Up>
2071  {
2072  if (__rhs.has_value())
2073  return __lhs != *__rhs;
2074  return true;
2075  }
2076 
2077  template<typename _Tp, typename _Up>
2078  _REQUIRES_NOT_OPTIONAL(_Up)
2079  constexpr auto
2080  operator< [[nodiscard]] (const optional<_Tp>& __lhs, const _Up& __rhs)
2081  -> __optional_lt_t<_Tp, _Up>
2082  {
2083  if (__lhs.has_value())
2084  return *__lhs < __rhs;
2085  return true;
2086  }
2087 
2088  template<typename _Tp, typename _Up>
2089  _REQUIRES_NOT_OPTIONAL(_Tp)
2090  constexpr auto
2091  operator< [[nodiscard]] (const _Tp& __lhs, const optional<_Up>& __rhs)
2092  -> __optional_lt_t<_Tp, _Up>
2093  {
2094  if (__rhs.has_value())
2095  return __lhs < *__rhs;
2096  return false;
2097  }
2098 
2099  template<typename _Tp, typename _Up>
2100  _REQUIRES_NOT_OPTIONAL(_Up)
2101  constexpr auto
2102  operator> [[nodiscard]] (const optional<_Tp>& __lhs, const _Up& __rhs)
2103  -> __optional_gt_t<_Tp, _Up>
2104  {
2105  if (__lhs.has_value())
2106  return *__lhs > __rhs;
2107  return false;
2108  }
2109 
2110  template<typename _Tp, typename _Up>
2111  _REQUIRES_NOT_OPTIONAL(_Tp)
2112  constexpr auto
2113  operator> [[nodiscard]] (const _Tp& __lhs, const optional<_Up>& __rhs)
2114  -> __optional_gt_t<_Tp, _Up>
2115  {
2116  if (__rhs.has_value())
2117  return __lhs > *__rhs;
2118  return true;
2119  }
2120 
2121  template<typename _Tp, typename _Up>
2122  _REQUIRES_NOT_OPTIONAL(_Up)
2123  constexpr auto
2124  operator<= [[nodiscard]] (const optional<_Tp>& __lhs, const _Up& __rhs)
2125  -> __optional_le_t<_Tp, _Up>
2126  {
2127  if (__lhs.has_value())
2128  return *__lhs <= __rhs;
2129  return true;
2130  }
2131 
2132  template<typename _Tp, typename _Up>
2133  _REQUIRES_NOT_OPTIONAL(_Tp)
2134  constexpr auto
2135  operator<= [[nodiscard]] (const _Tp& __lhs, const optional<_Up>& __rhs)
2136  -> __optional_le_t<_Tp, _Up>
2137  {
2138  if (__rhs.has_value())
2139  return __lhs <= *__rhs;
2140  return false;
2141  }
2142 
2143  template<typename _Tp, typename _Up>
2144  _REQUIRES_NOT_OPTIONAL(_Up)
2145  constexpr auto
2146  operator>= [[nodiscard]] (const optional<_Tp>& __lhs, const _Up& __rhs)
2147  -> __optional_ge_t<_Tp, _Up>
2148  {
2149  if (__lhs.has_value())
2150  return *__lhs >= __rhs;
2151  return false;
2152  }
2153 
2154  template<typename _Tp, typename _Up>
2155  _REQUIRES_NOT_OPTIONAL(_Tp)
2156  constexpr auto
2157  operator>= [[nodiscard]] (const _Tp& __lhs, const optional<_Up>& __rhs)
2158  -> __optional_ge_t<_Tp, _Up>
2159  {
2160  if (__rhs.has_value())
2161  return __lhs >= *__rhs;
2162  return true;
2163  }
2164 
2165 #ifdef __cpp_lib_three_way_comparison
2166  // _GLIBCXX_RESOLVE_LIB_DEFECTS
2167  // 3746. optional's spaceship with U with a type derived from optional
2168  // causes infinite constraint meta-recursion
2169  template<typename _Tp>
2170  concept __is_derived_from_optional = requires (const _Tp& __t) {
2171  []<typename _Up>(const optional<_Up>&){ }(__t);
2172  };
2173 
2174  template<typename _Tp, typename _Up>
2175  requires (!__is_derived_from_optional<_Up>)
2176  && requires { typename compare_three_way_result_t<_Tp, _Up>; }
2177  && three_way_comparable_with<_Tp, _Up>
2178  constexpr compare_three_way_result_t<_Tp, _Up>
2179  operator<=> [[nodiscard]] (const optional<_Tp>& __x, const _Up& __v)
2180  { return bool(__x) ? *__x <=> __v : strong_ordering::less; }
2181 #endif
2182 
2183  // Swap and creation functions.
2184 
2185  // _GLIBCXX_RESOLVE_LIB_DEFECTS
2186  // 2748. swappable traits for optionals
2187  template<typename _Tp>
2188  _GLIBCXX20_CONSTEXPR
2189  inline enable_if_t<is_move_constructible_v<_Tp> && is_swappable_v<_Tp>>
2190  swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
2191  noexcept(noexcept(__lhs.swap(__rhs)))
2192  { __lhs.swap(__rhs); }
2193 
2194 #if __cpp_lib_optional >= 202506L
2195  // We deviate from standard, that do not declared separate swap overload
2196  // from optional<T&>.
2197  template<typename _Tp>
2198  constexpr void
2199  swap(optional<_Tp&>& __lhs, optional<_Tp&>& __rhs) noexcept
2200  { __lhs.swap(__rhs); }
2201 #endif
2202 
2203  // _GLIBCXX_RESOLVE_LIB_DEFECTS
2204  // 2766. Swapping non-swappable types
2205  template<typename _Tp>
2206  enable_if_t<!(is_move_constructible_v<_Tp> && is_swappable_v<_Tp>)>
2207  swap(optional<_Tp>&, optional<_Tp>&) = delete;
2208 
2209 #if __cpp_lib_optional >= 202506L
2210  template<int = 0, typename _Tp>
2211 #else
2212  template<typename _Tp>
2213 #endif
2214  constexpr
2215  enable_if_t<is_constructible_v<decay_t<_Tp>, _Tp>,
2216  optional<decay_t<_Tp>>>
2217  make_optional(_Tp&& __t)
2218  noexcept(is_nothrow_constructible_v<optional<decay_t<_Tp>>, _Tp>)
2219  { return optional<decay_t<_Tp>>( std::forward<_Tp>(__t) ); }
2220 
2221  template<typename _Tp, typename... _Args>
2222  constexpr
2223  enable_if_t<is_constructible_v<_Tp, _Args...>,
2224  optional<_Tp>>
2225  make_optional(_Args&&... __args)
2226  noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
2227  { return optional<_Tp>( in_place, std::forward<_Args>(__args)... ); }
2228 
2229  template<typename _Tp, typename _Up, typename... _Args>
2230  constexpr
2231  enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
2232  optional<_Tp>>
2233  make_optional(initializer_list<_Up> __il, _Args&&... __args)
2234  noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>)
2235  { return optional<_Tp>( in_place, __il, std::forward<_Args>(__args)... ); }
2236 
2237  // Hash.
2238 
2239  template<typename _Tp, typename _Up = remove_const_t<_Tp>>
2240  struct __optional_hash
2241 #if ! _GLIBCXX_INLINE_VERSION
2242  : public __hash_empty_base<_Up>
2243 #endif
2244  {
2245 #if __cplusplus < 202002L
2246  using result_type [[__deprecated__]] = size_t;
2247  using argument_type [[__deprecated__]] = optional<_Tp>;
2248 #endif
2249 
2250  size_t
2251  operator()(const optional<_Tp>& __t) const
2252  noexcept(noexcept(hash<_Up>{}(*__t)))
2253  {
2254  // We pick an arbitrary hash for disengaged optionals which hopefully
2255  // usual values of _Tp won't typically hash to.
2256  constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333);
2257  return __t ? hash<_Up>{}(*__t) : __magic_disengaged_hash;
2258  }
2259  };
2260 
2261  template<typename _Tp>
2262  struct hash<optional<_Tp>>
2263  // hash for optional<T&> is disabled because is_hash_enabled_for<T&> is false
2264  : public __conditional_t<__is_hash_enabled_for<remove_const_t<_Tp>>,
2265  __optional_hash<_Tp>,
2266  __hash_not_enabled<_Tp>>
2267  { };
2268 
2269  template<typename _Tp>
2270  struct __is_fast_hash<hash<optional<_Tp>>> : __is_fast_hash<hash<_Tp>>
2271  { };
2272 
2273  /// @}
2274 
2275 #if __cpp_deduction_guides >= 201606
2276  template <typename _Tp> optional(_Tp) -> optional<_Tp>;
2277 #endif
2278 
2279 #ifdef __cpp_lib_optional_range_support // >= C++26
2280  template<typename _Tp>
2281  inline constexpr bool
2282  ranges::enable_view<optional<_Tp>> = true;
2283 
2284 #if __cpp_lib_optional >= 202506L // C++26
2285  template<typename _Tp>
2286  constexpr bool
2287  ranges::enable_borrowed_range<optional<_Tp&>> = true;
2288 #endif
2289 
2290 #if _GLIBCXX_HOSTED
2291  template<typename _Tp>
2292  inline constexpr range_format
2293  format_kind<optional<_Tp>> = range_format::disabled;
2294 #endif
2295 #endif // __cpp_lib_optional_range_support
2296 
2297 #undef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL
2298 
2299 _GLIBCXX_END_NAMESPACE_VERSION
2300 } // namespace std
2301 
2302 #endif // __cpp_lib_optional
2303 
2304 #endif // _GLIBCXX_OPTIONAL