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