1// <optional> -*- C++ -*-
2
3// Copyright (C) 2013-2017 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    virtual const char* what() const noexcept override
86    {return "bad optional access";}
87
88    virtual ~bad_optional_access() noexcept = default;
89  };
90
91  void
92  __throw_bad_optional_access()
93  __attribute__((__noreturn__));
94
95  // XXX Does not belong here.
96  inline void
97  __throw_bad_optional_access()
98  { _GLIBCXX_THROW_OR_ABORT(bad_optional_access()); }
99
100
101  // Payload for constexpr optionals.
102  template <typename _Tp,
103	    bool /*_TrivialCopyMove*/ =
104	      is_trivially_copy_constructible<_Tp>::value
105	      && is_trivially_move_constructible<_Tp>::value,
106	    bool /*_ShouldProvideDestructor*/ =
107	      is_trivially_destructible<_Tp>::value>
108    struct _Optional_payload
109    {
110      constexpr _Optional_payload()
111	: _M_empty() {}
112
113      template<typename... _Args>
114      constexpr _Optional_payload(in_place_t, _Args&&... __args)
115	: _M_payload(std::forward<_Args>(__args)...),
116	  _M_engaged(true)
117      {}
118
119      template<typename _Up, typename... _Args>
120      constexpr _Optional_payload(std::initializer_list<_Up> __il,
121				  _Args&&... __args)
122	: _M_payload(__il, std::forward<_Args>(__args)...),
123	  _M_engaged(true) {}
124
125      template <class _Up> struct __ctor_tag {};
126
127      constexpr _Optional_payload(__ctor_tag<bool>,
128				  const _Tp& __other)
129	: _M_payload(__other),
130	  _M_engaged(true)
131      {}
132
133      constexpr _Optional_payload(__ctor_tag<void>)
134	: _M_empty()
135      {}
136
137      constexpr _Optional_payload(__ctor_tag<bool>, _Tp&& __other)
138	: _M_payload(std::move(__other)),
139	  _M_engaged(true)
140      {}
141
142      constexpr _Optional_payload(bool __engaged,
143				  const _Optional_payload& __other)
144	: _Optional_payload(__engaged ?
145			    _Optional_payload(__ctor_tag<bool>{},
146					      __other._M_payload) :
147			    _Optional_payload(__ctor_tag<void>{}))
148      {}
149
150      constexpr _Optional_payload(bool __engaged,
151				  _Optional_payload&& __other)
152	: _Optional_payload(__engaged
153			    ? _Optional_payload(__ctor_tag<bool>{},
154						std::move(__other._M_payload))
155			    : _Optional_payload(__ctor_tag<void>{}))
156      {}
157
158      using _Stored_type = remove_const_t<_Tp>;
159      struct _Empty_byte { };
160      union {
161          _Empty_byte _M_empty;
162          _Stored_type _M_payload;
163      };
164      bool _M_engaged = false;
165    };
166
167  // Payload for non-constexpr optionals with non-trivial destructor.
168  template <typename _Tp>
169    struct _Optional_payload<_Tp, false, false>
170    {
171      constexpr _Optional_payload()
172	: _M_empty() {}
173
174      template <typename... _Args>
175      constexpr _Optional_payload(in_place_t, _Args&&... __args)
176	: _M_payload(std::forward<_Args>(__args)...),
177	  _M_engaged(true) {}
178
179      template<typename _Up, typename... _Args>
180      constexpr _Optional_payload(std::initializer_list<_Up> __il,
181				  _Args&&... __args)
182	: _M_payload(__il, std::forward<_Args>(__args)...),
183	  _M_engaged(true) {}
184      constexpr
185      _Optional_payload(bool __engaged, const _Optional_payload& __other)
186	: _Optional_payload(__other)
187      {}
188
189      constexpr
190      _Optional_payload(bool __engaged, _Optional_payload&& __other)
191	: _Optional_payload(std::move(__other))
192      {}
193
194      constexpr _Optional_payload(const _Optional_payload& __other)
195      {
196	if (__other._M_engaged)
197	  this->_M_construct(__other._M_payload);
198      }
199
200      constexpr _Optional_payload(_Optional_payload&& __other)
201      {
202	if (__other._M_engaged)
203	  this->_M_construct(std::move(__other._M_payload));
204      }
205
206      using _Stored_type = remove_const_t<_Tp>;
207      struct _Empty_byte { };
208      union {
209          _Empty_byte _M_empty;
210          _Stored_type _M_payload;
211      };
212      bool _M_engaged = false;
213
214      ~_Optional_payload()
215      {
216        if (_M_engaged)
217          _M_payload.~_Stored_type();
218      }
219
220      template<typename... _Args>
221        void
222        _M_construct(_Args&&... __args)
223        noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
224        {
225          ::new ((void *) std::__addressof(this->_M_payload))
226            _Stored_type(std::forward<_Args>(__args)...);
227          this->_M_engaged = true;
228        }
229    };
230
231  // Payload for non-constexpr optionals with trivial destructor.
232  template <typename _Tp>
233    struct _Optional_payload<_Tp, false, true>
234    {
235      constexpr _Optional_payload()
236	: _M_empty() {}
237
238      template <typename... _Args>
239      constexpr _Optional_payload(in_place_t, _Args&&... __args)
240	: _M_payload(std::forward<_Args>(__args)...),
241	  _M_engaged(true) {}
242
243      template<typename _Up, typename... _Args>
244      constexpr _Optional_payload(std::initializer_list<_Up> __il,
245				  _Args&&... __args)
246	: _M_payload(__il, std::forward<_Args>(__args)...),
247	  _M_engaged(true) {}
248      constexpr
249      _Optional_payload(bool __engaged, const _Optional_payload& __other)
250	: _Optional_payload(__other)
251      {}
252
253      constexpr
254      _Optional_payload(bool __engaged, _Optional_payload&& __other)
255	: _Optional_payload(std::move(__other))
256      {}
257
258      constexpr _Optional_payload(const _Optional_payload& __other)
259      {
260	if (__other._M_engaged)
261	  this->_M_construct(__other._M_payload);
262      }
263
264      constexpr _Optional_payload(_Optional_payload&& __other)
265      {
266	if (__other._M_engaged)
267	  this->_M_construct(std::move(__other._M_payload));
268      }
269
270      using _Stored_type = remove_const_t<_Tp>;
271      struct _Empty_byte { };
272      union {
273          _Empty_byte _M_empty;
274          _Stored_type _M_payload;
275      };
276      bool _M_engaged = false;
277
278      template<typename... _Args>
279        void
280        _M_construct(_Args&&... __args)
281        noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
282        {
283          ::new ((void *) std::__addressof(this->_M_payload))
284            _Stored_type(std::forward<_Args>(__args)...);
285          this->_M_engaged = true;
286        }
287    };
288
289  /**
290    * @brief Class template that holds the necessary state for @ref optional
291    * and that has the responsibility for construction and the special members.
292    *
293    * Such a separate base class template is necessary in order to
294    * conditionally enable the special members (e.g. copy/move constructors).
295    * Note that this means that @ref _Optional_base implements the
296    * functionality for copy and move assignment, but not for converting
297    * assignment.
298    *
299    * @see optional, _Enable_special_members
300    */
301  template<typename _Tp>
302    class _Optional_base
303    {
304    private:
305      // Remove const to avoid prohibition of reusing object storage for
306      // const-qualified types in [3.8/9]. This is strictly internal
307      // and even optional itself is oblivious to it.
308      using _Stored_type = remove_const_t<_Tp>;
309
310    public:
311
312      // Constructors for disengaged optionals.
313      constexpr _Optional_base() noexcept
314      { }
315
316      constexpr _Optional_base(nullopt_t) noexcept
317      { }
318
319      // Constructors for engaged optionals.
320      template<typename... _Args,
321	       enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
322        constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
323        : _M_payload(in_place,
324		     std::forward<_Args>(__args)...) { }
325
326      template<typename _Up, typename... _Args,
327               enable_if_t<is_constructible_v<_Tp,
328					      initializer_list<_Up>&,
329					      _Args&&...>, bool> = false>
330        constexpr explicit _Optional_base(in_place_t,
331                                          initializer_list<_Up> __il,
332                                          _Args&&... __args)
333        : _M_payload(in_place,
334		     __il, std::forward<_Args>(__args)...)
335        { }
336
337      // Copy and move constructors.
338      constexpr _Optional_base(const _Optional_base& __other)
339	: _M_payload(__other._M_payload._M_engaged,
340		     __other._M_payload)
341      { }
342
343      constexpr _Optional_base(_Optional_base&& __other)
344      noexcept(is_nothrow_move_constructible<_Tp>())
345	: _M_payload(__other._M_payload._M_engaged,
346		     std::move(__other._M_payload))
347      { }
348
349      // Assignment operators.
350      _Optional_base&
351      operator=(const _Optional_base& __other)
352      {
353        if (this->_M_payload._M_engaged && __other._M_payload._M_engaged)
354          this->_M_get() = __other._M_get();
355        else
356	  {
357	    if (__other._M_payload._M_engaged)
358	      this->_M_construct(__other._M_get());
359	    else
360	      this->_M_reset();
361	  }
362
363        return *this;
364      }
365
366      _Optional_base&
367      operator=(_Optional_base&& __other)
368      noexcept(__and_<is_nothrow_move_constructible<_Tp>,
369		      is_nothrow_move_assignable<_Tp>>())
370      {
371	if (this->_M_payload._M_engaged && __other._M_payload._M_engaged)
372	  this->_M_get() = std::move(__other._M_get());
373	else
374	  {
375	    if (__other._M_payload._M_engaged)
376	      this->_M_construct(std::move(__other._M_get()));
377	    else
378	      this->_M_reset();
379	  }
380	return *this;
381      }
382      // The following functionality is also needed by optional, hence the
383      // protected accessibility.
384    protected:
385      constexpr bool _M_is_engaged() const noexcept
386      { return this->_M_payload._M_engaged; }
387
388      // The _M_get operations have _M_engaged as a precondition.
389      constexpr _Tp&
390      _M_get() noexcept
391      { return this->_M_payload._M_payload; }
392
393      constexpr const _Tp&
394      _M_get() const noexcept
395      { return this->_M_payload._M_payload; }
396
397      // The _M_construct operation has !_M_engaged as a precondition
398      // while _M_destruct has _M_engaged as a precondition.
399      template<typename... _Args>
400        void
401        _M_construct(_Args&&... __args)
402        noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
403        {
404          ::new (std::__addressof(this->_M_payload._M_payload))
405            _Stored_type(std::forward<_Args>(__args)...);
406          this->_M_payload._M_engaged = true;
407        }
408
409      void
410      _M_destruct()
411      {
412        this->_M_payload._M_engaged = false;
413        this->_M_payload._M_payload.~_Stored_type();
414      }
415
416      // _M_reset is a 'safe' operation with no precondition.
417      void
418      _M_reset()
419      {
420        if (this->_M_payload._M_engaged)
421          this->_M_destruct();
422      }
423
424    private:
425      _Optional_payload<_Tp> _M_payload;
426    };
427
428  template<typename _Tp>
429  class optional;
430
431  template<typename _Tp, typename _Up>
432    using __converts_from_optional =
433      __or_<is_constructible<_Tp, const optional<_Up>&>,
434	    is_constructible<_Tp, optional<_Up>&>,
435	    is_constructible<_Tp, const optional<_Up>&&>,
436	    is_constructible<_Tp, optional<_Up>&&>,
437	    is_convertible<const optional<_Up>&, _Tp>,
438	    is_convertible<optional<_Up>&, _Tp>,
439	    is_convertible<const optional<_Up>&&, _Tp>,
440	    is_convertible<optional<_Up>&&, _Tp>>;
441
442  template<typename _Tp, typename _Up>
443    using __assigns_from_optional =
444      __or_<is_assignable<_Tp&, const optional<_Up>&>,
445	    is_assignable<_Tp&, optional<_Up>&>,
446	    is_assignable<_Tp&, const optional<_Up>&&>,
447	    is_assignable<_Tp&, optional<_Up>&&>>;
448
449  /**
450    * @brief Class template for optional values.
451    */
452  template<typename _Tp>
453    class optional
454    : private _Optional_base<_Tp>,
455      private _Enable_copy_move<
456        // Copy constructor.
457        is_copy_constructible<_Tp>::value,
458        // Copy assignment.
459        __and_<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>::value,
460        // Move constructor.
461        is_move_constructible<_Tp>::value,
462        // Move assignment.
463        __and_<is_move_constructible<_Tp>, is_move_assignable<_Tp>>::value,
464        // Unique tag type.
465        optional<_Tp>>
466    {
467      static_assert(__and_<__not_<is_same<remove_cv_t<_Tp>, nullopt_t>>,
468			   __not_<is_same<remove_cv_t<_Tp>, in_place_t>>,
469			   __not_<is_reference<_Tp>>>(),
470                    "Invalid instantiation of optional<T>");
471
472    private:
473      using _Base = _Optional_base<_Tp>;
474
475    public:
476      using value_type = _Tp;
477
478      constexpr optional() = default;
479
480      constexpr optional(nullopt_t) noexcept
481	: _Base(nullopt) { }
482
483      // Converting constructors for engaged optionals.
484      template <typename _Up = _Tp,
485                enable_if_t<__and_<
486			      __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
487			      __not_<is_same<in_place_t, decay_t<_Up>>>,
488			      is_constructible<_Tp, _Up&&>,
489			      is_convertible<_Up&&, _Tp>
490			      >::value, bool> = true>
491      constexpr optional(_Up&& __t)
492        : _Base(std::in_place, std::forward<_Up>(__t)) { }
493
494      template <typename _Up = _Tp,
495                enable_if_t<__and_<
496			      __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
497			      __not_<is_same<in_place_t, decay_t<_Up>>>,
498			      is_constructible<_Tp, _Up&&>,
499			      __not_<is_convertible<_Up&&, _Tp>>
500			      >::value, bool> = false>
501      explicit constexpr optional(_Up&& __t)
502        : _Base(std::in_place, std::forward<_Up>(__t)) { }
503
504      template <typename _Up,
505                enable_if_t<__and_<
506			    __not_<is_same<_Tp, _Up>>,
507			    is_constructible<_Tp, const _Up&>,
508			    is_convertible<const _Up&, _Tp>,
509			    __not_<__converts_from_optional<_Tp, _Up>>
510			    >::value, bool> = true>
511      constexpr optional(const optional<_Up>& __t)
512      {
513	if (__t)
514	  emplace(*__t);
515      }
516
517      template <typename _Up,
518                 enable_if_t<__and_<
519			       __not_<is_same<_Tp, _Up>>,
520			       is_constructible<_Tp, const _Up&>,
521			       __not_<is_convertible<const _Up&, _Tp>>,
522			       __not_<__converts_from_optional<_Tp, _Up>>
523			       >::value, bool> = false>
524      explicit constexpr optional(const optional<_Up>& __t)
525      {
526	if (__t)
527	  emplace(*__t);
528      }
529
530      template <typename _Up,
531                enable_if_t<__and_<
532			      __not_<is_same<_Tp, _Up>>,
533			      is_constructible<_Tp, _Up&&>,
534			      is_convertible<_Up&&, _Tp>,
535			      __not_<__converts_from_optional<_Tp, _Up>>
536			      >::value, bool> = true>
537      constexpr optional(optional<_Up>&& __t)
538      {
539	if (__t)
540	  emplace(std::move(*__t));
541      }
542
543      template <typename _Up,
544                enable_if_t<__and_<
545			    __not_<is_same<_Tp, _Up>>,
546			    is_constructible<_Tp, _Up&&>,
547			    __not_<is_convertible<_Up&&, _Tp>>,
548			    __not_<__converts_from_optional<_Tp, _Up>>
549			    >::value, bool> = false>
550      explicit constexpr optional(optional<_Up>&& __t)
551      {
552	if (__t)
553	  emplace(std::move(*__t));
554      }
555
556      template<typename... _Args,
557	       enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
558      explicit constexpr optional(in_place_t, _Args&&... __args)
559        : _Base(std::in_place, std::forward<_Args>(__args)...) { }
560
561      template<typename _Up, typename... _Args,
562               enable_if_t<is_constructible_v<_Tp,
563					      initializer_list<_Up>&,
564					      _Args&&...>, bool> = false>
565      explicit constexpr optional(in_place_t,
566				  initializer_list<_Up> __il,
567				  _Args&&... __args)
568        : _Base(std::in_place, __il, std::forward<_Args>(__args)...) { }
569
570      // Assignment operators.
571      optional&
572      operator=(nullopt_t) noexcept
573      {
574        this->_M_reset();
575        return *this;
576      }
577
578      template<typename _Up = _Tp>
579        enable_if_t<__and_<
580		      __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
581		      is_constructible<_Tp, _Up>,
582		      __not_<__and_<is_scalar<_Tp>,
583				    is_same<_Tp, decay_t<_Up>>>>,
584		      is_assignable<_Tp&, _Up>>::value,
585		    optional&>
586        operator=(_Up&& __u)
587        {
588          if (this->_M_is_engaged())
589            this->_M_get() = std::forward<_Up>(__u);
590          else
591            this->_M_construct(std::forward<_Up>(__u));
592
593          return *this;
594        }
595
596      template<typename _Up>
597	enable_if_t<__and_<
598		      __not_<is_same<_Tp, _Up>>,
599		      is_constructible<_Tp, const _Up&>,
600		      is_assignable<_Tp&, _Up>,
601		      __not_<__converts_from_optional<_Tp, _Up>>,
602		      __not_<__assigns_from_optional<_Tp, _Up>>
603		      >::value,
604		    optional&>
605        operator=(const optional<_Up>& __u)
606        {
607          if (__u)
608            {
609              if (this->_M_is_engaged())
610                this->_M_get() = *__u;
611              else
612                this->_M_construct(*__u);
613            }
614          else
615            {
616              this->_M_reset();
617            }
618          return *this;
619        }
620
621      template<typename _Up>
622	enable_if_t<__and_<
623		      __not_<is_same<_Tp, _Up>>,
624		      is_constructible<_Tp, _Up>,
625		      is_assignable<_Tp&, _Up>,
626		      __not_<__converts_from_optional<_Tp, _Up>>,
627		      __not_<__assigns_from_optional<_Tp, _Up>>
628		      >::value,
629		    optional&>
630        operator=(optional<_Up>&& __u)
631        {
632          if (__u)
633            {
634              if (this->_M_is_engaged())
635                this->_M_get() = std::move(*__u);
636              else
637                this->_M_construct(std::move(*__u));
638            }
639          else
640            {
641              this->_M_reset();
642            }
643
644          return *this;
645        }
646
647      template<typename... _Args>
648	enable_if_t<is_constructible<_Tp, _Args&&...>::value, _Tp&>
649	emplace(_Args&&... __args)
650	{
651	  this->_M_reset();
652	  this->_M_construct(std::forward<_Args>(__args)...);
653	  return this->_M_get();
654	}
655
656      template<typename _Up, typename... _Args>
657	enable_if_t<is_constructible<_Tp, initializer_list<_Up>&,
658				     _Args&&...>::value, _Tp&>
659	emplace(initializer_list<_Up> __il, _Args&&... __args)
660	{
661	  this->_M_reset();
662	  this->_M_construct(__il, std::forward<_Args>(__args)...);
663	  return this->_M_get();
664	}
665
666      // Destructor is implicit, implemented in _Optional_base.
667
668      // Swap.
669      void
670      swap(optional& __other)
671      noexcept(is_nothrow_move_constructible<_Tp>()
672               && is_nothrow_swappable_v<_Tp>)
673      {
674        using std::swap;
675
676        if (this->_M_is_engaged() && __other._M_is_engaged())
677          swap(this->_M_get(), __other._M_get());
678        else if (this->_M_is_engaged())
679	  {
680	    __other._M_construct(std::move(this->_M_get()));
681	    this->_M_destruct();
682	  }
683        else if (__other._M_is_engaged())
684	  {
685	    this->_M_construct(std::move(__other._M_get()));
686	    __other._M_destruct();
687	  }
688      }
689
690      // Observers.
691      constexpr const _Tp*
692      operator->() const
693      { return std::__addressof(this->_M_get()); }
694
695      _Tp*
696      operator->()
697      { return std::__addressof(this->_M_get()); }
698
699      constexpr const _Tp&
700      operator*() const&
701      { return this->_M_get(); }
702
703      constexpr _Tp&
704      operator*()&
705      { return this->_M_get(); }
706
707      constexpr _Tp&&
708      operator*()&&
709      { return std::move(this->_M_get()); }
710
711      constexpr const _Tp&&
712      operator*() const&&
713      { return std::move(this->_M_get()); }
714
715      constexpr explicit operator bool() const noexcept
716      { return this->_M_is_engaged(); }
717
718      constexpr bool has_value() const noexcept
719      { return this->_M_is_engaged(); }
720
721      constexpr const _Tp&
722      value() const&
723      {
724	return this->_M_is_engaged()
725	  ?  this->_M_get()
726	  : (__throw_bad_optional_access(),
727	     this->_M_get());
728      }
729
730      constexpr _Tp&
731      value()&
732      {
733	return this->_M_is_engaged()
734	  ?  this->_M_get()
735	  : (__throw_bad_optional_access(),
736	     this->_M_get());
737      }
738
739      constexpr _Tp&&
740      value()&&
741      {
742	return this->_M_is_engaged()
743	  ?  std::move(this->_M_get())
744	  : (__throw_bad_optional_access(),
745	     std::move(this->_M_get()));
746      }
747
748      constexpr const _Tp&&
749      value() const&&
750      {
751	return this->_M_is_engaged()
752	  ?  std::move(this->_M_get())
753	  : (__throw_bad_optional_access(),
754	     std::move(this->_M_get()));
755      }
756
757      template<typename _Up>
758	constexpr _Tp
759	value_or(_Up&& __u) const&
760	{
761	  static_assert(__and_<is_copy_constructible<_Tp>,
762			       is_convertible<_Up&&, _Tp>>(),
763			"Cannot return value");
764
765	  return this->_M_is_engaged()
766	    ? this->_M_get()
767	    : static_cast<_Tp>(std::forward<_Up>(__u));
768	}
769
770      template<typename _Up>
771	_Tp
772	value_or(_Up&& __u) &&
773	{
774	  static_assert(__and_<is_move_constructible<_Tp>,
775			       is_convertible<_Up&&, _Tp>>(),
776			"Cannot return value" );
777
778	  return this->_M_is_engaged()
779	    ? std::move(this->_M_get())
780	    : static_cast<_Tp>(std::forward<_Up>(__u));
781	}
782      void reset() noexcept { this->_M_reset(); }
783    };
784
785  template<typename _Tp>
786    using __optional_relop_t =
787    enable_if_t<is_convertible<_Tp, bool>::value, bool>;
788
789  // Comparisons between optional values.
790  template<typename _Tp, typename _Up>
791    constexpr auto
792    operator==(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
793    -> __optional_relop_t<decltype(declval<_Tp>() == declval<_Up>())>
794    {
795      return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
796	     && (!__lhs || *__lhs == *__rhs);
797    }
798
799  template<typename _Tp, typename _Up>
800    constexpr auto
801    operator!=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
802    -> __optional_relop_t<decltype(declval<_Tp>() != declval<_Up>())>
803    {
804      return static_cast<bool>(__lhs) != static_cast<bool>(__rhs)
805	|| (static_cast<bool>(__lhs) && *__lhs != *__rhs);
806    }
807
808  template<typename _Tp, typename _Up>
809    constexpr auto
810    operator<(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
811    -> __optional_relop_t<decltype(declval<_Tp>() < declval<_Up>())>
812    {
813      return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
814    }
815
816  template<typename _Tp, typename _Up>
817    constexpr auto
818    operator>(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
819    -> __optional_relop_t<decltype(declval<_Tp>() > declval<_Up>())>
820    {
821      return static_cast<bool>(__lhs) && (!__rhs || *__lhs > *__rhs);
822    }
823
824  template<typename _Tp, typename _Up>
825    constexpr auto
826    operator<=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
827    -> __optional_relop_t<decltype(declval<_Tp>() <= declval<_Up>())>
828    {
829      return !__lhs || (static_cast<bool>(__rhs) && *__lhs <= *__rhs);
830    }
831
832  template<typename _Tp, typename _Up>
833    constexpr auto
834    operator>=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
835    -> __optional_relop_t<decltype(declval<_Tp>() >= declval<_Up>())>
836    {
837      return !__rhs || (static_cast<bool>(__lhs) && *__lhs >= *__rhs);
838    }
839
840  // Comparisons with nullopt.
841  template<typename _Tp>
842    constexpr bool
843    operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept
844    { return !__lhs; }
845
846  template<typename _Tp>
847    constexpr bool
848    operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept
849    { return !__rhs; }
850
851  template<typename _Tp>
852    constexpr bool
853    operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept
854    { return static_cast<bool>(__lhs); }
855
856  template<typename _Tp>
857    constexpr bool
858    operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept
859    { return static_cast<bool>(__rhs); }
860
861  template<typename _Tp>
862    constexpr bool
863    operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
864    { return false; }
865
866  template<typename _Tp>
867    constexpr bool
868    operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
869    { return static_cast<bool>(__rhs); }
870
871  template<typename _Tp>
872    constexpr bool
873    operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept
874    { return static_cast<bool>(__lhs); }
875
876  template<typename _Tp>
877    constexpr bool
878    operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
879    { return false; }
880
881  template<typename _Tp>
882    constexpr bool
883    operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept
884    { return !__lhs; }
885
886  template<typename _Tp>
887    constexpr bool
888    operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
889    { return true; }
890
891  template<typename _Tp>
892    constexpr bool
893    operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
894    { return true; }
895
896  template<typename _Tp>
897    constexpr bool
898    operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept
899    { return !__rhs; }
900
901  // Comparisons with value type.
902  template<typename _Tp, typename _Up>
903    constexpr auto
904    operator==(const optional<_Tp>& __lhs, const _Up& __rhs)
905    -> __optional_relop_t<decltype(declval<_Tp>() == declval<_Up>())>
906    { return __lhs && *__lhs == __rhs; }
907
908  template<typename _Tp, typename _Up>
909    constexpr auto
910    operator==(const _Up& __lhs, const optional<_Tp>& __rhs)
911    -> __optional_relop_t<decltype(declval<_Up>() == declval<_Tp>())>
912    { return __rhs && __lhs == *__rhs; }
913
914  template<typename _Tp, typename _Up>
915    constexpr auto
916    operator!=(const optional<_Tp>& __lhs, const _Up& __rhs)
917    -> __optional_relop_t<decltype(declval<_Tp>() != declval<_Up>())>
918    { return !__lhs || *__lhs != __rhs; }
919
920  template<typename _Tp, typename _Up>
921    constexpr auto
922    operator!=(const _Up& __lhs, const optional<_Tp>& __rhs)
923    -> __optional_relop_t<decltype(declval<_Up>() != declval<_Tp>())>
924    { return !__rhs || __lhs != *__rhs; }
925
926  template<typename _Tp, typename _Up>
927    constexpr auto
928    operator<(const optional<_Tp>& __lhs, const _Up& __rhs)
929    -> __optional_relop_t<decltype(declval<_Tp>() < declval<_Up>())>
930    { return !__lhs || *__lhs < __rhs; }
931
932  template<typename _Tp, typename _Up>
933    constexpr auto
934    operator<(const _Up& __lhs, const optional<_Tp>& __rhs)
935    -> __optional_relop_t<decltype(declval<_Up>() < declval<_Tp>())>
936    { return __rhs && __lhs < *__rhs; }
937
938  template<typename _Tp, typename _Up>
939    constexpr auto
940    operator>(const optional<_Tp>& __lhs, const _Up& __rhs)
941    -> __optional_relop_t<decltype(declval<_Tp>() > declval<_Up>())>
942    { return __lhs && *__lhs > __rhs; }
943
944  template<typename _Tp, typename _Up>
945    constexpr auto
946    operator>(const _Up& __lhs, const optional<_Tp>& __rhs)
947    -> __optional_relop_t<decltype(declval<_Up>() > declval<_Tp>())>
948    { return !__rhs || __lhs > *__rhs; }
949
950  template<typename _Tp, typename _Up>
951    constexpr auto
952    operator<=(const optional<_Tp>& __lhs, const _Up& __rhs)
953    -> __optional_relop_t<decltype(declval<_Tp>() <= declval<_Up>())>
954    { return !__lhs || *__lhs <= __rhs; }
955
956  template<typename _Tp, typename _Up>
957    constexpr auto
958    operator<=(const _Up& __lhs, const optional<_Tp>& __rhs)
959    -> __optional_relop_t<decltype(declval<_Up>() <= declval<_Tp>())>
960    { return __rhs && __lhs <= *__rhs; }
961
962  template<typename _Tp, typename _Up>
963    constexpr auto
964    operator>=(const optional<_Tp>& __lhs, const _Up& __rhs)
965    -> __optional_relop_t<decltype(declval<_Tp>() >= declval<_Up>())>
966    { return __lhs && *__lhs >= __rhs; }
967
968  template<typename _Tp, typename _Up>
969    constexpr auto
970    operator>=(const _Up& __lhs, const optional<_Tp>& __rhs)
971    -> __optional_relop_t<decltype(declval<_Up>() >= declval<_Tp>())>
972    { return !__rhs || __lhs >= *__rhs; }
973
974  // Swap and creation functions.
975
976  // _GLIBCXX_RESOLVE_LIB_DEFECTS
977  // 2748. swappable traits for optionals
978  template<typename _Tp>
979    inline enable_if_t<is_move_constructible_v<_Tp> && is_swappable_v<_Tp>>
980    swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
981    noexcept(noexcept(__lhs.swap(__rhs)))
982    { __lhs.swap(__rhs); }
983
984  template<typename _Tp>
985    enable_if_t<!(is_move_constructible_v<_Tp> && is_swappable_v<_Tp>)>
986    swap(optional<_Tp>&, optional<_Tp>&) = delete;
987
988  template<typename _Tp>
989    constexpr optional<decay_t<_Tp>>
990    make_optional(_Tp&& __t)
991    { return optional<decay_t<_Tp>> { std::forward<_Tp>(__t) }; }
992
993  template<typename _Tp, typename ..._Args>
994    constexpr optional<_Tp>
995    make_optional(_Args&&... __args)
996    { return optional<_Tp> { in_place, std::forward<_Args>(__args)... }; }
997
998  template<typename _Tp, typename _Up, typename ..._Args>
999    constexpr optional<_Tp>
1000    make_optional(initializer_list<_Up> __il, _Args&&... __args)
1001    { return optional<_Tp> { in_place, __il, std::forward<_Args>(__args)... }; }
1002
1003  // Hash.
1004
1005  template<typename _Tp, typename _Up = remove_const_t<_Tp>,
1006           bool = __poison_hash<_Up>::__enable_hash_call>
1007    struct __optional_hash_call_base
1008    {
1009      size_t
1010      operator()(const optional<_Tp>& __t) const
1011      noexcept(noexcept(hash<_Up>{}(*__t)))
1012      {
1013        // We pick an arbitrary hash for disengaged optionals which hopefully
1014        // usual values of _Tp won't typically hash to.
1015        constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333);
1016        return __t ? hash<_Up>{}(*__t) : __magic_disengaged_hash;
1017      }
1018    };
1019
1020  template<typename _Tp, typename _Up>
1021    struct __optional_hash_call_base<_Tp, _Up, false> {};
1022
1023  template<typename _Tp>
1024    struct hash<optional<_Tp>>
1025    : private __poison_hash<remove_const_t<_Tp>>,
1026      public __optional_hash_call_base<_Tp>
1027    {
1028      using result_type = size_t;
1029      using argument_type = optional<_Tp>;
1030    };
1031
1032  /// @}
1033
1034#if __cpp_deduction_guides >= 201606
1035  template <typename _Tp> optional(_Tp) -> optional<_Tp>;
1036#endif
1037
1038_GLIBCXX_END_NAMESPACE_VERSION
1039} // namespace std
1040
1041#endif // C++17
1042
1043#endif // _GLIBCXX_OPTIONAL
1044