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