libstdc++
optional
Go to the documentation of this file.
1 // <optional> -*- C++ -*-
2 
3 // Copyright (C) 2013-2020 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /** @file include/optional
26  * This is a Standard C++ Library header.
27  */
28 
29 #ifndef _GLIBCXX_OPTIONAL
30 #define _GLIBCXX_OPTIONAL 1
31 
32 #pragma GCC system_header
33 
34 #if __cplusplus >= 201703L
35 
36 #include <utility>
37 #include <type_traits>
38 #include <exception>
39 #include <new>
40 #include <initializer_list>
41 #include <bits/exception_defines.h>
42 #include <bits/functional_hash.h>
43 #include <bits/enable_special_members.h>
44 #if __cplusplus > 201703L
45 # include <compare>
46 #endif
47 
48 namespace std _GLIBCXX_VISIBILITY(default)
49 {
50 _GLIBCXX_BEGIN_NAMESPACE_VERSION
51 
52  /**
53  * @addtogroup utilities
54  * @{
55  */
56 
57 #define __cpp_lib_optional 201606L
58 
59  template<typename _Tp>
60  class optional;
61 
62  /// Tag type to disengage optional objects.
63  struct nullopt_t
64  {
65  // Do not user-declare default constructor at all for
66  // optional_value = {} syntax to work.
67  // nullopt_t() = delete;
68 
69  // Used for constructing nullopt.
70  enum class _Construct { _Token };
71 
72  // Must be constexpr for nullopt_t to be literal.
73  explicit constexpr nullopt_t(_Construct) { }
74  };
75 
76  /// Tag to disengage optional objects.
77  inline constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token };
78 
79  /**
80  * @brief Exception class thrown when a disengaged optional object is
81  * dereferenced.
82  * @ingroup exceptions
83  */
84  class bad_optional_access : public exception
85  {
86  public:
87  bad_optional_access() = default;
88  virtual ~bad_optional_access() = default;
89 
90  const char* what() const noexcept override
91  { return "bad optional access"; }
92  };
93 
94  void
95  __throw_bad_optional_access()
96  __attribute__((__noreturn__));
97 
98  // XXX Does not belong here.
99  inline void
100  __throw_bad_optional_access()
101  { _GLIBCXX_THROW_OR_ABORT(bad_optional_access()); }
102 
103  // This class template manages construction/destruction of
104  // the contained value for a std::optional.
105  template <typename _Tp>
106  struct _Optional_payload_base
107  {
108  using _Stored_type = remove_const_t<_Tp>;
109 
110  _Optional_payload_base() = default;
111  ~_Optional_payload_base() = default;
112 
113  template<typename... _Args>
114  constexpr
115  _Optional_payload_base(in_place_t __tag, _Args&&... __args)
116  : _M_payload(__tag, std::forward<_Args>(__args)...),
117  _M_engaged(true)
118  { }
119 
120  template<typename _Up, typename... _Args>
121  constexpr
122  _Optional_payload_base(std::initializer_list<_Up> __il,
123  _Args&&... __args)
124  : _M_payload(__il, std::forward<_Args>(__args)...),
125  _M_engaged(true)
126  { }
127 
128  // Constructor used by _Optional_base copy constructor when the
129  // contained value is not trivially copy constructible.
130  constexpr
131  _Optional_payload_base(bool __engaged,
132  const _Optional_payload_base& __other)
133  {
134  if (__other._M_engaged)
135  this->_M_construct(__other._M_get());
136  }
137 
138  // Constructor used by _Optional_base move constructor when the
139  // contained value is not trivially move constructible.
140  constexpr
141  _Optional_payload_base(bool __engaged,
142  _Optional_payload_base&& __other)
143  {
144  if (__other._M_engaged)
145  this->_M_construct(std::move(__other._M_get()));
146  }
147 
148  // Copy constructor is only used to when the contained value is
149  // trivially copy constructible.
150  _Optional_payload_base(const _Optional_payload_base&) = default;
151 
152  // Move constructor is only used to when the contained value is
153  // trivially copy constructible.
154  _Optional_payload_base(_Optional_payload_base&&) = default;
155 
156  _Optional_payload_base&
157  operator=(const _Optional_payload_base&) = default;
158 
159  _Optional_payload_base&
160  operator=(_Optional_payload_base&&) = default;
161 
162  // used to perform non-trivial copy assignment.
163  constexpr void
164  _M_copy_assign(const _Optional_payload_base& __other)
165  {
166  if (this->_M_engaged && __other._M_engaged)
167  this->_M_get() = __other._M_get();
168  else
169  {
170  if (__other._M_engaged)
171  this->_M_construct(__other._M_get());
172  else
173  this->_M_reset();
174  }
175  }
176 
177  // used to perform non-trivial move assignment.
178  constexpr void
179  _M_move_assign(_Optional_payload_base&& __other)
180  noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
181  is_nothrow_move_assignable<_Tp>>)
182  {
183  if (this->_M_engaged && __other._M_engaged)
184  this->_M_get() = std::move(__other._M_get());
185  else
186  {
187  if (__other._M_engaged)
188  this->_M_construct(std::move(__other._M_get()));
189  else
190  this->_M_reset();
191  }
192  }
193 
194  struct _Empty_byte { };
195 
196  template<typename _Up, bool = is_trivially_destructible_v<_Up>>
197  union _Storage
198  {
199  constexpr _Storage() noexcept : _M_empty() { }
200 
201  template<typename... _Args>
202  constexpr
203  _Storage(in_place_t, _Args&&... __args)
204  : _M_value(std::forward<_Args>(__args)...)
205  { }
206 
207  template<typename _Vp, typename... _Args>
208  constexpr
209  _Storage(std::initializer_list<_Vp> __il, _Args&&... __args)
210  : _M_value(__il, std::forward<_Args>(__args)...)
211  { }
212 
213  _Empty_byte _M_empty;
214  _Up _M_value;
215  };
216 
217  template<typename _Up>
218  union _Storage<_Up, false>
219  {
220  constexpr _Storage() noexcept : _M_empty() { }
221 
222  template<typename... _Args>
223  constexpr
224  _Storage(in_place_t, _Args&&... __args)
225  : _M_value(std::forward<_Args>(__args)...)
226  { }
227 
228  template<typename _Vp, typename... _Args>
229  constexpr
230  _Storage(std::initializer_list<_Vp> __il, _Args&&... __args)
231  : _M_value(__il, std::forward<_Args>(__args)...)
232  { }
233 
234  // User-provided destructor is needed when _Up has non-trivial dtor.
235  ~_Storage() { }
236 
237  _Empty_byte _M_empty;
238  _Up _M_value;
239  };
240 
241  _Storage<_Stored_type> _M_payload;
242 
243  bool _M_engaged = false;
244 
245  template<typename... _Args>
246  void
247  _M_construct(_Args&&... __args)
248  noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
249  {
250  ::new ((void *) std::__addressof(this->_M_payload))
251  _Stored_type(std::forward<_Args>(__args)...);
252  this->_M_engaged = true;
253  }
254 
255  constexpr void
256  _M_destroy() noexcept
257  {
258  _M_engaged = false;
259  _M_payload._M_value.~_Stored_type();
260  }
261 
262  // The _M_get() operations have _M_engaged as a precondition.
263  // They exist to access the contained value with the appropriate
264  // const-qualification, because _M_payload has had the const removed.
265 
266  constexpr _Tp&
267  _M_get() noexcept
268  { return this->_M_payload._M_value; }
269 
270  constexpr const _Tp&
271  _M_get() const noexcept
272  { return this->_M_payload._M_value; }
273 
274  // _M_reset is a 'safe' operation with no precondition.
275  constexpr void
276  _M_reset() noexcept
277  {
278  if (this->_M_engaged)
279  _M_destroy();
280  }
281  };
282 
283  // Class template that manages the payload for optionals.
284  template <typename _Tp,
285  bool /*_HasTrivialDestructor*/ =
286  is_trivially_destructible_v<_Tp>,
287  bool /*_HasTrivialCopy */ =
288  is_trivially_copy_assignable_v<_Tp>
289  && is_trivially_copy_constructible_v<_Tp>,
290  bool /*_HasTrivialMove */ =
291  is_trivially_move_assignable_v<_Tp>
292  && is_trivially_move_constructible_v<_Tp>>
293  struct _Optional_payload;
294 
295  // Payload for potentially-constexpr optionals (trivial copy/move/destroy).
296  template <typename _Tp>
297  struct _Optional_payload<_Tp, true, true, true>
298  : _Optional_payload_base<_Tp>
299  {
300  using _Optional_payload_base<_Tp>::_Optional_payload_base;
301 
302  _Optional_payload() = default;
303  };
304 
305  // Payload for optionals with non-trivial copy construction/assignment.
306  template <typename _Tp>
307  struct _Optional_payload<_Tp, true, false, true>
308  : _Optional_payload_base<_Tp>
309  {
310  using _Optional_payload_base<_Tp>::_Optional_payload_base;
311 
312  _Optional_payload() = default;
313  ~_Optional_payload() = default;
314  _Optional_payload(const _Optional_payload&) = default;
315  _Optional_payload(_Optional_payload&&) = default;
316  _Optional_payload& operator=(_Optional_payload&&) = default;
317 
318  // Non-trivial copy assignment.
319  constexpr
320  _Optional_payload&
321  operator=(const _Optional_payload& __other)
322  {
323  this->_M_copy_assign(__other);
324  return *this;
325  }
326  };
327 
328  // Payload for optionals with non-trivial move construction/assignment.
329  template <typename _Tp>
330  struct _Optional_payload<_Tp, true, true, false>
331  : _Optional_payload_base<_Tp>
332  {
333  using _Optional_payload_base<_Tp>::_Optional_payload_base;
334 
335  _Optional_payload() = default;
336  ~_Optional_payload() = default;
337  _Optional_payload(const _Optional_payload&) = default;
338  _Optional_payload(_Optional_payload&&) = default;
339  _Optional_payload& operator=(const _Optional_payload&) = default;
340 
341  // Non-trivial move assignment.
342  constexpr
343  _Optional_payload&
344  operator=(_Optional_payload&& __other)
345  noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
346  is_nothrow_move_assignable<_Tp>>)
347  {
348  this->_M_move_assign(std::move(__other));
349  return *this;
350  }
351  };
352 
353  // Payload for optionals with non-trivial copy and move assignment.
354  template <typename _Tp>
355  struct _Optional_payload<_Tp, true, false, false>
356  : _Optional_payload_base<_Tp>
357  {
358  using _Optional_payload_base<_Tp>::_Optional_payload_base;
359 
360  _Optional_payload() = default;
361  ~_Optional_payload() = default;
362  _Optional_payload(const _Optional_payload&) = default;
363  _Optional_payload(_Optional_payload&&) = default;
364 
365  // Non-trivial copy assignment.
366  constexpr
367  _Optional_payload&
368  operator=(const _Optional_payload& __other)
369  {
370  this->_M_copy_assign(__other);
371  return *this;
372  }
373 
374  // Non-trivial move assignment.
375  constexpr
376  _Optional_payload&
377  operator=(_Optional_payload&& __other)
378  noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
379  is_nothrow_move_assignable<_Tp>>)
380  {
381  this->_M_move_assign(std::move(__other));
382  return *this;
383  }
384  };
385 
386  // Payload for optionals with non-trivial destructors.
387  template <typename _Tp, bool _Copy, bool _Move>
388  struct _Optional_payload<_Tp, false, _Copy, _Move>
389  : _Optional_payload<_Tp, true, false, false>
390  {
391  // Base class implements all the constructors and assignment operators:
392  using _Optional_payload<_Tp, true, false, false>::_Optional_payload;
393  _Optional_payload() = default;
394  _Optional_payload(const _Optional_payload&) = default;
395  _Optional_payload(_Optional_payload&&) = default;
396  _Optional_payload& operator=(const _Optional_payload&) = default;
397  _Optional_payload& operator=(_Optional_payload&&) = default;
398 
399  // Destructor needs to destroy the contained value:
400  ~_Optional_payload() { this->_M_reset(); }
401  };
402 
403  // Common base class for _Optional_base<T> to avoid repeating these
404  // member functions in each specialization.
405  template<typename _Tp, typename _Dp>
406  class _Optional_base_impl
407  {
408  protected:
409  using _Stored_type = remove_const_t<_Tp>;
410 
411  // The _M_construct operation has !_M_engaged as a precondition
412  // while _M_destruct has _M_engaged as a precondition.
413  template<typename... _Args>
414  void
415  _M_construct(_Args&&... __args)
416  noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
417  {
418  ::new
419  (std::__addressof(static_cast<_Dp*>(this)->_M_payload._M_payload))
420  _Stored_type(std::forward<_Args>(__args)...);
421  static_cast<_Dp*>(this)->_M_payload._M_engaged = true;
422  }
423 
424  void
425  _M_destruct() noexcept
426  { static_cast<_Dp*>(this)->_M_payload._M_destroy(); }
427 
428  // _M_reset is a 'safe' operation with no precondition.
429  constexpr void
430  _M_reset() noexcept
431  { static_cast<_Dp*>(this)->_M_payload._M_reset(); }
432 
433  constexpr bool _M_is_engaged() const noexcept
434  { return static_cast<const _Dp*>(this)->_M_payload._M_engaged; }
435 
436  // The _M_get operations have _M_engaged as a precondition.
437  constexpr _Tp&
438  _M_get() noexcept
439  {
440  __glibcxx_assert(this->_M_is_engaged());
441  return static_cast<_Dp*>(this)->_M_payload._M_get();
442  }
443 
444  constexpr const _Tp&
445  _M_get() const noexcept
446  {
447  __glibcxx_assert(this->_M_is_engaged());
448  return static_cast<const _Dp*>(this)->_M_payload._M_get();
449  }
450  };
451 
452  /**
453  * @brief Class template that provides copy/move constructors of optional.
454  *
455  * Such a separate base class template is necessary in order to
456  * conditionally make copy/move constructors trivial.
457  *
458  * When the contained value is trivially copy/move constructible,
459  * the copy/move constructors of _Optional_base will invoke the
460  * trivial copy/move constructor of _Optional_payload. Otherwise,
461  * they will invoke _Optional_payload(bool, const _Optional_payload&)
462  * or _Optional_payload(bool, _Optional_payload&&) to initialize
463  * the contained value, if copying/moving an engaged optional.
464  *
465  * Whether the other special members are trivial is determined by the
466  * _Optional_payload<_Tp> specialization used for the _M_payload member.
467  *
468  * @see optional, _Enable_special_members
469  */
470  template<typename _Tp,
471  bool = is_trivially_copy_constructible_v<_Tp>,
472  bool = is_trivially_move_constructible_v<_Tp>>
473  struct _Optional_base
474  : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
475  {
476  // Constructors for disengaged optionals.
477  constexpr _Optional_base() = default;
478 
479  // Constructors for engaged optionals.
480  template<typename... _Args,
481  enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
482  constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
483  : _M_payload(in_place,
484  std::forward<_Args>(__args)...) { }
485 
486  template<typename _Up, typename... _Args,
487  enable_if_t<is_constructible_v<_Tp,
488  initializer_list<_Up>&,
489  _Args&&...>, bool> = false>
490  constexpr explicit _Optional_base(in_place_t,
491  initializer_list<_Up> __il,
492  _Args&&... __args)
493  : _M_payload(in_place,
494  __il, std::forward<_Args>(__args)...)
495  { }
496 
497  // Copy and move constructors.
498  constexpr _Optional_base(const _Optional_base& __other)
499  : _M_payload(__other._M_payload._M_engaged,
500  __other._M_payload)
501  { }
502 
503  constexpr _Optional_base(_Optional_base&& __other)
504  noexcept(is_nothrow_move_constructible_v<_Tp>)
505  : _M_payload(__other._M_payload._M_engaged,
506  std::move(__other._M_payload))
507  { }
508 
509  // Assignment operators.
510  _Optional_base& operator=(const _Optional_base&) = default;
511  _Optional_base& operator=(_Optional_base&&) = default;
512 
513  _Optional_payload<_Tp> _M_payload;
514  };
515 
516  template<typename _Tp>
517  struct _Optional_base<_Tp, false, true>
518  : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
519  {
520  // Constructors for disengaged optionals.
521  constexpr _Optional_base() = default;
522 
523  // Constructors for engaged optionals.
524  template<typename... _Args,
525  enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
526  constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
527  : _M_payload(in_place,
528  std::forward<_Args>(__args)...) { }
529 
530  template<typename _Up, typename... _Args,
531  enable_if_t<is_constructible_v<_Tp,
532  initializer_list<_Up>&,
533  _Args&&...>, bool> = false>
534  constexpr explicit _Optional_base(in_place_t,
535  initializer_list<_Up> __il,
536  _Args&&... __args)
537  : _M_payload(in_place,
538  __il, std::forward<_Args>(__args)...)
539  { }
540 
541  // Copy and move constructors.
542  constexpr _Optional_base(const _Optional_base& __other)
543  : _M_payload(__other._M_payload._M_engaged,
544  __other._M_payload)
545  { }
546 
547  constexpr _Optional_base(_Optional_base&& __other) = default;
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 
556  template<typename _Tp>
557  struct _Optional_base<_Tp, true, false>
558  : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
559  {
560  // Constructors for disengaged optionals.
561  constexpr _Optional_base() = default;
562 
563  // Constructors for engaged optionals.
564  template<typename... _Args,
565  enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
566  constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
567  : _M_payload(in_place,
568  std::forward<_Args>(__args)...) { }
569 
570  template<typename _Up, typename... _Args,
571  enable_if_t<is_constructible_v<_Tp,
572  initializer_list<_Up>&,
573  _Args&&...>, bool> = false>
574  constexpr explicit _Optional_base(in_place_t,
575  initializer_list<_Up> __il,
576  _Args&&... __args)
577  : _M_payload(in_place,
578  __il, std::forward<_Args>(__args)...)
579  { }
580 
581  // Copy and move constructors.
582  constexpr _Optional_base(const _Optional_base& __other) = default;
583 
584  constexpr _Optional_base(_Optional_base&& __other)
585  noexcept(is_nothrow_move_constructible_v<_Tp>)
586  : _M_payload(__other._M_payload._M_engaged,
587  std::move(__other._M_payload))
588  { }
589 
590  // Assignment operators.
591  _Optional_base& operator=(const _Optional_base&) = default;
592  _Optional_base& operator=(_Optional_base&&) = default;
593 
594  _Optional_payload<_Tp> _M_payload;
595  };
596 
597  template<typename _Tp>
598  struct _Optional_base<_Tp, true, true>
599  : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
600  {
601  // Constructors for disengaged optionals.
602  constexpr _Optional_base() = default;
603 
604  // Constructors for engaged optionals.
605  template<typename... _Args,
606  enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
607  constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
608  : _M_payload(in_place,
609  std::forward<_Args>(__args)...) { }
610 
611  template<typename _Up, typename... _Args,
612  enable_if_t<is_constructible_v<_Tp,
613  initializer_list<_Up>&,
614  _Args&&...>, bool> = false>
615  constexpr explicit _Optional_base(in_place_t,
616  initializer_list<_Up> __il,
617  _Args&&... __args)
618  : _M_payload(in_place,
619  __il, std::forward<_Args>(__args)...)
620  { }
621 
622  // Copy and move constructors.
623  constexpr _Optional_base(const _Optional_base& __other) = default;
624  constexpr _Optional_base(_Optional_base&& __other) = default;
625 
626  // Assignment operators.
627  _Optional_base& operator=(const _Optional_base&) = default;
628  _Optional_base& operator=(_Optional_base&&) = default;
629 
630  _Optional_payload<_Tp> _M_payload;
631  };
632 
633  template<typename _Tp>
634  class optional;
635 
636  template<typename _Tp, typename _Up>
637  using __converts_from_optional =
638  __or_<is_constructible<_Tp, const optional<_Up>&>,
639  is_constructible<_Tp, optional<_Up>&>,
640  is_constructible<_Tp, const optional<_Up>&&>,
641  is_constructible<_Tp, optional<_Up>&&>,
642  is_convertible<const optional<_Up>&, _Tp>,
643  is_convertible<optional<_Up>&, _Tp>,
644  is_convertible<const optional<_Up>&&, _Tp>,
645  is_convertible<optional<_Up>&&, _Tp>>;
646 
647  template<typename _Tp, typename _Up>
648  using __assigns_from_optional =
649  __or_<is_assignable<_Tp&, const optional<_Up>&>,
650  is_assignable<_Tp&, optional<_Up>&>,
651  is_assignable<_Tp&, const optional<_Up>&&>,
652  is_assignable<_Tp&, optional<_Up>&&>>;
653 
654  /**
655  * @brief Class template for optional values.
656  */
657  template<typename _Tp>
658  class optional
659  : private _Optional_base<_Tp>,
660  private _Enable_copy_move<
661  // Copy constructor.
662  is_copy_constructible_v<_Tp>,
663  // Copy assignment.
664  __and_v<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>,
665  // Move constructor.
666  is_move_constructible_v<_Tp>,
667  // Move assignment.
668  __and_v<is_move_constructible<_Tp>, is_move_assignable<_Tp>>,
669  // Unique tag type.
670  optional<_Tp>>
671  {
672  static_assert(!is_same_v<remove_cv_t<_Tp>, nullopt_t>);
673  static_assert(!is_same_v<remove_cv_t<_Tp>, in_place_t>);
674  static_assert(!is_reference_v<_Tp>);
675 
676  private:
677  using _Base = _Optional_base<_Tp>;
678 
679  // SFINAE helpers
680  template<typename _Up>
681  using __not_self = __not_<is_same<optional, __remove_cvref_t<_Up>>>;
682  template<typename _Up>
683  using __not_tag = __not_<is_same<in_place_t, __remove_cvref_t<_Up>>>;
684  template<typename... _Cond>
685  using _Requires = enable_if_t<__and_v<_Cond...>, bool>;
686 
687  public:
688  using value_type = _Tp;
689 
690  constexpr optional() = default;
691 
692  constexpr optional(nullopt_t) noexcept { }
693 
694  // Converting constructors for engaged optionals.
695  template<typename _Up = _Tp,
696  _Requires<__not_self<_Up>, __not_tag<_Up>,
697  is_constructible<_Tp, _Up&&>,
698  is_convertible<_Up&&, _Tp>> = true>
699  constexpr
700  optional(_Up&& __t)
701  : _Base(std::in_place, std::forward<_Up>(__t)) { }
702 
703  template<typename _Up = _Tp,
704  _Requires<__not_self<_Up>, __not_tag<_Up>,
705  is_constructible<_Tp, _Up&&>,
706  __not_<is_convertible<_Up&&, _Tp>>> = false>
707  explicit constexpr
708  optional(_Up&& __t)
709  : _Base(std::in_place, std::forward<_Up>(__t)) { }
710 
711  template<typename _Up,
712  _Requires<__not_<is_same<_Tp, _Up>>,
713  is_constructible<_Tp, const _Up&>,
714  is_convertible<const _Up&, _Tp>,
715  __not_<__converts_from_optional<_Tp, _Up>>> = true>
716  constexpr
717  optional(const optional<_Up>& __t)
718  {
719  if (__t)
720  emplace(*__t);
721  }
722 
723  template<typename _Up,
724  _Requires<__not_<is_same<_Tp, _Up>>,
725  is_constructible<_Tp, const _Up&>,
726  __not_<is_convertible<const _Up&, _Tp>>,
727  __not_<__converts_from_optional<_Tp, _Up>>> = false>
728  explicit constexpr
729  optional(const optional<_Up>& __t)
730  {
731  if (__t)
732  emplace(*__t);
733  }
734 
735  template <typename _Up,
736  _Requires<__not_<is_same<_Tp, _Up>>,
737  is_constructible<_Tp, _Up&&>,
738  is_convertible<_Up&&, _Tp>,
739  __not_<__converts_from_optional<_Tp, _Up>>> = true>
740  constexpr
741  optional(optional<_Up>&& __t)
742  {
743  if (__t)
744  emplace(std::move(*__t));
745  }
746 
747  template <typename _Up,
748  _Requires<__not_<is_same<_Tp, _Up>>,
749  is_constructible<_Tp, _Up&&>,
750  __not_<is_convertible<_Up&&, _Tp>>,
751  __not_<__converts_from_optional<_Tp, _Up>>> = false>
752  explicit constexpr
753  optional(optional<_Up>&& __t)
754  {
755  if (__t)
756  emplace(std::move(*__t));
757  }
758 
759  template<typename... _Args,
760  _Requires<is_constructible<_Tp, _Args&&...>> = false>
761  explicit constexpr
762  optional(in_place_t, _Args&&... __args)
763  : _Base(std::in_place, std::forward<_Args>(__args)...) { }
764 
765  template<typename _Up, typename... _Args,
766  _Requires<is_constructible<_Tp,
767  initializer_list<_Up>&,
768  _Args&&...>> = false>
769  explicit constexpr
770  optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
771  : _Base(std::in_place, __il, std::forward<_Args>(__args)...) { }
772 
773  // Assignment operators.
774  optional&
775  operator=(nullopt_t) noexcept
776  {
777  this->_M_reset();
778  return *this;
779  }
780 
781  template<typename _Up = _Tp>
782  enable_if_t<__and_v<__not_self<_Up>,
783  __not_<__and_<is_scalar<_Tp>,
784  is_same<_Tp, decay_t<_Up>>>>,
785  is_constructible<_Tp, _Up>,
786  is_assignable<_Tp&, _Up>>,
787  optional&>
788  operator=(_Up&& __u)
789  {
790  if (this->_M_is_engaged())
791  this->_M_get() = std::forward<_Up>(__u);
792  else
793  this->_M_construct(std::forward<_Up>(__u));
794 
795  return *this;
796  }
797 
798  template<typename _Up>
799  enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
800  is_constructible<_Tp, const _Up&>,
801  is_assignable<_Tp&, const _Up&>,
802  __not_<__converts_from_optional<_Tp, _Up>>,
803  __not_<__assigns_from_optional<_Tp, _Up>>>,
804  optional&>
805  operator=(const optional<_Up>& __u)
806  {
807  if (__u)
808  {
809  if (this->_M_is_engaged())
810  this->_M_get() = *__u;
811  else
812  this->_M_construct(*__u);
813  }
814  else
815  {
816  this->_M_reset();
817  }
818  return *this;
819  }
820 
821  template<typename _Up>
822  enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
823  is_constructible<_Tp, _Up>,
824  is_assignable<_Tp&, _Up>,
825  __not_<__converts_from_optional<_Tp, _Up>>,
826  __not_<__assigns_from_optional<_Tp, _Up>>>,
827  optional&>
828  operator=(optional<_Up>&& __u)
829  {
830  if (__u)
831  {
832  if (this->_M_is_engaged())
833  this->_M_get() = std::move(*__u);
834  else
835  this->_M_construct(std::move(*__u));
836  }
837  else
838  {
839  this->_M_reset();
840  }
841 
842  return *this;
843  }
844 
845  template<typename... _Args>
846  enable_if_t<is_constructible_v<_Tp, _Args&&...>, _Tp&>
847  emplace(_Args&&... __args)
848  {
849  this->_M_reset();
850  this->_M_construct(std::forward<_Args>(__args)...);
851  return this->_M_get();
852  }
853 
854  template<typename _Up, typename... _Args>
855  enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&,
856  _Args&&...>, _Tp&>
857  emplace(initializer_list<_Up> __il, _Args&&... __args)
858  {
859  this->_M_reset();
860  this->_M_construct(__il, std::forward<_Args>(__args)...);
861  return this->_M_get();
862  }
863 
864  // Destructor is implicit, implemented in _Optional_base.
865 
866  // Swap.
867  void
868  swap(optional& __other)
869  noexcept(is_nothrow_move_constructible_v<_Tp>
870  && is_nothrow_swappable_v<_Tp>)
871  {
872  using std::swap;
873 
874  if (this->_M_is_engaged() && __other._M_is_engaged())
875  swap(this->_M_get(), __other._M_get());
876  else if (this->_M_is_engaged())
877  {
878  __other._M_construct(std::move(this->_M_get()));
879  this->_M_destruct();
880  }
881  else if (__other._M_is_engaged())
882  {
883  this->_M_construct(std::move(__other._M_get()));
884  __other._M_destruct();
885  }
886  }
887 
888  // Observers.
889  constexpr const _Tp*
890  operator->() const
891  { return std::__addressof(this->_M_get()); }
892 
893  constexpr _Tp*
894  operator->()
895  { return std::__addressof(this->_M_get()); }
896 
897  constexpr const _Tp&
898  operator*() const&
899  { return this->_M_get(); }
900 
901  constexpr _Tp&
902  operator*()&
903  { return this->_M_get(); }
904 
905  constexpr _Tp&&
906  operator*()&&
907  { return std::move(this->_M_get()); }
908 
909  constexpr const _Tp&&
910  operator*() const&&
911  { return std::move(this->_M_get()); }
912 
913  constexpr explicit operator bool() const noexcept
914  { return this->_M_is_engaged(); }
915 
916  constexpr bool has_value() const noexcept
917  { return this->_M_is_engaged(); }
918 
919  constexpr const _Tp&
920  value() const&
921  {
922  return this->_M_is_engaged()
923  ? this->_M_get()
924  : (__throw_bad_optional_access(), this->_M_get());
925  }
926 
927  constexpr _Tp&
928  value()&
929  {
930  return this->_M_is_engaged()
931  ? this->_M_get()
932  : (__throw_bad_optional_access(), this->_M_get());
933  }
934 
935  constexpr _Tp&&
936  value()&&
937  {
938  return this->_M_is_engaged()
939  ? std::move(this->_M_get())
940  : (__throw_bad_optional_access(), std::move(this->_M_get()));
941  }
942 
943  constexpr const _Tp&&
944  value() const&&
945  {
946  return this->_M_is_engaged()
947  ? std::move(this->_M_get())
948  : (__throw_bad_optional_access(), std::move(this->_M_get()));
949  }
950 
951  template<typename _Up>
952  constexpr _Tp
953  value_or(_Up&& __u) const&
954  {
955  static_assert(is_copy_constructible_v<_Tp>);
956  static_assert(is_convertible_v<_Up&&, _Tp>);
957 
958  return this->_M_is_engaged()
959  ? this->_M_get() : static_cast<_Tp>(std::forward<_Up>(__u));
960  }
961 
962  template<typename _Up>
963  constexpr _Tp
964  value_or(_Up&& __u) &&
965  {
966  static_assert(is_move_constructible_v<_Tp>);
967  static_assert(is_convertible_v<_Up&&, _Tp>);
968 
969  return this->_M_is_engaged()
970  ? std::move(this->_M_get())
971  : static_cast<_Tp>(std::forward<_Up>(__u));
972  }
973 
974  void reset() noexcept { this->_M_reset(); }
975  };
976 
977  template<typename _Tp>
978  using __optional_relop_t =
979  enable_if_t<is_convertible<_Tp, bool>::value, bool>;
980 
981  template<typename _Tp, typename _Up>
982  using __optional_eq_t = __optional_relop_t<
983  decltype(std::declval<const _Tp&>() == std::declval<const _Up&>())
984  >;
985 
986  template<typename _Tp, typename _Up>
987  using __optional_ne_t = __optional_relop_t<
988  decltype(std::declval<const _Tp&>() != std::declval<const _Up&>())
989  >;
990 
991  template<typename _Tp, typename _Up>
992  using __optional_lt_t = __optional_relop_t<
993  decltype(std::declval<const _Tp&>() < std::declval<const _Up&>())
994  >;
995 
996  template<typename _Tp, typename _Up>
997  using __optional_gt_t = __optional_relop_t<
998  decltype(std::declval<const _Tp&>() > std::declval<const _Up&>())
999  >;
1000 
1001  template<typename _Tp, typename _Up>
1002  using __optional_le_t = __optional_relop_t<
1003  decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>())
1004  >;
1005 
1006  template<typename _Tp, typename _Up>
1007  using __optional_ge_t = __optional_relop_t<
1008  decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>())
1009  >;
1010 
1011  // Comparisons between optional values.
1012  template<typename _Tp, typename _Up>
1013  constexpr auto
1014  operator==(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1015  -> __optional_eq_t<_Tp, _Up>
1016  {
1017  return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
1018  && (!__lhs || *__lhs == *__rhs);
1019  }
1020 
1021  template<typename _Tp, typename _Up>
1022  constexpr auto
1023  operator!=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1024  -> __optional_ne_t<_Tp, _Up>
1025  {
1026  return static_cast<bool>(__lhs) != static_cast<bool>(__rhs)
1027  || (static_cast<bool>(__lhs) && *__lhs != *__rhs);
1028  }
1029 
1030  template<typename _Tp, typename _Up>
1031  constexpr auto
1032  operator<(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1033  -> __optional_lt_t<_Tp, _Up>
1034  {
1035  return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
1036  }
1037 
1038  template<typename _Tp, typename _Up>
1039  constexpr auto
1040  operator>(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1041  -> __optional_gt_t<_Tp, _Up>
1042  {
1043  return static_cast<bool>(__lhs) && (!__rhs || *__lhs > *__rhs);
1044  }
1045 
1046  template<typename _Tp, typename _Up>
1047  constexpr auto
1048  operator<=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1049  -> __optional_le_t<_Tp, _Up>
1050  {
1051  return !__lhs || (static_cast<bool>(__rhs) && *__lhs <= *__rhs);
1052  }
1053 
1054  template<typename _Tp, typename _Up>
1055  constexpr auto
1056  operator>=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1057  -> __optional_ge_t<_Tp, _Up>
1058  {
1059  return !__rhs || (static_cast<bool>(__lhs) && *__lhs >= *__rhs);
1060  }
1061 
1062 #ifdef __cpp_lib_three_way_comparison
1063  template<typename _Tp, three_way_comparable_with<_Tp> _Up>
1064  constexpr compare_three_way_result_t<_Tp, _Up>
1065  operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y)
1066  {
1067  return __x && __y ? *__x <=> *__y : bool(__x) <=> bool(__y);
1068  }
1069 #endif
1070 
1071  // Comparisons with nullopt.
1072  template<typename _Tp>
1073  constexpr bool
1074  operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept
1075  { return !__lhs; }
1076 
1077 #ifdef __cpp_lib_three_way_comparison
1078  template<typename _Tp>
1079  constexpr strong_ordering
1080  operator<=>(const optional<_Tp>& __x, nullopt_t) noexcept
1081  { return bool(__x) <=> false; }
1082 #else
1083  template<typename _Tp>
1084  constexpr bool
1085  operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept
1086  { return !__rhs; }
1087 
1088  template<typename _Tp>
1089  constexpr bool
1090  operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept
1091  { return static_cast<bool>(__lhs); }
1092 
1093  template<typename _Tp>
1094  constexpr bool
1095  operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept
1096  { return static_cast<bool>(__rhs); }
1097 
1098  template<typename _Tp>
1099  constexpr bool
1100  operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
1101  { return false; }
1102 
1103  template<typename _Tp>
1104  constexpr bool
1105  operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
1106  { return static_cast<bool>(__rhs); }
1107 
1108  template<typename _Tp>
1109  constexpr bool
1110  operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept
1111  { return static_cast<bool>(__lhs); }
1112 
1113  template<typename _Tp>
1114  constexpr bool
1115  operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
1116  { return false; }
1117 
1118  template<typename _Tp>
1119  constexpr bool
1120  operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept
1121  { return !__lhs; }
1122 
1123  template<typename _Tp>
1124  constexpr bool
1125  operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
1126  { return true; }
1127 
1128  template<typename _Tp>
1129  constexpr bool
1130  operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
1131  { return true; }
1132 
1133  template<typename _Tp>
1134  constexpr bool
1135  operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept
1136  { return !__rhs; }
1137 #endif // three-way-comparison
1138 
1139  // Comparisons with value type.
1140  template<typename _Tp, typename _Up>
1141  constexpr auto
1142  operator==(const optional<_Tp>& __lhs, const _Up& __rhs)
1143  -> __optional_eq_t<_Tp, _Up>
1144  { return __lhs && *__lhs == __rhs; }
1145 
1146  template<typename _Tp, typename _Up>
1147  constexpr auto
1148  operator==(const _Up& __lhs, const optional<_Tp>& __rhs)
1149  -> __optional_eq_t<_Up, _Tp>
1150  { return __rhs && __lhs == *__rhs; }
1151 
1152  template<typename _Tp, typename _Up>
1153  constexpr auto
1154  operator!=(const optional<_Tp>& __lhs, const _Up& __rhs)
1155  -> __optional_ne_t<_Tp, _Up>
1156  { return !__lhs || *__lhs != __rhs; }
1157 
1158  template<typename _Tp, typename _Up>
1159  constexpr auto
1160  operator!=(const _Up& __lhs, const optional<_Tp>& __rhs)
1161  -> __optional_ne_t<_Up, _Tp>
1162  { return !__rhs || __lhs != *__rhs; }
1163 
1164  template<typename _Tp, typename _Up>
1165  constexpr auto
1166  operator<(const optional<_Tp>& __lhs, const _Up& __rhs)
1167  -> __optional_lt_t<_Tp, _Up>
1168  { return !__lhs || *__lhs < __rhs; }
1169 
1170  template<typename _Tp, typename _Up>
1171  constexpr auto
1172  operator<(const _Up& __lhs, const optional<_Tp>& __rhs)
1173  -> __optional_lt_t<_Up, _Tp>
1174  { return __rhs && __lhs < *__rhs; }
1175 
1176  template<typename _Tp, typename _Up>
1177  constexpr auto
1178  operator>(const optional<_Tp>& __lhs, const _Up& __rhs)
1179  -> __optional_gt_t<_Tp, _Up>
1180  { return __lhs && *__lhs > __rhs; }
1181 
1182  template<typename _Tp, typename _Up>
1183  constexpr auto
1184  operator>(const _Up& __lhs, const optional<_Tp>& __rhs)
1185  -> __optional_gt_t<_Up, _Tp>
1186  { return !__rhs || __lhs > *__rhs; }
1187 
1188  template<typename _Tp, typename _Up>
1189  constexpr auto
1190  operator<=(const optional<_Tp>& __lhs, const _Up& __rhs)
1191  -> __optional_le_t<_Tp, _Up>
1192  { return !__lhs || *__lhs <= __rhs; }
1193 
1194  template<typename _Tp, typename _Up>
1195  constexpr auto
1196  operator<=(const _Up& __lhs, const optional<_Tp>& __rhs)
1197  -> __optional_le_t<_Up, _Tp>
1198  { return __rhs && __lhs <= *__rhs; }
1199 
1200  template<typename _Tp, typename _Up>
1201  constexpr auto
1202  operator>=(const optional<_Tp>& __lhs, const _Up& __rhs)
1203  -> __optional_ge_t<_Tp, _Up>
1204  { return __lhs && *__lhs >= __rhs; }
1205 
1206  template<typename _Tp, typename _Up>
1207  constexpr auto
1208  operator>=(const _Up& __lhs, const optional<_Tp>& __rhs)
1209  -> __optional_ge_t<_Up, _Tp>
1210  { return !__rhs || __lhs >= *__rhs; }
1211 
1212 #ifdef __cpp_lib_three_way_comparison
1213  template<typename _Tp>
1214  inline constexpr bool __is_optional_v = false;
1215  template<typename _Tp>
1216  inline constexpr bool __is_optional_v<optional<_Tp>> = true;
1217 
1218  template<typename _Tp, typename _Up>
1219  requires (!__is_optional_v<_Up>)
1220  && three_way_comparable_with<_Tp, _Up>
1221  constexpr compare_three_way_result_t<_Tp, _Up>
1222  operator<=>(const optional<_Tp>& __x, const _Up& __v)
1223  { return bool(__x) ? *__x <=> __v : strong_ordering::less; }
1224 #endif
1225 
1226  // Swap and creation functions.
1227 
1228  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1229  // 2748. swappable traits for optionals
1230  template<typename _Tp>
1231  inline enable_if_t<is_move_constructible_v<_Tp> && is_swappable_v<_Tp>>
1232  swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
1233  noexcept(noexcept(__lhs.swap(__rhs)))
1234  { __lhs.swap(__rhs); }
1235 
1236  template<typename _Tp>
1237  enable_if_t<!(is_move_constructible_v<_Tp> && is_swappable_v<_Tp>)>
1238  swap(optional<_Tp>&, optional<_Tp>&) = delete;
1239 
1240  template<typename _Tp>
1241  constexpr optional<decay_t<_Tp>>
1242  make_optional(_Tp&& __t)
1243  { return optional<decay_t<_Tp>> { std::forward<_Tp>(__t) }; }
1244 
1245  template<typename _Tp, typename ..._Args>
1246  constexpr optional<_Tp>
1247  make_optional(_Args&&... __args)
1248  { return optional<_Tp> { in_place, std::forward<_Args>(__args)... }; }
1249 
1250  template<typename _Tp, typename _Up, typename ..._Args>
1251  constexpr optional<_Tp>
1252  make_optional(initializer_list<_Up> __il, _Args&&... __args)
1253  { return optional<_Tp> { in_place, __il, std::forward<_Args>(__args)... }; }
1254 
1255  // Hash.
1256 
1257  template<typename _Tp, typename _Up = remove_const_t<_Tp>,
1258  bool = __poison_hash<_Up>::__enable_hash_call>
1259  struct __optional_hash_call_base
1260  {
1261  size_t
1262  operator()(const optional<_Tp>& __t) const
1263  noexcept(noexcept(hash<_Up>{}(*__t)))
1264  {
1265  // We pick an arbitrary hash for disengaged optionals which hopefully
1266  // usual values of _Tp won't typically hash to.
1267  constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333);
1268  return __t ? hash<_Up>{}(*__t) : __magic_disengaged_hash;
1269  }
1270  };
1271 
1272  template<typename _Tp, typename _Up>
1273  struct __optional_hash_call_base<_Tp, _Up, false> {};
1274 
1275  template<typename _Tp>
1276  struct hash<optional<_Tp>>
1277  : private __poison_hash<remove_const_t<_Tp>>,
1278  public __optional_hash_call_base<_Tp>
1279  {
1280  using result_type [[__deprecated__]] = size_t;
1281  using argument_type [[__deprecated__]] = optional<_Tp>;
1282  };
1283 
1284  template<typename _Tp>
1285  struct __is_fast_hash<hash<optional<_Tp>>> : __is_fast_hash<hash<_Tp>>
1286  { };
1287 
1288  /// @}
1289 
1290 #if __cpp_deduction_guides >= 201606
1291  template <typename _Tp> optional(_Tp) -> optional<_Tp>;
1292 #endif
1293 
1294 _GLIBCXX_END_NAMESPACE_VERSION
1295 } // namespace std
1296 
1297 #endif // C++17
1298 
1299 #endif // _GLIBCXX_OPTIONAL