1// <optional> -*- C++ -*-
2
3// Copyright (C) 2013-2018 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 201603
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
102  // Payload for optionals with non-trivial destructor.
103  template <typename _Tp,
104	    bool /*_HasTrivialDestructor*/ =
105	      is_trivially_destructible_v<_Tp>,
106	    bool /*_HasTrivialCopy */ =
107	      is_trivially_copy_assignable_v<_Tp>
108	      && is_trivially_copy_constructible_v<_Tp>,
109	    bool /*_HasTrivialMove */ =
110	      is_trivially_move_assignable_v<_Tp>
111	      && is_trivially_move_constructible_v<_Tp>>
112    struct _Optional_payload
113    {
114      constexpr _Optional_payload() noexcept : _M_empty() { }
115
116      template <typename... _Args>
117	constexpr
118	_Optional_payload(in_place_t, _Args&&... __args)
119	: _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { }
120
121      template<typename _Up, typename... _Args>
122	constexpr
123	_Optional_payload(std::initializer_list<_Up> __il,
124			  _Args&&... __args)
125	: _M_payload(__il, std::forward<_Args>(__args)...),
126	  _M_engaged(true)
127	{ }
128
129      constexpr
130      _Optional_payload(bool __engaged, const _Optional_payload& __other)
131      : _Optional_payload(__other)
132      { }
133
134      constexpr
135      _Optional_payload(bool __engaged, _Optional_payload&& __other)
136      : _Optional_payload(std::move(__other))
137      { }
138
139      constexpr
140      _Optional_payload(const _Optional_payload& __other)
141      {
142	if (__other._M_engaged)
143	  this->_M_construct(__other._M_payload);
144      }
145
146      constexpr
147      _Optional_payload(_Optional_payload&& __other)
148      {
149	if (__other._M_engaged)
150	  this->_M_construct(std::move(__other._M_payload));
151      }
152
153      constexpr
154      _Optional_payload&
155      operator=(const _Optional_payload& __other)
156      {
157        if (this->_M_engaged && __other._M_engaged)
158          this->_M_get() = __other._M_get();
159        else
160	  {
161	    if (__other._M_engaged)
162	      this->_M_construct(__other._M_get());
163	    else
164	      this->_M_reset();
165	  }
166	return *this;
167      }
168
169      constexpr
170      _Optional_payload&
171      operator=(_Optional_payload&& __other)
172      noexcept(__and_<is_nothrow_move_constructible<_Tp>,
173		      is_nothrow_move_assignable<_Tp>>())
174      {
175	if (this->_M_engaged && __other._M_engaged)
176	  this->_M_get() = std::move(__other._M_get());
177	else
178	  {
179	    if (__other._M_engaged)
180	      this->_M_construct(std::move(__other._M_get()));
181	    else
182	      this->_M_reset();
183	  }
184	return *this;
185      }
186
187      using _Stored_type = remove_const_t<_Tp>;
188
189      struct _Empty_byte { };
190
191      union {
192          _Empty_byte _M_empty;
193          _Stored_type _M_payload;
194      };
195      bool _M_engaged = false;
196
197      ~_Optional_payload()
198      {
199        if (_M_engaged)
200          _M_payload.~_Stored_type();
201      }
202
203      template<typename... _Args>
204        void
205        _M_construct(_Args&&... __args)
206        noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
207        {
208          ::new ((void *) std::__addressof(this->_M_payload))
209            _Stored_type(std::forward<_Args>(__args)...);
210          this->_M_engaged = true;
211        }
212
213      // The _M_get operations have _M_engaged as a precondition.
214      constexpr _Tp&
215      _M_get() noexcept
216      { return this->_M_payload; }
217
218      constexpr const _Tp&
219      _M_get() const noexcept
220      { return this->_M_payload; }
221
222      // _M_reset is a 'safe' operation with no precondition.
223      constexpr
224      void
225      _M_reset() noexcept
226      {
227	if (this->_M_engaged)
228	  {
229	    this->_M_engaged = false;
230	    this->_M_payload.~_Stored_type();
231	  }
232      }
233    };
234
235  // Payload for potentially-constexpr optionals.
236  template <typename _Tp>
237    struct _Optional_payload<_Tp, true, true, true>
238    {
239      constexpr _Optional_payload() noexcept
240      : _M_empty(), _M_engaged(false) { }
241
242      template<typename... _Args>
243	constexpr
244	_Optional_payload(in_place_t, _Args&&... __args)
245	: _M_payload(std::forward<_Args>(__args)...), _M_engaged(true)
246	{ }
247
248      template<typename _Up, typename... _Args>
249	constexpr
250	_Optional_payload(std::initializer_list<_Up> __il,
251			  _Args&&... __args)
252	: _M_payload(__il, std::forward<_Args>(__args)...),
253	  _M_engaged(true)
254	{ }
255
256      constexpr
257      _Optional_payload(bool __engaged, const _Optional_payload& __other)
258      : _M_engaged(__engaged)
259      {
260	if (__engaged)
261	  _M_construct(__other._M_get());
262      }
263
264      constexpr
265      _Optional_payload(bool __engaged, _Optional_payload&& __other)
266      : _M_engaged(__engaged)
267      {
268	if (__engaged)
269	  _M_construct(std::move(__other._M_get()));
270      }
271
272      using _Stored_type = remove_const_t<_Tp>;
273
274      struct _Empty_byte { };
275
276      union {
277	  _Empty_byte _M_empty;
278          _Stored_type _M_payload;
279      };
280      bool _M_engaged;
281
282      // The _M_get operations have _M_engaged as a precondition.
283      constexpr _Tp&
284      _M_get() noexcept
285      { return this->_M_payload; }
286
287      constexpr const _Tp&
288      _M_get() const noexcept
289      { return this->_M_payload; }
290    };
291
292  // Payload for optionals with non-trivial copy assignment.
293  template <typename _Tp>
294    struct _Optional_payload<_Tp, true, false, true>
295    {
296      constexpr _Optional_payload() noexcept
297      : _M_empty(), _M_engaged(false) { }
298
299      template<typename... _Args>
300	constexpr
301	_Optional_payload(in_place_t, _Args&&... __args)
302	: _M_payload(std::forward<_Args>(__args)...), _M_engaged(true)
303	{ }
304
305      template<typename _Up, typename... _Args>
306	constexpr
307	_Optional_payload(std::initializer_list<_Up> __il,
308			  _Args&&... __args)
309	: _M_payload(__il, std::forward<_Args>(__args)...),
310	  _M_engaged(true)
311	{ }
312
313      constexpr
314      _Optional_payload(bool __engaged, const _Optional_payload& __other)
315      : _M_engaged(__engaged)
316      {
317	if (__engaged)
318	  _M_construct(__other._M_get());
319      }
320
321      constexpr
322      _Optional_payload(bool __engaged, _Optional_payload&& __other)
323      : _M_engaged(__engaged)
324      {
325	if (__engaged)
326	  _M_construct(std::move(__other._M_get()));
327      }
328
329      _Optional_payload(const _Optional_payload&) = default;
330      _Optional_payload(_Optional_payload&&) = default;
331
332      constexpr
333      _Optional_payload&
334      operator=(const _Optional_payload& __other)
335      {
336        if (this->_M_engaged && __other._M_engaged)
337          this->_M_get() = __other._M_get();
338        else
339	  {
340	    if (__other._M_engaged)
341	      this->_M_construct(__other._M_get());
342	    else
343	      this->_M_reset();
344	  }
345	return *this;
346      }
347
348      _Optional_payload&
349      operator=(_Optional_payload&& __other) = default;
350
351      using _Stored_type = remove_const_t<_Tp>;
352
353      struct _Empty_byte { };
354
355      union {
356          _Empty_byte _M_empty;
357          _Stored_type _M_payload;
358      };
359      bool _M_engaged;
360
361      template<typename... _Args>
362        void
363        _M_construct(_Args&&... __args)
364        noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
365        {
366          ::new ((void *) std::__addressof(this->_M_payload))
367            _Stored_type(std::forward<_Args>(__args)...);
368          this->_M_engaged = true;
369        }
370
371      // The _M_get operations have _M_engaged as a precondition.
372      constexpr _Tp&
373      _M_get() noexcept
374      { return this->_M_payload; }
375
376      constexpr const _Tp&
377      _M_get() const noexcept
378      { return this->_M_payload; }
379
380      // _M_reset is a 'safe' operation with no precondition.
381      constexpr
382      void
383      _M_reset() noexcept
384      {
385	if (this->_M_engaged)
386	  {
387	    this->_M_engaged = false;
388	    this->_M_payload.~_Stored_type();
389	  }
390      }
391    };
392
393  // Payload for optionals with non-trivial move assignment.
394  template <typename _Tp>
395    struct _Optional_payload<_Tp, true, true, false>
396    {
397      constexpr _Optional_payload() noexcept
398      : _M_empty(), _M_engaged(false) { }
399
400      template<typename... _Args>
401	constexpr
402	_Optional_payload(in_place_t, _Args&&... __args)
403	: _M_payload(std::forward<_Args>(__args)...),
404	  _M_engaged(true)
405	{ }
406
407      template<typename _Up, typename... _Args>
408	constexpr
409	_Optional_payload(std::initializer_list<_Up> __il,
410			  _Args&&... __args)
411	: _M_payload(__il, std::forward<_Args>(__args)...),
412	  _M_engaged(true)
413	{ }
414
415      constexpr
416      _Optional_payload(bool __engaged, const _Optional_payload& __other)
417      : _M_engaged(__engaged)
418      {
419	if (__engaged)
420	  _M_construct(__other._M_get());
421      }
422
423      constexpr
424      _Optional_payload(bool __engaged, _Optional_payload&& __other)
425      : _M_engaged(__engaged)
426      {
427	if (__engaged)
428	  _M_construct(std::move(__other._M_get()));
429      }
430
431      _Optional_payload(const _Optional_payload&) = default;
432      _Optional_payload(_Optional_payload&&) = default;
433
434      _Optional_payload&
435      operator=(const _Optional_payload& __other) = default;
436
437      constexpr
438      _Optional_payload&
439      operator=(_Optional_payload&& __other)
440      noexcept(__and_<is_nothrow_move_constructible<_Tp>,
441		      is_nothrow_move_assignable<_Tp>>())
442      {
443	if (this->_M_engaged && __other._M_engaged)
444	  this->_M_get() = std::move(__other._M_get());
445	else
446	  {
447	    if (__other._M_engaged)
448	      this->_M_construct(std::move(__other._M_get()));
449	    else
450	      this->_M_reset();
451	  }
452	return *this;
453      }
454
455      using _Stored_type = remove_const_t<_Tp>;
456
457      struct _Empty_byte { };
458
459      union {
460          _Empty_byte _M_empty;
461          _Stored_type _M_payload;
462      };
463      bool _M_engaged;
464
465      template<typename... _Args>
466        void
467        _M_construct(_Args&&... __args)
468        noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
469        {
470          ::new ((void *) std::__addressof(this->_M_payload))
471            _Stored_type(std::forward<_Args>(__args)...);
472          this->_M_engaged = true;
473        }
474
475      // The _M_get operations have _M_engaged as a precondition.
476      constexpr _Tp&
477      _M_get() noexcept
478      { return this->_M_payload; }
479
480      constexpr const _Tp&
481      _M_get() const noexcept
482      { return this->_M_payload; }
483
484      // _M_reset is a 'safe' operation with no precondition.
485      constexpr
486      void
487      _M_reset() noexcept
488      {
489	if (this->_M_engaged)
490	  {
491	    this->_M_engaged = false;
492	    this->_M_payload.~_Stored_type();
493	  }
494      }
495    };
496
497  // Payload for optionals with non-trivial copy and move assignment.
498  template <typename _Tp>
499    struct _Optional_payload<_Tp, true, false, false>
500    {
501      constexpr _Optional_payload() noexcept
502      : _M_empty(), _M_engaged(false) {}
503
504      template<typename... _Args>
505	constexpr
506	_Optional_payload(in_place_t, _Args&&... __args)
507	: _M_payload(std::forward<_Args>(__args)...),
508	  _M_engaged(true)
509	{ }
510
511      template<typename _Up, typename... _Args>
512	constexpr
513	_Optional_payload(std::initializer_list<_Up> __il,
514			  _Args&&... __args)
515	: _M_payload(__il, std::forward<_Args>(__args)...),
516	  _M_engaged(true)
517	{ }
518
519      constexpr
520      _Optional_payload(bool __engaged, const _Optional_payload& __other)
521      : _M_engaged(__engaged)
522      {
523	if (__engaged)
524	  _M_construct(__other._M_get());
525      }
526
527      constexpr
528      _Optional_payload(bool __engaged, _Optional_payload&& __other)
529      : _M_engaged(__engaged)
530      {
531	if (__engaged)
532	  _M_construct(std::move(__other._M_get()));
533      }
534
535      _Optional_payload(const _Optional_payload&) = default;
536      _Optional_payload(_Optional_payload&&) = default;
537
538      constexpr
539      _Optional_payload&
540      operator=(const _Optional_payload& __other)
541      {
542        if (this->_M_engaged && __other._M_engaged)
543          this->_M_get() = __other._M_get();
544        else
545	  {
546	    if (__other._M_engaged)
547	      this->_M_construct(__other._M_get());
548	    else
549	      this->_M_reset();
550	  }
551	return *this;
552      }
553
554      constexpr
555      _Optional_payload&
556      operator=(_Optional_payload&& __other)
557      noexcept(__and_<is_nothrow_move_constructible<_Tp>,
558		      is_nothrow_move_assignable<_Tp>>())
559      {
560	if (this->_M_engaged && __other._M_engaged)
561	  this->_M_get() = std::move(__other._M_get());
562	else
563	  {
564	    if (__other._M_engaged)
565	      this->_M_construct(std::move(__other._M_get()));
566	    else
567	      this->_M_reset();
568	  }
569	return *this;
570      }
571
572      using _Stored_type = remove_const_t<_Tp>;
573
574      struct _Empty_byte { };
575
576      union {
577          _Empty_byte _M_empty;
578          _Stored_type _M_payload;
579      };
580      bool _M_engaged;
581
582      template<typename... _Args>
583        void
584        _M_construct(_Args&&... __args)
585        noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
586        {
587          ::new ((void *) std::__addressof(this->_M_payload))
588            _Stored_type(std::forward<_Args>(__args)...);
589          this->_M_engaged = true;
590        }
591
592      // The _M_get operations have _M_engaged as a precondition.
593      constexpr _Tp&
594      _M_get() noexcept
595      { return this->_M_payload; }
596
597      constexpr const _Tp&
598      _M_get() const noexcept
599      { return this->_M_payload; }
600
601      // _M_reset is a 'safe' operation with no precondition.
602      constexpr
603      void
604      _M_reset() noexcept
605      {
606	if (this->_M_engaged)
607	  {
608	    this->_M_engaged = false;
609	    this->_M_payload.~_Stored_type();
610	  }
611      }
612    };
613
614  template<typename _Tp, typename _Dp>
615    class _Optional_base_impl
616    {
617    protected:
618      using _Stored_type = remove_const_t<_Tp>;
619
620      // The _M_construct operation has !_M_engaged as a precondition
621      // while _M_destruct has _M_engaged as a precondition.
622      template<typename... _Args>
623	void
624	_M_construct(_Args&&... __args)
625	noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
626	{
627	  ::new
628	    (std::__addressof(static_cast<_Dp*>(this)->_M_payload._M_payload))
629	    _Stored_type(std::forward<_Args>(__args)...);
630	  static_cast<_Dp*>(this)->_M_payload._M_engaged = true;
631	}
632
633      void
634      _M_destruct() noexcept
635      {
636	static_cast<_Dp*>(this)->_M_payload._M_engaged = false;
637	static_cast<_Dp*>(this)->_M_payload._M_payload.~_Stored_type();
638      }
639
640      // _M_reset is a 'safe' operation with no precondition.
641      constexpr
642      void
643      _M_reset() noexcept
644      {
645	if (static_cast<_Dp*>(this)->_M_payload._M_engaged)
646	  static_cast<_Dp*>(this)->_M_destruct();
647      }
648  };
649
650  /**
651    * @brief Class template that takes care of copy/move constructors
652    of optional
653    *
654    * Such a separate base class template is necessary in order to
655    * conditionally make copy/move constructors trivial.
656    * @see optional, _Enable_special_members
657    */
658  template<typename _Tp,
659	   bool = is_trivially_copy_constructible_v<_Tp>,
660	   bool = is_trivially_move_constructible_v<_Tp>>
661    class _Optional_base
662    // protected inheritance because optional needs to reach that base too
663      : protected _Optional_base_impl<_Tp, _Optional_base<_Tp>>
664    {
665      friend class _Optional_base_impl<_Tp, _Optional_base<_Tp>>;
666
667    public:
668      // Constructors for disengaged optionals.
669      constexpr _Optional_base() = default;
670
671      // Constructors for engaged optionals.
672      template<typename... _Args,
673	       enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
674        constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
675        : _M_payload(in_place,
676		     std::forward<_Args>(__args)...) { }
677
678      template<typename _Up, typename... _Args,
679               enable_if_t<is_constructible_v<_Tp,
680					      initializer_list<_Up>&,
681					      _Args&&...>, bool> = false>
682        constexpr explicit _Optional_base(in_place_t,
683                                          initializer_list<_Up> __il,
684                                          _Args&&... __args)
685        : _M_payload(in_place,
686		     __il, std::forward<_Args>(__args)...)
687        { }
688
689      // Copy and move constructors.
690      constexpr _Optional_base(const _Optional_base& __other)
691	: _M_payload(__other._M_payload._M_engaged,
692		     __other._M_payload)
693      { }
694
695      constexpr _Optional_base(_Optional_base&& __other)
696      noexcept(is_nothrow_move_constructible<_Tp>())
697	: _M_payload(__other._M_payload._M_engaged,
698		     std::move(__other._M_payload))
699      { }
700
701      // Assignment operators.
702      _Optional_base& operator=(const _Optional_base&) = default;
703      _Optional_base& operator=(_Optional_base&&) = default;
704
705    protected:
706
707      constexpr bool _M_is_engaged() const noexcept
708      { return this->_M_payload._M_engaged; }
709
710      // The _M_get operations have _M_engaged as a precondition.
711      constexpr _Tp&
712	_M_get() noexcept
713      {
714	__glibcxx_assert(this->_M_is_engaged());
715	return this->_M_payload._M_payload;
716      }
717
718      constexpr const _Tp&
719	_M_get() const noexcept
720      {
721	__glibcxx_assert(this->_M_is_engaged());
722	return this->_M_payload._M_payload;
723      }
724
725    private:
726      _Optional_payload<_Tp> _M_payload;
727    };
728
729  template<typename _Tp>
730    class _Optional_base<_Tp, false, true>
731      : protected _Optional_base_impl<_Tp, _Optional_base<_Tp>>
732    {
733      friend class _Optional_base_impl<_Tp, _Optional_base<_Tp>>;
734    public:
735
736      // Constructors for disengaged optionals.
737      constexpr _Optional_base() = default;
738
739      // Constructors for engaged optionals.
740      template<typename... _Args,
741	       enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
742        constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
743        : _M_payload(in_place,
744		     std::forward<_Args>(__args)...) { }
745
746      template<typename _Up, typename... _Args,
747               enable_if_t<is_constructible_v<_Tp,
748					      initializer_list<_Up>&,
749					      _Args&&...>, bool> = false>
750        constexpr explicit _Optional_base(in_place_t,
751                                          initializer_list<_Up> __il,
752                                          _Args&&... __args)
753        : _M_payload(in_place,
754		     __il, std::forward<_Args>(__args)...)
755        { }
756
757      // Copy and move constructors.
758      constexpr _Optional_base(const _Optional_base& __other)
759	: _M_payload(__other._M_payload._M_engaged,
760		     __other._M_payload)
761      { }
762
763      constexpr _Optional_base(_Optional_base&& __other) = default;
764
765      // Assignment operators.
766      _Optional_base& operator=(const _Optional_base&) = default;
767      _Optional_base& operator=(_Optional_base&&) = default;
768
769    protected:
770
771      constexpr bool _M_is_engaged() const noexcept
772      { return this->_M_payload._M_engaged; }
773
774      // The _M_get operations have _M_engaged as a precondition.
775      constexpr _Tp&
776	_M_get() noexcept
777      {
778	__glibcxx_assert(this->_M_is_engaged());
779	return this->_M_payload._M_payload;
780      }
781
782      constexpr const _Tp&
783	_M_get() const noexcept
784      {
785	__glibcxx_assert(this->_M_is_engaged());
786	return this->_M_payload._M_payload;
787      }
788
789    private:
790      _Optional_payload<_Tp> _M_payload;
791    };
792
793  template<typename _Tp>
794    class _Optional_base<_Tp, true, false>
795      : protected _Optional_base_impl<_Tp, _Optional_base<_Tp>>
796    {
797      friend class _Optional_base_impl<_Tp, _Optional_base<_Tp>>;
798    public:
799
800      // Constructors for disengaged optionals.
801      constexpr _Optional_base() = default;
802
803      // Constructors for engaged optionals.
804      template<typename... _Args,
805	       enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
806        constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
807        : _M_payload(in_place,
808		     std::forward<_Args>(__args)...) { }
809
810      template<typename _Up, typename... _Args,
811               enable_if_t<is_constructible_v<_Tp,
812					      initializer_list<_Up>&,
813					      _Args&&...>, bool> = false>
814        constexpr explicit _Optional_base(in_place_t,
815                                          initializer_list<_Up> __il,
816                                          _Args&&... __args)
817        : _M_payload(in_place,
818		     __il, std::forward<_Args>(__args)...)
819        { }
820
821      // Copy and move constructors.
822      constexpr _Optional_base(const _Optional_base& __other) = default;
823
824      constexpr _Optional_base(_Optional_base&& __other)
825      noexcept(is_nothrow_move_constructible<_Tp>())
826	: _M_payload(__other._M_payload._M_engaged,
827		     std::move(__other._M_payload))
828      { }
829
830      // Assignment operators.
831      _Optional_base& operator=(const _Optional_base&) = default;
832      _Optional_base& operator=(_Optional_base&&) = default;
833
834    protected:
835
836      constexpr bool _M_is_engaged() const noexcept
837      { return this->_M_payload._M_engaged; }
838
839      // The _M_get operations have _M_engaged as a precondition.
840      constexpr _Tp&
841	_M_get() noexcept
842      {
843	__glibcxx_assert(this->_M_is_engaged());
844	return this->_M_payload._M_payload;
845      }
846
847      constexpr const _Tp&
848	_M_get() const noexcept
849      {
850	__glibcxx_assert(this->_M_is_engaged());
851	return this->_M_payload._M_payload;
852      }
853
854    private:
855      _Optional_payload<_Tp> _M_payload;
856    };
857
858  template<typename _Tp>
859    class _Optional_base<_Tp, true, true>
860      : protected _Optional_base_impl<_Tp, _Optional_base<_Tp>>
861    {
862      friend class _Optional_base_impl<_Tp, _Optional_base<_Tp>>;
863    public:
864
865      // Constructors for disengaged optionals.
866      constexpr _Optional_base() = default;
867
868      // Constructors for engaged optionals.
869      template<typename... _Args,
870	       enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
871        constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
872        : _M_payload(in_place,
873		     std::forward<_Args>(__args)...) { }
874
875      template<typename _Up, typename... _Args,
876               enable_if_t<is_constructible_v<_Tp,
877					      initializer_list<_Up>&,
878					      _Args&&...>, bool> = false>
879        constexpr explicit _Optional_base(in_place_t,
880                                          initializer_list<_Up> __il,
881                                          _Args&&... __args)
882        : _M_payload(in_place,
883		     __il, std::forward<_Args>(__args)...)
884        { }
885
886      // Copy and move constructors.
887      constexpr _Optional_base(const _Optional_base& __other) = default;
888      constexpr _Optional_base(_Optional_base&& __other) = default;
889
890      // Assignment operators.
891      _Optional_base& operator=(const _Optional_base&) = default;
892      _Optional_base& operator=(_Optional_base&&) = default;
893
894    protected:
895
896      constexpr bool _M_is_engaged() const noexcept
897      { return this->_M_payload._M_engaged; }
898
899      // The _M_get operations have _M_engaged as a precondition.
900      constexpr _Tp&
901	_M_get() noexcept
902      {
903	__glibcxx_assert(this->_M_is_engaged());
904	return this->_M_payload._M_payload;
905      }
906
907      constexpr const _Tp&
908	_M_get() const noexcept
909      {
910	__glibcxx_assert(this->_M_is_engaged());
911	return this->_M_payload._M_payload;
912      }
913
914    private:
915      _Optional_payload<_Tp> _M_payload;
916    };
917
918  template<typename _Tp>
919  class optional;
920
921  template<typename _Tp, typename _Up>
922    using __converts_from_optional =
923      __or_<is_constructible<_Tp, const optional<_Up>&>,
924	    is_constructible<_Tp, optional<_Up>&>,
925	    is_constructible<_Tp, const optional<_Up>&&>,
926	    is_constructible<_Tp, optional<_Up>&&>,
927	    is_convertible<const optional<_Up>&, _Tp>,
928	    is_convertible<optional<_Up>&, _Tp>,
929	    is_convertible<const optional<_Up>&&, _Tp>,
930	    is_convertible<optional<_Up>&&, _Tp>>;
931
932  template<typename _Tp, typename _Up>
933    using __assigns_from_optional =
934      __or_<is_assignable<_Tp&, const optional<_Up>&>,
935	    is_assignable<_Tp&, optional<_Up>&>,
936	    is_assignable<_Tp&, const optional<_Up>&&>,
937	    is_assignable<_Tp&, optional<_Up>&&>>;
938
939  /**
940    * @brief Class template for optional values.
941    */
942  template<typename _Tp>
943    class optional
944    : private _Optional_base<_Tp>,
945      private _Enable_copy_move<
946        // Copy constructor.
947        is_copy_constructible<_Tp>::value,
948        // Copy assignment.
949        __and_<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>::value,
950        // Move constructor.
951        is_move_constructible<_Tp>::value,
952        // Move assignment.
953        __and_<is_move_constructible<_Tp>, is_move_assignable<_Tp>>::value,
954        // Unique tag type.
955        optional<_Tp>>
956    {
957      static_assert(!is_same_v<remove_cv_t<_Tp>, nullopt_t>);
958      static_assert(!is_same_v<remove_cv_t<_Tp>, in_place_t>);
959      static_assert(!is_reference_v<_Tp>);
960
961    private:
962      using _Base = _Optional_base<_Tp>;
963
964    public:
965      using value_type = _Tp;
966
967      constexpr optional() = default;
968
969      constexpr optional(nullopt_t) noexcept { }
970
971      // Converting constructors for engaged optionals.
972      template <typename _Up = _Tp,
973                enable_if_t<__and_<
974			      __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
975			      __not_<is_same<in_place_t, decay_t<_Up>>>,
976			      is_constructible<_Tp, _Up&&>,
977			      is_convertible<_Up&&, _Tp>
978			      >::value, bool> = true>
979      constexpr optional(_Up&& __t)
980        : _Base(std::in_place, std::forward<_Up>(__t)) { }
981
982      template <typename _Up = _Tp,
983                enable_if_t<__and_<
984			      __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
985			      __not_<is_same<in_place_t, decay_t<_Up>>>,
986			      is_constructible<_Tp, _Up&&>,
987			      __not_<is_convertible<_Up&&, _Tp>>
988			      >::value, bool> = false>
989      explicit constexpr optional(_Up&& __t)
990        : _Base(std::in_place, std::forward<_Up>(__t)) { }
991
992      template <typename _Up,
993                enable_if_t<__and_<
994			    __not_<is_same<_Tp, _Up>>,
995			    is_constructible<_Tp, const _Up&>,
996			    is_convertible<const _Up&, _Tp>,
997			    __not_<__converts_from_optional<_Tp, _Up>>
998			    >::value, bool> = true>
999      constexpr optional(const optional<_Up>& __t)
1000      {
1001	if (__t)
1002	  emplace(*__t);
1003      }
1004
1005      template <typename _Up,
1006                 enable_if_t<__and_<
1007			       __not_<is_same<_Tp, _Up>>,
1008			       is_constructible<_Tp, const _Up&>,
1009			       __not_<is_convertible<const _Up&, _Tp>>,
1010			       __not_<__converts_from_optional<_Tp, _Up>>
1011			       >::value, bool> = false>
1012      explicit constexpr optional(const optional<_Up>& __t)
1013      {
1014	if (__t)
1015	  emplace(*__t);
1016      }
1017
1018      template <typename _Up,
1019                enable_if_t<__and_<
1020			      __not_<is_same<_Tp, _Up>>,
1021			      is_constructible<_Tp, _Up&&>,
1022			      is_convertible<_Up&&, _Tp>,
1023			      __not_<__converts_from_optional<_Tp, _Up>>
1024			      >::value, bool> = true>
1025      constexpr optional(optional<_Up>&& __t)
1026      {
1027	if (__t)
1028	  emplace(std::move(*__t));
1029      }
1030
1031      template <typename _Up,
1032                enable_if_t<__and_<
1033			    __not_<is_same<_Tp, _Up>>,
1034			    is_constructible<_Tp, _Up&&>,
1035			    __not_<is_convertible<_Up&&, _Tp>>,
1036			    __not_<__converts_from_optional<_Tp, _Up>>
1037			    >::value, bool> = false>
1038      explicit constexpr optional(optional<_Up>&& __t)
1039      {
1040	if (__t)
1041	  emplace(std::move(*__t));
1042      }
1043
1044      template<typename... _Args,
1045	       enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
1046      explicit constexpr optional(in_place_t, _Args&&... __args)
1047        : _Base(std::in_place, std::forward<_Args>(__args)...) { }
1048
1049      template<typename _Up, typename... _Args,
1050               enable_if_t<is_constructible_v<_Tp,
1051					      initializer_list<_Up>&,
1052					      _Args&&...>, bool> = false>
1053      explicit constexpr optional(in_place_t,
1054				  initializer_list<_Up> __il,
1055				  _Args&&... __args)
1056        : _Base(std::in_place, __il, std::forward<_Args>(__args)...) { }
1057
1058      // Assignment operators.
1059      optional&
1060      operator=(nullopt_t) noexcept
1061      {
1062        this->_M_reset();
1063        return *this;
1064      }
1065
1066      template<typename _Up = _Tp>
1067        enable_if_t<__and_<
1068		      __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
1069		      is_constructible<_Tp, _Up>,
1070		      __not_<__and_<is_scalar<_Tp>,
1071				    is_same<_Tp, decay_t<_Up>>>>,
1072		      is_assignable<_Tp&, _Up>>::value,
1073		    optional&>
1074        operator=(_Up&& __u)
1075        {
1076          if (this->_M_is_engaged())
1077            this->_M_get() = std::forward<_Up>(__u);
1078          else
1079            this->_M_construct(std::forward<_Up>(__u));
1080
1081          return *this;
1082        }
1083
1084      template<typename _Up>
1085	enable_if_t<__and_<
1086		      __not_<is_same<_Tp, _Up>>,
1087		      is_constructible<_Tp, const _Up&>,
1088		      is_assignable<_Tp&, _Up>,
1089		      __not_<__converts_from_optional<_Tp, _Up>>,
1090		      __not_<__assigns_from_optional<_Tp, _Up>>
1091		      >::value,
1092		    optional&>
1093        operator=(const optional<_Up>& __u)
1094        {
1095          if (__u)
1096            {
1097              if (this->_M_is_engaged())
1098                this->_M_get() = *__u;
1099              else
1100                this->_M_construct(*__u);
1101            }
1102          else
1103            {
1104              this->_M_reset();
1105            }
1106          return *this;
1107        }
1108
1109      template<typename _Up>
1110	enable_if_t<__and_<
1111		      __not_<is_same<_Tp, _Up>>,
1112		      is_constructible<_Tp, _Up>,
1113		      is_assignable<_Tp&, _Up>,
1114		      __not_<__converts_from_optional<_Tp, _Up>>,
1115		      __not_<__assigns_from_optional<_Tp, _Up>>
1116		      >::value,
1117		    optional&>
1118        operator=(optional<_Up>&& __u)
1119        {
1120          if (__u)
1121            {
1122              if (this->_M_is_engaged())
1123                this->_M_get() = std::move(*__u);
1124              else
1125                this->_M_construct(std::move(*__u));
1126            }
1127          else
1128            {
1129              this->_M_reset();
1130            }
1131
1132          return *this;
1133        }
1134
1135      template<typename... _Args>
1136	enable_if_t<is_constructible<_Tp, _Args&&...>::value, _Tp&>
1137	emplace(_Args&&... __args)
1138	{
1139	  this->_M_reset();
1140	  this->_M_construct(std::forward<_Args>(__args)...);
1141	  return this->_M_get();
1142	}
1143
1144      template<typename _Up, typename... _Args>
1145	enable_if_t<is_constructible<_Tp, initializer_list<_Up>&,
1146				     _Args&&...>::value, _Tp&>
1147	emplace(initializer_list<_Up> __il, _Args&&... __args)
1148	{
1149	  this->_M_reset();
1150	  this->_M_construct(__il, std::forward<_Args>(__args)...);
1151	  return this->_M_get();
1152	}
1153
1154      // Destructor is implicit, implemented in _Optional_base.
1155
1156      // Swap.
1157      void
1158      swap(optional& __other)
1159      noexcept(is_nothrow_move_constructible<_Tp>()
1160               && is_nothrow_swappable_v<_Tp>)
1161      {
1162        using std::swap;
1163
1164        if (this->_M_is_engaged() && __other._M_is_engaged())
1165          swap(this->_M_get(), __other._M_get());
1166        else if (this->_M_is_engaged())
1167	  {
1168	    __other._M_construct(std::move(this->_M_get()));
1169	    this->_M_destruct();
1170	  }
1171        else if (__other._M_is_engaged())
1172	  {
1173	    this->_M_construct(std::move(__other._M_get()));
1174	    __other._M_destruct();
1175	  }
1176      }
1177
1178      // Observers.
1179      constexpr const _Tp*
1180      operator->() const
1181      { return std::__addressof(this->_M_get()); }
1182
1183      constexpr
1184      _Tp*
1185      operator->()
1186      { return std::__addressof(this->_M_get()); }
1187
1188      constexpr const _Tp&
1189      operator*() const&
1190      { return this->_M_get(); }
1191
1192      constexpr _Tp&
1193      operator*()&
1194      { return this->_M_get(); }
1195
1196      constexpr _Tp&&
1197      operator*()&&
1198      { return std::move(this->_M_get()); }
1199
1200      constexpr const _Tp&&
1201      operator*() const&&
1202      { return std::move(this->_M_get()); }
1203
1204      constexpr explicit operator bool() const noexcept
1205      { return this->_M_is_engaged(); }
1206
1207      constexpr bool has_value() const noexcept
1208      { return this->_M_is_engaged(); }
1209
1210      constexpr const _Tp&
1211      value() const&
1212      {
1213	return this->_M_is_engaged()
1214	  ?  this->_M_get()
1215	  : (__throw_bad_optional_access(),
1216	     this->_M_get());
1217      }
1218
1219      constexpr _Tp&
1220      value()&
1221      {
1222	return this->_M_is_engaged()
1223	  ?  this->_M_get()
1224	  : (__throw_bad_optional_access(),
1225	     this->_M_get());
1226      }
1227
1228      constexpr _Tp&&
1229      value()&&
1230      {
1231	return this->_M_is_engaged()
1232	  ?  std::move(this->_M_get())
1233	  : (__throw_bad_optional_access(),
1234	     std::move(this->_M_get()));
1235      }
1236
1237      constexpr const _Tp&&
1238      value() const&&
1239      {
1240	return this->_M_is_engaged()
1241	  ?  std::move(this->_M_get())
1242	  : (__throw_bad_optional_access(),
1243	     std::move(this->_M_get()));
1244      }
1245
1246      template<typename _Up>
1247	constexpr _Tp
1248	value_or(_Up&& __u) const&
1249	{
1250	  static_assert(is_copy_constructible_v<_Tp>);
1251	  static_assert(is_convertible_v<_Up&&, _Tp>);
1252
1253	  return this->_M_is_engaged()
1254	    ? this->_M_get()
1255	    : static_cast<_Tp>(std::forward<_Up>(__u));
1256	}
1257
1258      template<typename _Up>
1259	_Tp
1260	value_or(_Up&& __u) &&
1261	{
1262	  static_assert(is_move_constructible_v<_Tp>);
1263	  static_assert(is_convertible_v<_Up&&, _Tp>);
1264
1265	  return this->_M_is_engaged()
1266	    ? std::move(this->_M_get())
1267	    : static_cast<_Tp>(std::forward<_Up>(__u));
1268	}
1269      void reset() noexcept { this->_M_reset(); }
1270    };
1271
1272  template<typename _Tp>
1273    using __optional_relop_t =
1274    enable_if_t<is_convertible<_Tp, bool>::value, bool>;
1275
1276  // Comparisons between optional values.
1277  template<typename _Tp, typename _Up>
1278    constexpr auto
1279    operator==(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1280    -> __optional_relop_t<decltype(declval<_Tp>() == declval<_Up>())>
1281    {
1282      return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
1283	     && (!__lhs || *__lhs == *__rhs);
1284    }
1285
1286  template<typename _Tp, typename _Up>
1287    constexpr auto
1288    operator!=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1289    -> __optional_relop_t<decltype(declval<_Tp>() != declval<_Up>())>
1290    {
1291      return static_cast<bool>(__lhs) != static_cast<bool>(__rhs)
1292	|| (static_cast<bool>(__lhs) && *__lhs != *__rhs);
1293    }
1294
1295  template<typename _Tp, typename _Up>
1296    constexpr auto
1297    operator<(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1298    -> __optional_relop_t<decltype(declval<_Tp>() < declval<_Up>())>
1299    {
1300      return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
1301    }
1302
1303  template<typename _Tp, typename _Up>
1304    constexpr auto
1305    operator>(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1306    -> __optional_relop_t<decltype(declval<_Tp>() > declval<_Up>())>
1307    {
1308      return static_cast<bool>(__lhs) && (!__rhs || *__lhs > *__rhs);
1309    }
1310
1311  template<typename _Tp, typename _Up>
1312    constexpr auto
1313    operator<=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1314    -> __optional_relop_t<decltype(declval<_Tp>() <= declval<_Up>())>
1315    {
1316      return !__lhs || (static_cast<bool>(__rhs) && *__lhs <= *__rhs);
1317    }
1318
1319  template<typename _Tp, typename _Up>
1320    constexpr auto
1321    operator>=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1322    -> __optional_relop_t<decltype(declval<_Tp>() >= declval<_Up>())>
1323    {
1324      return !__rhs || (static_cast<bool>(__lhs) && *__lhs >= *__rhs);
1325    }
1326
1327  // Comparisons with nullopt.
1328  template<typename _Tp>
1329    constexpr bool
1330    operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept
1331    { return !__lhs; }
1332
1333  template<typename _Tp>
1334    constexpr bool
1335    operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept
1336    { return !__rhs; }
1337
1338  template<typename _Tp>
1339    constexpr bool
1340    operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept
1341    { return static_cast<bool>(__lhs); }
1342
1343  template<typename _Tp>
1344    constexpr bool
1345    operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept
1346    { return static_cast<bool>(__rhs); }
1347
1348  template<typename _Tp>
1349    constexpr bool
1350    operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
1351    { return false; }
1352
1353  template<typename _Tp>
1354    constexpr bool
1355    operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
1356    { return static_cast<bool>(__rhs); }
1357
1358  template<typename _Tp>
1359    constexpr bool
1360    operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept
1361    { return static_cast<bool>(__lhs); }
1362
1363  template<typename _Tp>
1364    constexpr bool
1365    operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
1366    { return false; }
1367
1368  template<typename _Tp>
1369    constexpr bool
1370    operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept
1371    { return !__lhs; }
1372
1373  template<typename _Tp>
1374    constexpr bool
1375    operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
1376    { return true; }
1377
1378  template<typename _Tp>
1379    constexpr bool
1380    operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
1381    { return true; }
1382
1383  template<typename _Tp>
1384    constexpr bool
1385    operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept
1386    { return !__rhs; }
1387
1388  // Comparisons with value type.
1389  template<typename _Tp, typename _Up>
1390    constexpr auto
1391    operator==(const optional<_Tp>& __lhs, const _Up& __rhs)
1392    -> __optional_relop_t<decltype(declval<_Tp>() == declval<_Up>())>
1393    { return __lhs && *__lhs == __rhs; }
1394
1395  template<typename _Tp, typename _Up>
1396    constexpr auto
1397    operator==(const _Up& __lhs, const optional<_Tp>& __rhs)
1398    -> __optional_relop_t<decltype(declval<_Up>() == declval<_Tp>())>
1399    { return __rhs && __lhs == *__rhs; }
1400
1401  template<typename _Tp, typename _Up>
1402    constexpr auto
1403    operator!=(const optional<_Tp>& __lhs, const _Up& __rhs)
1404    -> __optional_relop_t<decltype(declval<_Tp>() != declval<_Up>())>
1405    { return !__lhs || *__lhs != __rhs; }
1406
1407  template<typename _Tp, typename _Up>
1408    constexpr auto
1409    operator!=(const _Up& __lhs, const optional<_Tp>& __rhs)
1410    -> __optional_relop_t<decltype(declval<_Up>() != declval<_Tp>())>
1411    { return !__rhs || __lhs != *__rhs; }
1412
1413  template<typename _Tp, typename _Up>
1414    constexpr auto
1415    operator<(const optional<_Tp>& __lhs, const _Up& __rhs)
1416    -> __optional_relop_t<decltype(declval<_Tp>() < declval<_Up>())>
1417    { return !__lhs || *__lhs < __rhs; }
1418
1419  template<typename _Tp, typename _Up>
1420    constexpr auto
1421    operator<(const _Up& __lhs, const optional<_Tp>& __rhs)
1422    -> __optional_relop_t<decltype(declval<_Up>() < declval<_Tp>())>
1423    { return __rhs && __lhs < *__rhs; }
1424
1425  template<typename _Tp, typename _Up>
1426    constexpr auto
1427    operator>(const optional<_Tp>& __lhs, const _Up& __rhs)
1428    -> __optional_relop_t<decltype(declval<_Tp>() > declval<_Up>())>
1429    { return __lhs && *__lhs > __rhs; }
1430
1431  template<typename _Tp, typename _Up>
1432    constexpr auto
1433    operator>(const _Up& __lhs, const optional<_Tp>& __rhs)
1434    -> __optional_relop_t<decltype(declval<_Up>() > declval<_Tp>())>
1435    { return !__rhs || __lhs > *__rhs; }
1436
1437  template<typename _Tp, typename _Up>
1438    constexpr auto
1439    operator<=(const optional<_Tp>& __lhs, const _Up& __rhs)
1440    -> __optional_relop_t<decltype(declval<_Tp>() <= declval<_Up>())>
1441    { return !__lhs || *__lhs <= __rhs; }
1442
1443  template<typename _Tp, typename _Up>
1444    constexpr auto
1445    operator<=(const _Up& __lhs, const optional<_Tp>& __rhs)
1446    -> __optional_relop_t<decltype(declval<_Up>() <= declval<_Tp>())>
1447    { return __rhs && __lhs <= *__rhs; }
1448
1449  template<typename _Tp, typename _Up>
1450    constexpr auto
1451    operator>=(const optional<_Tp>& __lhs, const _Up& __rhs)
1452    -> __optional_relop_t<decltype(declval<_Tp>() >= declval<_Up>())>
1453    { return __lhs && *__lhs >= __rhs; }
1454
1455  template<typename _Tp, typename _Up>
1456    constexpr auto
1457    operator>=(const _Up& __lhs, const optional<_Tp>& __rhs)
1458    -> __optional_relop_t<decltype(declval<_Up>() >= declval<_Tp>())>
1459    { return !__rhs || __lhs >= *__rhs; }
1460
1461  // Swap and creation functions.
1462
1463  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1464  // 2748. swappable traits for optionals
1465  template<typename _Tp>
1466    inline enable_if_t<is_move_constructible_v<_Tp> && is_swappable_v<_Tp>>
1467    swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
1468    noexcept(noexcept(__lhs.swap(__rhs)))
1469    { __lhs.swap(__rhs); }
1470
1471  template<typename _Tp>
1472    enable_if_t<!(is_move_constructible_v<_Tp> && is_swappable_v<_Tp>)>
1473    swap(optional<_Tp>&, optional<_Tp>&) = delete;
1474
1475  template<typename _Tp>
1476    constexpr optional<decay_t<_Tp>>
1477    make_optional(_Tp&& __t)
1478    { return optional<decay_t<_Tp>> { std::forward<_Tp>(__t) }; }
1479
1480  template<typename _Tp, typename ..._Args>
1481    constexpr optional<_Tp>
1482    make_optional(_Args&&... __args)
1483    { return optional<_Tp> { in_place, std::forward<_Args>(__args)... }; }
1484
1485  template<typename _Tp, typename _Up, typename ..._Args>
1486    constexpr optional<_Tp>
1487    make_optional(initializer_list<_Up> __il, _Args&&... __args)
1488    { return optional<_Tp> { in_place, __il, std::forward<_Args>(__args)... }; }
1489
1490  // Hash.
1491
1492  template<typename _Tp, typename _Up = remove_const_t<_Tp>,
1493           bool = __poison_hash<_Up>::__enable_hash_call>
1494    struct __optional_hash_call_base
1495    {
1496      size_t
1497      operator()(const optional<_Tp>& __t) const
1498      noexcept(noexcept(hash<_Up>{}(*__t)))
1499      {
1500        // We pick an arbitrary hash for disengaged optionals which hopefully
1501        // usual values of _Tp won't typically hash to.
1502        constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333);
1503        return __t ? hash<_Up>{}(*__t) : __magic_disengaged_hash;
1504      }
1505    };
1506
1507  template<typename _Tp, typename _Up>
1508    struct __optional_hash_call_base<_Tp, _Up, false> {};
1509
1510  template<typename _Tp>
1511    struct hash<optional<_Tp>>
1512    : private __poison_hash<remove_const_t<_Tp>>,
1513      public __optional_hash_call_base<_Tp>
1514    {
1515      using result_type [[__deprecated__]] = size_t;
1516      using argument_type [[__deprecated__]] = optional<_Tp>;
1517    };
1518
1519  template<typename _Tp>
1520    struct __is_fast_hash<hash<optional<_Tp>>> : __is_fast_hash<hash<_Tp>>
1521    { };
1522
1523  /// @}
1524
1525#if __cpp_deduction_guides >= 201606
1526  template <typename _Tp> optional(_Tp) -> optional<_Tp>;
1527#endif
1528
1529_GLIBCXX_END_NAMESPACE_VERSION
1530} // namespace std
1531
1532#endif // C++17
1533
1534#endif // _GLIBCXX_OPTIONAL
1535