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
48namespace 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
1300