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