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>
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
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,
489					      initializer_list<_Up>&,
490					      _Args...>, bool> = false>
491	constexpr explicit
492	_Optional_base(in_place_t,
493		       initializer_list<_Up> __il,
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>
519    struct _Optional_base<_Tp, false, true>
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>,
702			 is_constructible<_Tp, _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>,
711			 is_constructible<_Tp, _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>>,
720			 is_constructible<_Tp, const _Up&>,
721			 is_convertible<const _Up&, _Tp>,
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>>,
733			 is_constructible<_Tp, const _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>>,
746			 is_constructible<_Tp, _Up>,
747			 is_convertible<_Up, _Tp>,
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>>,
759			 is_constructible<_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,
779					  initializer_list<_Up>&,
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>
797	enable_if_t<__and_v<__not_self<_Up>,
798			    __not_<__and_<is_scalar<_Tp>,
799					  is_same<_Tp, decay_t<_Up>>>>,
800			    is_constructible<_Tp, _Up>,
801			    is_assignable<_Tp&, _Up>>,
802		    optional&>
803	operator=(_Up&& __u)
804	noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>,
805			 is_nothrow_assignable<_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>
816	enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
817			    is_constructible<_Tp, const _Up&>,
818			    is_assignable<_Tp&, const _Up&>,
819			    __not_<__converts_from_optional<_Tp, _Up>>,
820			    __not_<__assigns_from_optional<_Tp, _Up>>>,
821		    optional&>
822	operator=(const optional<_Up>& __u)
823	noexcept(__and_v<is_nothrow_constructible<_Tp, const _Up&>,
824			 is_nothrow_assignable<_Tp&, const _Up&>>)
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>
841	enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
842			    is_constructible<_Tp, _Up>,
843			    is_assignable<_Tp&, _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>,
849			 is_nothrow_assignable<_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>
877	enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _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 =
1003      enable_if_t<is_convertible<_Tp, bool>::value, bool>;
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
1333