libstdc++
optional
Go to the documentation of this file.
1 // <optional> -*- C++ -*-
2 
3 // Copyright (C) 2013-2021 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>
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  */
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>>
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
483  _Optional_base(in_place_t, _Args&&... __args)
484  : _M_payload(in_place, std::forward<_Args>(__args)...)
485  { }
486 
487  template<typename _Up, typename... _Args,
488  enable_if_t<is_constructible_v<_Tp,
490  _Args...>, bool> = false>
491  constexpr explicit
492  _Optional_base(in_place_t,
494  _Args&&... __args)
495  : _M_payload(in_place, __il, std::forward<_Args>(__args)...)
496  { }
497 
498  // Copy and move constructors.
499  constexpr
500  _Optional_base(const _Optional_base& __other)
501  : _M_payload(__other._M_payload._M_engaged, __other._M_payload)
502  { }
503 
504  constexpr
505  _Optional_base(_Optional_base&& __other)
506  noexcept(is_nothrow_move_constructible_v<_Tp>)
507  : _M_payload(__other._M_payload._M_engaged,
508  std::move(__other._M_payload))
509  { }
510 
511  // Assignment operators.
512  _Optional_base& operator=(const _Optional_base&) = default;
513  _Optional_base& operator=(_Optional_base&&) = default;
514 
515  _Optional_payload<_Tp> _M_payload;
516  };
517 
518  template<typename _Tp>
520  : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
521  {
522  // Constructors for disengaged optionals.
523  constexpr _Optional_base() = default;
524 
525  // Constructors for engaged optionals.
526  template<typename... _Args,
527  enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
528  constexpr explicit
529  _Optional_base(in_place_t, _Args&&... __args)
530  : _M_payload(in_place, std::forward<_Args>(__args)...)
531  { }
532 
533  template<typename _Up, typename... _Args,
534  enable_if_t<is_constructible_v<_Tp,
535  initializer_list<_Up>&,
536  _Args...>, bool> = false>
537  constexpr explicit
538  _Optional_base(in_place_t,
539  initializer_list<_Up> __il,
540  _Args... __args)
541  : _M_payload(in_place, __il, std::forward<_Args>(__args)...)
542  { }
543 
544  // Copy and move constructors.
545  constexpr _Optional_base(const _Optional_base& __other)
546  : _M_payload(__other._M_payload._M_engaged, __other._M_payload)
547  { }
548 
549  constexpr _Optional_base(_Optional_base&& __other) = default;
550 
551  // Assignment operators.
552  _Optional_base& operator=(const _Optional_base&) = default;
553  _Optional_base& operator=(_Optional_base&&) = default;
554 
555  _Optional_payload<_Tp> _M_payload;
556  };
557 
558  template<typename _Tp>
559  struct _Optional_base<_Tp, true, false>
560  : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
561  {
562  // Constructors for disengaged optionals.
563  constexpr _Optional_base() = default;
564 
565  // Constructors for engaged optionals.
566  template<typename... _Args,
567  enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
568  constexpr explicit
569  _Optional_base(in_place_t, _Args&&... __args)
570  : _M_payload(in_place, std::forward<_Args>(__args)...)
571  { }
572 
573  template<typename _Up, typename... _Args,
574  enable_if_t<is_constructible_v<_Tp,
575  initializer_list<_Up>&,
576  _Args...>, bool> = false>
577  constexpr explicit
578  _Optional_base(in_place_t,
579  initializer_list<_Up> __il,
580  _Args&&... __args)
581  : _M_payload(in_place, __il, std::forward<_Args>(__args)...)
582  { }
583 
584  // Copy and move constructors.
585  constexpr _Optional_base(const _Optional_base& __other) = default;
586 
587  constexpr
588  _Optional_base(_Optional_base&& __other)
589  noexcept(is_nothrow_move_constructible_v<_Tp>)
590  : _M_payload(__other._M_payload._M_engaged,
591  std::move(__other._M_payload))
592  { }
593 
594  // Assignment operators.
595  _Optional_base& operator=(const _Optional_base&) = default;
596  _Optional_base& operator=(_Optional_base&&) = default;
597 
598  _Optional_payload<_Tp> _M_payload;
599  };
600 
601  template<typename _Tp>
602  struct _Optional_base<_Tp, true, true>
603  : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
604  {
605  // Constructors for disengaged optionals.
606  constexpr _Optional_base() = default;
607 
608  // Constructors for engaged optionals.
609  template<typename... _Args,
610  enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
611  constexpr explicit
612  _Optional_base(in_place_t, _Args&&... __args)
613  : _M_payload(in_place, std::forward<_Args>(__args)...)
614  { }
615 
616  template<typename _Up, typename... _Args,
617  enable_if_t<is_constructible_v<_Tp,
618  initializer_list<_Up>&,
619  _Args...>, bool> = false>
620  constexpr explicit
621  _Optional_base(in_place_t,
622  initializer_list<_Up> __il,
623  _Args&&... __args)
624  : _M_payload(in_place, __il, std::forward<_Args>(__args)...)
625  { }
626 
627  // Copy and move constructors.
628  constexpr _Optional_base(const _Optional_base& __other) = default;
629  constexpr _Optional_base(_Optional_base&& __other) = default;
630 
631  // Assignment operators.
632  _Optional_base& operator=(const _Optional_base&) = default;
633  _Optional_base& operator=(_Optional_base&&) = default;
634 
635  _Optional_payload<_Tp> _M_payload;
636  };
637 
638  template<typename _Tp>
639  class optional;
640 
641  template<typename _Tp, typename _Up>
642  using __converts_from_optional =
643  __or_<is_constructible<_Tp, const optional<_Up>&>,
644  is_constructible<_Tp, optional<_Up>&>,
645  is_constructible<_Tp, const optional<_Up>&&>,
646  is_constructible<_Tp, optional<_Up>&&>,
647  is_convertible<const optional<_Up>&, _Tp>,
648  is_convertible<optional<_Up>&, _Tp>,
649  is_convertible<const optional<_Up>&&, _Tp>,
650  is_convertible<optional<_Up>&&, _Tp>>;
651 
652  template<typename _Tp, typename _Up>
653  using __assigns_from_optional =
654  __or_<is_assignable<_Tp&, const optional<_Up>&>,
655  is_assignable<_Tp&, optional<_Up>&>,
656  is_assignable<_Tp&, const optional<_Up>&&>,
657  is_assignable<_Tp&, optional<_Up>&&>>;
658 
659  /**
660  * @brief Class template for optional values.
661  */
662  template<typename _Tp>
663  class optional
664  : private _Optional_base<_Tp>,
665  private _Enable_copy_move<
666  // Copy constructor.
667  is_copy_constructible_v<_Tp>,
668  // Copy assignment.
669  __and_v<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>,
670  // Move constructor.
671  is_move_constructible_v<_Tp>,
672  // Move assignment.
673  __and_v<is_move_constructible<_Tp>, is_move_assignable<_Tp>>,
674  // Unique tag type.
675  optional<_Tp>>
676  {
677  static_assert(!is_same_v<remove_cv_t<_Tp>, nullopt_t>);
678  static_assert(!is_same_v<remove_cv_t<_Tp>, in_place_t>);
679  static_assert(!is_reference_v<_Tp>);
680 
681  private:
682  using _Base = _Optional_base<_Tp>;
683 
684  // SFINAE helpers
685  template<typename _Up>
686  using __not_self = __not_<is_same<optional, __remove_cvref_t<_Up>>>;
687  template<typename _Up>
688  using __not_tag = __not_<is_same<in_place_t, __remove_cvref_t<_Up>>>;
689  template<typename... _Cond>
690  using _Requires = enable_if_t<__and_v<_Cond...>, bool>;
691 
692  public:
693  using value_type = _Tp;
694 
695  constexpr optional() noexcept { }
696 
697  constexpr optional(nullopt_t) noexcept { }
698 
699  // Converting constructors for engaged optionals.
700  template<typename _Up = _Tp,
701  _Requires<__not_self<_Up>, __not_tag<_Up>,
703  is_convertible<_Up, _Tp>> = true>
704  constexpr
705  optional(_Up&& __t)
706  noexcept(is_nothrow_constructible_v<_Tp, _Up>)
707  : _Base(std::in_place, std::forward<_Up>(__t)) { }
708 
709  template<typename _Up = _Tp,
710  _Requires<__not_self<_Up>, __not_tag<_Up>,
712  __not_<is_convertible<_Up, _Tp>>> = false>
713  explicit constexpr
714  optional(_Up&& __t)
715  noexcept(is_nothrow_constructible_v<_Tp, _Up>)
716  : _Base(std::in_place, std::forward<_Up>(__t)) { }
717 
718  template<typename _Up,
719  _Requires<__not_<is_same<_Tp, _Up>>,
722  __not_<__converts_from_optional<_Tp, _Up>>> = true>
723  constexpr
724  optional(const optional<_Up>& __t)
725  noexcept(is_nothrow_constructible_v<_Tp, const _Up&>)
726  {
727  if (__t)
728  emplace(*__t);
729  }
730 
731  template<typename _Up,
732  _Requires<__not_<is_same<_Tp, _Up>>,
734  __not_<is_convertible<const _Up&, _Tp>>,
735  __not_<__converts_from_optional<_Tp, _Up>>> = false>
736  explicit constexpr
737  optional(const optional<_Up>& __t)
738  noexcept(is_nothrow_constructible_v<_Tp, const _Up&>)
739  {
740  if (__t)
741  emplace(*__t);
742  }
743 
744  template<typename _Up,
745  _Requires<__not_<is_same<_Tp, _Up>>,
748  __not_<__converts_from_optional<_Tp, _Up>>> = true>
749  constexpr
750  optional(optional<_Up>&& __t)
751  noexcept(is_nothrow_constructible_v<_Tp, _Up>)
752  {
753  if (__t)
754  emplace(std::move(*__t));
755  }
756 
757  template<typename _Up,
758  _Requires<__not_<is_same<_Tp, _Up>>,
760  __not_<is_convertible<_Up, _Tp>>,
761  __not_<__converts_from_optional<_Tp, _Up>>> = false>
762  explicit constexpr
763  optional(optional<_Up>&& __t)
764  noexcept(is_nothrow_constructible_v<_Tp, _Up>)
765  {
766  if (__t)
767  emplace(std::move(*__t));
768  }
769 
770  template<typename... _Args,
771  _Requires<is_constructible<_Tp, _Args...>> = false>
772  explicit constexpr
773  optional(in_place_t, _Args&&... __args)
774  noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
775  : _Base(std::in_place, std::forward<_Args>(__args)...) { }
776 
777  template<typename _Up, typename... _Args,
778  _Requires<is_constructible<_Tp,
780  _Args...>> = false>
781  explicit constexpr
782  optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
783  noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
784  _Args...>)
785  : _Base(std::in_place, __il, std::forward<_Args>(__args)...) { }
786 
787 
788  // Assignment operators.
789  optional&
790  operator=(nullopt_t) noexcept
791  {
792  this->_M_reset();
793  return *this;
794  }
795 
796  template<typename _Up = _Tp>
798  __not_<__and_<is_scalar<_Tp>,
802  optional&>
803  operator=(_Up&& __u)
804  noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>,
806  {
807  if (this->_M_is_engaged())
808  this->_M_get() = std::forward<_Up>(__u);
809  else
810  this->_M_construct(std::forward<_Up>(__u));
811 
812  return *this;
813  }
814 
815  template<typename _Up>
819  __not_<__converts_from_optional<_Tp, _Up>>,
820  __not_<__assigns_from_optional<_Tp, _Up>>>,
821  optional&>
822  operator=(const optional<_Up>& __u)
825  {
826  if (__u)
827  {
828  if (this->_M_is_engaged())
829  this->_M_get() = *__u;
830  else
831  this->_M_construct(*__u);
832  }
833  else
834  {
835  this->_M_reset();
836  }
837  return *this;
838  }
839 
840  template<typename _Up>
844  __not_<__converts_from_optional<_Tp, _Up>>,
845  __not_<__assigns_from_optional<_Tp, _Up>>>,
846  optional&>
847  operator=(optional<_Up>&& __u)
848  noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>,
850  {
851  if (__u)
852  {
853  if (this->_M_is_engaged())
854  this->_M_get() = std::move(*__u);
855  else
856  this->_M_construct(std::move(*__u));
857  }
858  else
859  {
860  this->_M_reset();
861  }
862 
863  return *this;
864  }
865 
866  template<typename... _Args>
867  enable_if_t<is_constructible_v<_Tp, _Args...>, _Tp&>
868  emplace(_Args&&... __args)
869  noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
870  {
871  this->_M_reset();
872  this->_M_construct(std::forward<_Args>(__args)...);
873  return this->_M_get();
874  }
875 
876  template<typename _Up, typename... _Args>
878  _Tp&>
879  emplace(initializer_list<_Up> __il, _Args&&... __args)
880  noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
881  _Args...>)
882  {
883  this->_M_reset();
884  this->_M_construct(__il, std::forward<_Args>(__args)...);
885  return this->_M_get();
886  }
887 
888  // Destructor is implicit, implemented in _Optional_base.
889 
890  // Swap.
891  void
892  swap(optional& __other)
893  noexcept(is_nothrow_move_constructible_v<_Tp>
894  && is_nothrow_swappable_v<_Tp>)
895  {
896  using std::swap;
897 
898  if (this->_M_is_engaged() && __other._M_is_engaged())
899  swap(this->_M_get(), __other._M_get());
900  else if (this->_M_is_engaged())
901  {
902  __other._M_construct(std::move(this->_M_get()));
903  this->_M_destruct();
904  }
905  else if (__other._M_is_engaged())
906  {
907  this->_M_construct(std::move(__other._M_get()));
908  __other._M_destruct();
909  }
910  }
911 
912  // Observers.
913  constexpr const _Tp*
914  operator->() const noexcept
915  { return std::__addressof(this->_M_get()); }
916 
917  constexpr _Tp*
918  operator->() noexcept
919  { return std::__addressof(this->_M_get()); }
920 
921  constexpr const _Tp&
922  operator*() const& noexcept
923  { return this->_M_get(); }
924 
925  constexpr _Tp&
926  operator*()& noexcept
927  { return this->_M_get(); }
928 
929  constexpr _Tp&&
930  operator*()&& noexcept
931  { return std::move(this->_M_get()); }
932 
933  constexpr const _Tp&&
934  operator*() const&& noexcept
935  { return std::move(this->_M_get()); }
936 
937  constexpr explicit operator bool() const noexcept
938  { return this->_M_is_engaged(); }
939 
940  constexpr bool has_value() const noexcept
941  { return this->_M_is_engaged(); }
942 
943  constexpr const _Tp&
944  value() const&
945  {
946  return this->_M_is_engaged()
947  ? this->_M_get()
948  : (__throw_bad_optional_access(), this->_M_get());
949  }
950 
951  constexpr _Tp&
952  value()&
953  {
954  return this->_M_is_engaged()
955  ? this->_M_get()
956  : (__throw_bad_optional_access(), this->_M_get());
957  }
958 
959  constexpr _Tp&&
960  value()&&
961  {
962  return this->_M_is_engaged()
963  ? std::move(this->_M_get())
964  : (__throw_bad_optional_access(), std::move(this->_M_get()));
965  }
966 
967  constexpr const _Tp&&
968  value() const&&
969  {
970  return this->_M_is_engaged()
971  ? std::move(this->_M_get())
972  : (__throw_bad_optional_access(), std::move(this->_M_get()));
973  }
974 
975  template<typename _Up>
976  constexpr _Tp
977  value_or(_Up&& __u) const&
978  {
979  static_assert(is_copy_constructible_v<_Tp>);
980  static_assert(is_convertible_v<_Up&&, _Tp>);
981 
982  return this->_M_is_engaged()
983  ? this->_M_get() : static_cast<_Tp>(std::forward<_Up>(__u));
984  }
985 
986  template<typename _Up>
987  constexpr _Tp
988  value_or(_Up&& __u) &&
989  {
990  static_assert(is_move_constructible_v<_Tp>);
991  static_assert(is_convertible_v<_Up&&, _Tp>);
992 
993  return this->_M_is_engaged()
994  ? std::move(this->_M_get())
995  : static_cast<_Tp>(std::forward<_Up>(__u));
996  }
997 
998  void reset() noexcept { this->_M_reset(); }
999  };
1000 
1001  template<typename _Tp>
1002  using __optional_relop_t =
1004 
1005  template<typename _Tp, typename _Up>
1006  using __optional_eq_t = __optional_relop_t<
1007  decltype(std::declval<const _Tp&>() == std::declval<const _Up&>())
1008  >;
1009 
1010  template<typename _Tp, typename _Up>
1011  using __optional_ne_t = __optional_relop_t<
1012  decltype(std::declval<const _Tp&>() != std::declval<const _Up&>())
1013  >;
1014 
1015  template<typename _Tp, typename _Up>
1016  using __optional_lt_t = __optional_relop_t<
1017  decltype(std::declval<const _Tp&>() < std::declval<const _Up&>())
1018  >;
1019 
1020  template<typename _Tp, typename _Up>
1021  using __optional_gt_t = __optional_relop_t<
1022  decltype(std::declval<const _Tp&>() > std::declval<const _Up&>())
1023  >;
1024 
1025  template<typename _Tp, typename _Up>
1026  using __optional_le_t = __optional_relop_t<
1027  decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>())
1028  >;
1029 
1030  template<typename _Tp, typename _Up>
1031  using __optional_ge_t = __optional_relop_t<
1032  decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>())
1033  >;
1034 
1035  // Comparisons between optional values.
1036  template<typename _Tp, typename _Up>
1037  constexpr auto
1038  operator==(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1039  -> __optional_eq_t<_Tp, _Up>
1040  {
1041  return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
1042  && (!__lhs || *__lhs == *__rhs);
1043  }
1044 
1045  template<typename _Tp, typename _Up>
1046  constexpr auto
1047  operator!=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1048  -> __optional_ne_t<_Tp, _Up>
1049  {
1050  return static_cast<bool>(__lhs) != static_cast<bool>(__rhs)
1051  || (static_cast<bool>(__lhs) && *__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_lt_t<_Tp, _Up>
1058  {
1059  return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
1060  }
1061 
1062  template<typename _Tp, typename _Up>
1063  constexpr auto
1064  operator>(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1065  -> __optional_gt_t<_Tp, _Up>
1066  {
1067  return static_cast<bool>(__lhs) && (!__rhs || *__lhs > *__rhs);
1068  }
1069 
1070  template<typename _Tp, typename _Up>
1071  constexpr auto
1072  operator<=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1073  -> __optional_le_t<_Tp, _Up>
1074  {
1075  return !__lhs || (static_cast<bool>(__rhs) && *__lhs <= *__rhs);
1076  }
1077 
1078  template<typename _Tp, typename _Up>
1079  constexpr auto
1080  operator>=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1081  -> __optional_ge_t<_Tp, _Up>
1082  {
1083  return !__rhs || (static_cast<bool>(__lhs) && *__lhs >= *__rhs);
1084  }
1085 
1086 #ifdef __cpp_lib_three_way_comparison
1087  template<typename _Tp, three_way_comparable_with<_Tp> _Up>
1088  constexpr compare_three_way_result_t<_Tp, _Up>
1089  operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y)
1090  {
1091  return __x && __y ? *__x <=> *__y : bool(__x) <=> bool(__y);
1092  }
1093 #endif
1094 
1095  // Comparisons with nullopt.
1096  template<typename _Tp>
1097  constexpr bool
1098  operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept
1099  { return !__lhs; }
1100 
1101 #ifdef __cpp_lib_three_way_comparison
1102  template<typename _Tp>
1103  constexpr strong_ordering
1104  operator<=>(const optional<_Tp>& __x, nullopt_t) noexcept
1105  { return bool(__x) <=> false; }
1106 #else
1107  template<typename _Tp>
1108  constexpr bool
1109  operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept
1110  { return !__rhs; }
1111 
1112  template<typename _Tp>
1113  constexpr bool
1114  operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept
1115  { return static_cast<bool>(__lhs); }
1116 
1117  template<typename _Tp>
1118  constexpr bool
1119  operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept
1120  { return static_cast<bool>(__rhs); }
1121 
1122  template<typename _Tp>
1123  constexpr bool
1124  operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
1125  { return false; }
1126 
1127  template<typename _Tp>
1128  constexpr bool
1129  operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
1130  { return static_cast<bool>(__rhs); }
1131 
1132  template<typename _Tp>
1133  constexpr bool
1134  operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept
1135  { return static_cast<bool>(__lhs); }
1136 
1137  template<typename _Tp>
1138  constexpr bool
1139  operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
1140  { return false; }
1141 
1142  template<typename _Tp>
1143  constexpr bool
1144  operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept
1145  { return !__lhs; }
1146 
1147  template<typename _Tp>
1148  constexpr bool
1149  operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
1150  { return true; }
1151 
1152  template<typename _Tp>
1153  constexpr bool
1154  operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
1155  { return true; }
1156 
1157  template<typename _Tp>
1158  constexpr bool
1159  operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept
1160  { return !__rhs; }
1161 #endif // three-way-comparison
1162 
1163  // Comparisons with value type.
1164  template<typename _Tp, typename _Up>
1165  constexpr auto
1166  operator==(const optional<_Tp>& __lhs, const _Up& __rhs)
1167  -> __optional_eq_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_eq_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_ne_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_ne_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_lt_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_lt_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_gt_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_gt_t<_Up, _Tp>
1210  { return !__rhs || __lhs > *__rhs; }
1211 
1212  template<typename _Tp, typename _Up>
1213  constexpr auto
1214  operator<=(const optional<_Tp>& __lhs, const _Up& __rhs)
1215  -> __optional_le_t<_Tp, _Up>
1216  { return !__lhs || *__lhs <= __rhs; }
1217 
1218  template<typename _Tp, typename _Up>
1219  constexpr auto
1220  operator<=(const _Up& __lhs, const optional<_Tp>& __rhs)
1221  -> __optional_le_t<_Up, _Tp>
1222  { return __rhs && __lhs <= *__rhs; }
1223 
1224  template<typename _Tp, typename _Up>
1225  constexpr auto
1226  operator>=(const optional<_Tp>& __lhs, const _Up& __rhs)
1227  -> __optional_ge_t<_Tp, _Up>
1228  { return __lhs && *__lhs >= __rhs; }
1229 
1230  template<typename _Tp, typename _Up>
1231  constexpr auto
1232  operator>=(const _Up& __lhs, const optional<_Tp>& __rhs)
1233  -> __optional_ge_t<_Up, _Tp>
1234  { return !__rhs || __lhs >= *__rhs; }
1235 
1236 #ifdef __cpp_lib_three_way_comparison
1237  template<typename _Tp>
1238  inline constexpr bool __is_optional_v = false;
1239  template<typename _Tp>
1240  inline constexpr bool __is_optional_v<optional<_Tp>> = true;
1241 
1242  template<typename _Tp, typename _Up>
1243  requires (!__is_optional_v<_Up>)
1244  && three_way_comparable_with<_Tp, _Up>
1245  constexpr compare_three_way_result_t<_Tp, _Up>
1246  operator<=>(const optional<_Tp>& __x, const _Up& __v)
1247  { return bool(__x) ? *__x <=> __v : strong_ordering::less; }
1248 #endif
1249 
1250  // Swap and creation functions.
1251 
1252  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1253  // 2748. swappable traits for optionals
1254  template<typename _Tp>
1255  inline enable_if_t<is_move_constructible_v<_Tp> && is_swappable_v<_Tp>>
1256  swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
1257  noexcept(noexcept(__lhs.swap(__rhs)))
1258  { __lhs.swap(__rhs); }
1259 
1260  template<typename _Tp>
1261  enable_if_t<!(is_move_constructible_v<_Tp> && is_swappable_v<_Tp>)>
1262  swap(optional<_Tp>&, optional<_Tp>&) = delete;
1263 
1264  template<typename _Tp>
1265  constexpr
1266  enable_if_t<is_constructible_v<decay_t<_Tp>, _Tp>,
1267  optional<decay_t<_Tp>>>
1268  make_optional(_Tp&& __t)
1269  noexcept(is_nothrow_constructible_v<optional<decay_t<_Tp>>, _Tp>)
1270  { return optional<decay_t<_Tp>>{ std::forward<_Tp>(__t) }; }
1271 
1272  template<typename _Tp, typename... _Args>
1273  constexpr
1274  enable_if_t<is_constructible_v<_Tp, _Args...>,
1275  optional<_Tp>>
1276  make_optional(_Args&&... __args)
1277  noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
1278  { return optional<_Tp>{ in_place, std::forward<_Args>(__args)... }; }
1279 
1280  template<typename _Tp, typename _Up, typename... _Args>
1281  constexpr
1282  enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1283  optional<_Tp>>
1284  make_optional(initializer_list<_Up> __il, _Args&&... __args)
1285  noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>)
1286  { return optional<_Tp>{ in_place, __il, std::forward<_Args>(__args)... }; }
1287 
1288  // Hash.
1289 
1290  template<typename _Tp, typename _Up = remove_const_t<_Tp>,
1291  bool = __poison_hash<_Up>::__enable_hash_call>
1292  struct __optional_hash_call_base
1293  {
1294  size_t
1295  operator()(const optional<_Tp>& __t) const
1296  noexcept(noexcept(hash<_Up>{}(*__t)))
1297  {
1298  // We pick an arbitrary hash for disengaged optionals which hopefully
1299  // usual values of _Tp won't typically hash to.
1300  constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333);
1301  return __t ? hash<_Up>{}(*__t) : __magic_disengaged_hash;
1302  }
1303  };
1304 
1305  template<typename _Tp, typename _Up>
1306  struct __optional_hash_call_base<_Tp, _Up, false> {};
1307 
1308  template<typename _Tp>
1309  struct hash<optional<_Tp>>
1310  : private __poison_hash<remove_const_t<_Tp>>,
1311  public __optional_hash_call_base<_Tp>
1312  {
1313  using result_type [[__deprecated__]] = size_t;
1314  using argument_type [[__deprecated__]] = optional<_Tp>;
1315  };
1316 
1317  template<typename _Tp>
1318  struct __is_fast_hash<hash<optional<_Tp>>> : __is_fast_hash<hash<_Tp>>
1319  { };
1320 
1321  /// @}
1322 
1323 #if __cpp_deduction_guides >= 201606
1324  template <typename _Tp> optional(_Tp) -> optional<_Tp>;
1325 #endif
1326 
1327 _GLIBCXX_END_NAMESPACE_VERSION
1328 } // namespace std
1329 
1330 #endif // C++17
1331 
1332 #endif // _GLIBCXX_OPTIONAL
constexpr complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
Definition: complex:392
typename remove_cv< _Tp >::type remove_cv_t
Alias template for remove_cv.
Definition: type_traits:1584
typename enable_if< _Cond, _Tp >::type enable_if_t
Alias template for enable_if.
Definition: type_traits:2585
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Definition: move.h:49
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition: move.h:104
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Definition: move.h:77
constexpr nullopt_t nullopt
Tag to disengage optional objects.
Definition: optional:77
void swap(any &__x, any &__y) noexcept
Exchange the states of two any objects.
Definition: any:422
ISO C++ entities toplevel namespace is std.
initializer_list
Class template for optional values.
Definition: optional:676
Tag type to disengage optional objects.
Definition: optional:64
Exception class thrown when a disengaged optional object is dereferenced.
Definition: optional:85
const char * what() const noexcept override
Definition: optional:90
Class template that provides copy/move constructors of optional.
Definition: optional:475
is_same
Definition: type_traits:1410
is_constructible
Definition: type_traits:954
is_nothrow_constructible
Definition: type_traits:1024
is_assignable
Definition: type_traits:1088
is_nothrow_assignable
Definition: type_traits:1143
is_convertible
Definition: type_traits:1459
A mixin helper to conditionally enable or disable the copy/move special members.
Base class for all library exceptions.
Definition: exception.h:61