]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/libcxx/include/optional
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / libcxx / include / optional
1 // -*- C++ -*-
2 //===-------------------------- optional ----------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef _LIBCPP_OPTIONAL
11 #define _LIBCPP_OPTIONAL
12
13 /*
14     optional synopsis
15
16 // C++1z
17
18 namespace std {
19   // 23.6.3, optional for object types
20   template <class T> class optional;
21
22   // 23.6.4, no-value state indicator
23   struct nullopt_t{see below };
24   inline constexpr nullopt_t nullopt(unspecified );
25
26   // 23.6.5, class bad_optional_access
27   class bad_optional_access;
28
29   // 23.6.6, relational operators
30   template <class T, class U>
31   constexpr bool operator==(const optional<T>&, const optional<U>&);
32   template <class T, class U>
33   constexpr bool operator!=(const optional<T>&, const optional<U>&);
34   template <class T, class U>
35   constexpr bool operator<(const optional<T>&, const optional<U>&);
36   template <class T, class U>
37   constexpr bool operator>(const optional<T>&, const optional<U>&);
38   template <class T, class U>
39   constexpr bool operator<=(const optional<T>&, const optional<U>&);
40   template <class T, class U>
41   constexpr bool operator>=(const optional<T>&, const optional<U>&);
42
43   // 23.6.7 comparison with nullopt
44   template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
45   template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept;
46   template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept;
47   template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept;
48   template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept;
49   template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept;
50   template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept;
51   template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept;
52   template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept;
53   template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept;
54   template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept;
55   template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept;
56
57   // 23.6.8, comparison with T
58   template <class T, class U> constexpr bool operator==(const optional<T>&, const U&);
59   template <class T, class U> constexpr bool operator==(const T&, const optional<U>&);
60   template <class T, class U> constexpr bool operator!=(const optional<T>&, const U&);
61   template <class T, class U> constexpr bool operator!=(const T&, const optional<U>&);
62   template <class T, class U> constexpr bool operator<(const optional<T>&, const U&);
63   template <class T, class U> constexpr bool operator<(const T&, const optional<U>&);
64   template <class T, class U> constexpr bool operator<=(const optional<T>&, const U&);
65   template <class T, class U> constexpr bool operator<=(const T&, const optional<U>&);
66   template <class T, class U> constexpr bool operator>(const optional<T>&, const U&);
67   template <class T, class U> constexpr bool operator>(const T&, const optional<U>&);
68   template <class T, class U> constexpr bool operator>=(const optional<T>&, const U&);
69   template <class T, class U> constexpr bool operator>=(const T&, const optional<U>&);
70
71   // 23.6.9, specialized algorithms
72   template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below );
73   template <class T> constexpr optional<see below > make_optional(T&&);
74   template <class T, class... Args>
75     constexpr optional<T> make_optional(Args&&... args);
76   template <class T, class U, class... Args>
77     constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args);
78
79   // 23.6.10, hash support
80   template <class T> struct hash;
81   template <class T> struct hash<optional<T>>;
82
83   template <class T> class optional {
84   public:
85     using value_type = T;
86
87     // 23.6.3.1, constructors
88     constexpr optional() noexcept;
89     constexpr optional(nullopt_t) noexcept;
90     optional(const optional &);
91     optional(optional &&) noexcept(see below);
92     template <class... Args> constexpr explicit optional(in_place_t, Args &&...);
93     template <class U, class... Args>
94       constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...);
95     template <class U = T>
96       constexpr EXPLICIT optional(U &&);
97     template <class U>
98       constexpr EXPLICIT optional(const optional<U> &);
99     template <class U>
100       constexpr EXPLICIT optional(optional<U> &&);
101
102     // 23.6.3.2, destructor
103     ~optional();
104
105     // 23.6.3.3, assignment
106     optional &operator=(nullopt_t) noexcept;
107     optional &operator=(const optional &);                // constexpr in C++20
108     optional &operator=(optional &&) noexcept(see below); // constexpr in C++20
109     template <class U = T> optional &operator=(U &&);
110     template <class U> optional &operator=(const optional<U> &);
111     template <class U> optional &operator=(optional<U> &&);
112     template <class... Args> T& emplace(Args &&...);
113     template <class U, class... Args>
114       T& emplace(initializer_list<U>, Args &&...);
115
116     // 23.6.3.4, swap
117     void swap(optional &) noexcept(see below );
118
119     // 23.6.3.5, observers
120     constexpr T const *operator->() const;
121     constexpr T *operator->();
122     constexpr T const &operator*() const &;
123     constexpr T &operator*() &;
124     constexpr T &&operator*() &&;
125     constexpr const T &&operator*() const &&;
126     constexpr explicit operator bool() const noexcept;
127     constexpr bool has_value() const noexcept;
128     constexpr T const &value() const &;
129     constexpr T &value() &;
130     constexpr T &&value() &&;
131     constexpr const T &&value() const &&;
132     template <class U> constexpr T value_or(U &&) const &;
133     template <class U> constexpr T value_or(U &&) &&;
134
135     // 23.6.3.6, modifiers
136     void reset() noexcept;
137
138   private:
139     T *val; // exposition only
140   };
141
142 template<class T>
143   optional(T) -> optional<T>;
144
145 } // namespace std
146
147 */
148
149 #include <__config>
150 #include <__debug>
151 #include <__functional_base>
152 #include <functional>
153 #include <initializer_list>
154 #include <new>
155 #include <stdexcept>
156 #include <type_traits>
157 #include <utility>
158 #include <version>
159
160 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
161 #pragma GCC system_header
162 #endif
163
164 _LIBCPP_PUSH_MACROS
165 #include <__undef_macros>
166
167
168 namespace std  // purposefully not using versioning namespace
169 {
170
171 class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
172     : public exception
173 {
174 public:
175     // Get the key function ~bad_optional_access() into the dylib
176     virtual ~bad_optional_access() _NOEXCEPT;
177     virtual const char* what() const _NOEXCEPT;
178 };
179
180 }  // std
181
182 #if _LIBCPP_STD_VER > 14
183
184 _LIBCPP_BEGIN_NAMESPACE_STD
185
186 _LIBCPP_NORETURN
187 inline _LIBCPP_INLINE_VISIBILITY
188 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
189 void __throw_bad_optional_access() {
190 #ifndef _LIBCPP_NO_EXCEPTIONS
191         throw bad_optional_access();
192 #else
193         _VSTD::abort();
194 #endif
195 }
196
197 struct nullopt_t
198 {
199     struct __secret_tag { _LIBCPP_INLINE_VISIBILITY explicit __secret_tag() = default; };
200     _LIBCPP_INLINE_VISIBILITY constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {}
201 };
202
203 _LIBCPP_INLINE_VAR constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}};
204
205 template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
206 struct __optional_destruct_base;
207
208 template <class _Tp>
209 struct __optional_destruct_base<_Tp, false>
210 {
211     typedef _Tp value_type;
212     static_assert(is_object_v<value_type>,
213         "instantiation of optional with a non-object type is undefined behavior");
214     union
215     {
216         char __null_state_;
217         value_type __val_;
218     };
219     bool __engaged_;
220
221     _LIBCPP_INLINE_VISIBILITY
222     ~__optional_destruct_base()
223     {
224         if (__engaged_)
225             __val_.~value_type();
226     }
227
228     _LIBCPP_INLINE_VISIBILITY
229     constexpr __optional_destruct_base() noexcept
230         :  __null_state_(),
231            __engaged_(false) {}
232
233     template <class... _Args>
234     _LIBCPP_INLINE_VISIBILITY
235     constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
236         :  __val_(_VSTD::forward<_Args>(__args)...),
237            __engaged_(true) {}
238
239     _LIBCPP_INLINE_VISIBILITY
240     void reset() noexcept
241     {
242         if (__engaged_)
243         {
244             __val_.~value_type();
245             __engaged_ = false;
246         }
247     }
248 };
249
250 template <class _Tp>
251 struct __optional_destruct_base<_Tp, true>
252 {
253     typedef _Tp value_type;
254     static_assert(is_object_v<value_type>,
255         "instantiation of optional with a non-object type is undefined behavior");
256     union
257     {
258         char __null_state_;
259         value_type __val_;
260     };
261     bool __engaged_;
262
263     _LIBCPP_INLINE_VISIBILITY
264     constexpr __optional_destruct_base() noexcept
265         :  __null_state_(),
266            __engaged_(false) {}
267
268     template <class... _Args>
269     _LIBCPP_INLINE_VISIBILITY
270     constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
271         :  __val_(_VSTD::forward<_Args>(__args)...),
272            __engaged_(true) {}
273
274     _LIBCPP_INLINE_VISIBILITY
275     void reset() noexcept
276     {
277         if (__engaged_)
278         {
279             __engaged_ = false;
280         }
281     }
282 };
283
284 template <class _Tp, bool = is_reference<_Tp>::value>
285 struct __optional_storage_base : __optional_destruct_base<_Tp>
286 {
287     using __base = __optional_destruct_base<_Tp>;
288     using value_type = _Tp;
289     using __base::__base;
290
291     _LIBCPP_INLINE_VISIBILITY
292     constexpr bool has_value() const noexcept
293     {
294         return this->__engaged_;
295     }
296
297     _LIBCPP_INLINE_VISIBILITY
298     constexpr value_type& __get() & noexcept
299     {
300         return this->__val_;
301     }
302     _LIBCPP_INLINE_VISIBILITY
303     constexpr const value_type& __get() const& noexcept
304     {
305         return this->__val_;
306     }
307     _LIBCPP_INLINE_VISIBILITY
308     constexpr value_type&& __get() && noexcept
309     {
310         return _VSTD::move(this->__val_);
311     }
312     _LIBCPP_INLINE_VISIBILITY
313     constexpr const value_type&& __get() const&& noexcept
314     {
315         return _VSTD::move(this->__val_);
316     }
317
318     template <class... _Args>
319     _LIBCPP_INLINE_VISIBILITY
320     void __construct(_Args&&... __args)
321     {
322         _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
323         ::new((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
324         this->__engaged_ = true;
325     }
326
327     template <class _That>
328     _LIBCPP_INLINE_VISIBILITY
329     void __construct_from(_That&& __opt)
330     {
331         if (__opt.has_value())
332             __construct(_VSTD::forward<_That>(__opt).__get());
333     }
334
335     template <class _That>
336     _LIBCPP_INLINE_VISIBILITY
337     void __assign_from(_That&& __opt)
338     {
339         if (this->__engaged_ == __opt.has_value())
340         {
341             if (this->__engaged_)
342                 this->__val_ = _VSTD::forward<_That>(__opt).__get();
343         }
344         else
345         {
346             if (this->__engaged_)
347                 this->reset();
348             else
349                 __construct(_VSTD::forward<_That>(__opt).__get());
350         }
351     }
352 };
353
354 // optional<T&> is currently required ill-formed, however it may to be in the
355 // future. For this reason it has already been implemented to ensure we can
356 // make the change in an ABI compatible manner.
357 template <class _Tp>
358 struct __optional_storage_base<_Tp, true>
359 {
360     using value_type = _Tp;
361     using __raw_type = remove_reference_t<_Tp>;
362     __raw_type* __value_;
363
364     template <class _Up>
365     static constexpr bool __can_bind_reference() {
366         using _RawUp = typename remove_reference<_Up>::type;
367         using _UpPtr = _RawUp*;
368         using _RawTp = typename remove_reference<_Tp>::type;
369         using _TpPtr = _RawTp*;
370         using _CheckLValueArg = integral_constant<bool,
371             (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value)
372         ||  is_same<_RawUp, reference_wrapper<_RawTp>>::value
373         ||  is_same<_RawUp, reference_wrapper<typename remove_const<_RawTp>::type>>::value
374         >;
375         return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value)
376             || (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value &&
377                 is_convertible<_UpPtr, _TpPtr>::value);
378     }
379
380     _LIBCPP_INLINE_VISIBILITY
381     constexpr __optional_storage_base() noexcept
382         :  __value_(nullptr) {}
383
384     template <class _UArg>
385     _LIBCPP_INLINE_VISIBILITY
386     constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg)
387         :  __value_(_VSTD::addressof(__uarg))
388     {
389       static_assert(__can_bind_reference<_UArg>(),
390         "Attempted to construct a reference element in tuple from a "
391         "possible temporary");
392     }
393
394     _LIBCPP_INLINE_VISIBILITY
395     void reset() noexcept { __value_ = nullptr; }
396
397     _LIBCPP_INLINE_VISIBILITY
398     constexpr bool has_value() const noexcept
399       { return __value_ != nullptr; }
400
401     _LIBCPP_INLINE_VISIBILITY
402     constexpr value_type& __get() const& noexcept
403       { return *__value_; }
404
405     _LIBCPP_INLINE_VISIBILITY
406     constexpr value_type&& __get() const&& noexcept
407       { return _VSTD::forward<value_type>(*__value_); }
408
409     template <class _UArg>
410     _LIBCPP_INLINE_VISIBILITY
411     void __construct(_UArg&& __val)
412     {
413         _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
414         static_assert(__can_bind_reference<_UArg>(),
415             "Attempted to construct a reference element in tuple from a "
416             "possible temporary");
417         __value_ = _VSTD::addressof(__val);
418     }
419
420     template <class _That>
421     _LIBCPP_INLINE_VISIBILITY
422     void __construct_from(_That&& __opt)
423     {
424         if (__opt.has_value())
425             __construct(_VSTD::forward<_That>(__opt).__get());
426     }
427
428     template <class _That>
429     _LIBCPP_INLINE_VISIBILITY
430     void __assign_from(_That&& __opt)
431     {
432         if (has_value() == __opt.has_value())
433         {
434             if (has_value())
435                 *__value_ = _VSTD::forward<_That>(__opt).__get();
436         }
437         else
438         {
439             if (has_value())
440                 reset();
441             else
442                 __construct(_VSTD::forward<_That>(__opt).__get());
443         }
444     }
445 };
446
447 template <class _Tp, bool = is_trivially_copy_constructible<_Tp>::value>
448 struct __optional_copy_base : __optional_storage_base<_Tp>
449 {
450     using __optional_storage_base<_Tp>::__optional_storage_base;
451 };
452
453 template <class _Tp>
454 struct __optional_copy_base<_Tp, false> : __optional_storage_base<_Tp>
455 {
456     using __optional_storage_base<_Tp>::__optional_storage_base;
457
458     _LIBCPP_INLINE_VISIBILITY
459     __optional_copy_base() = default;
460
461     _LIBCPP_INLINE_VISIBILITY
462     __optional_copy_base(const __optional_copy_base& __opt)
463     {
464         this->__construct_from(__opt);
465     }
466
467     _LIBCPP_INLINE_VISIBILITY
468     __optional_copy_base(__optional_copy_base&&) = default;
469     _LIBCPP_INLINE_VISIBILITY
470     __optional_copy_base& operator=(const __optional_copy_base&) = default;
471     _LIBCPP_INLINE_VISIBILITY
472     __optional_copy_base& operator=(__optional_copy_base&&) = default;
473 };
474
475 template <class _Tp, bool = is_trivially_move_constructible<_Tp>::value>
476 struct __optional_move_base : __optional_copy_base<_Tp>
477 {
478     using __optional_copy_base<_Tp>::__optional_copy_base;
479 };
480
481 template <class _Tp>
482 struct __optional_move_base<_Tp, false> : __optional_copy_base<_Tp>
483 {
484     using value_type = _Tp;
485     using __optional_copy_base<_Tp>::__optional_copy_base;
486
487     _LIBCPP_INLINE_VISIBILITY
488     __optional_move_base() = default;
489     _LIBCPP_INLINE_VISIBILITY
490     __optional_move_base(const __optional_move_base&) = default;
491
492     _LIBCPP_INLINE_VISIBILITY
493     __optional_move_base(__optional_move_base&& __opt)
494         noexcept(is_nothrow_move_constructible_v<value_type>)
495     {
496         this->__construct_from(_VSTD::move(__opt));
497     }
498
499     _LIBCPP_INLINE_VISIBILITY
500     __optional_move_base& operator=(const __optional_move_base&) = default;
501     _LIBCPP_INLINE_VISIBILITY
502     __optional_move_base& operator=(__optional_move_base&&) = default;
503 };
504
505 template <class _Tp, bool =
506     is_trivially_destructible<_Tp>::value &&
507     is_trivially_copy_constructible<_Tp>::value &&
508     is_trivially_copy_assignable<_Tp>::value>
509 struct __optional_copy_assign_base : __optional_move_base<_Tp>
510 {
511     using __optional_move_base<_Tp>::__optional_move_base;
512 };
513
514 template <class _Tp>
515 struct __optional_copy_assign_base<_Tp, false> : __optional_move_base<_Tp>
516 {
517     using __optional_move_base<_Tp>::__optional_move_base;
518
519     _LIBCPP_INLINE_VISIBILITY
520     __optional_copy_assign_base() = default;
521     _LIBCPP_INLINE_VISIBILITY
522     __optional_copy_assign_base(const __optional_copy_assign_base&) = default;
523     _LIBCPP_INLINE_VISIBILITY
524     __optional_copy_assign_base(__optional_copy_assign_base&&) = default;
525
526     _LIBCPP_INLINE_VISIBILITY
527     __optional_copy_assign_base& operator=(const __optional_copy_assign_base& __opt)
528     {
529         this->__assign_from(__opt);
530         return *this;
531     }
532
533     _LIBCPP_INLINE_VISIBILITY
534     __optional_copy_assign_base& operator=(__optional_copy_assign_base&&) = default;
535 };
536
537 template <class _Tp, bool =
538     is_trivially_destructible<_Tp>::value &&
539     is_trivially_move_constructible<_Tp>::value &&
540     is_trivially_move_assignable<_Tp>::value>
541 struct __optional_move_assign_base : __optional_copy_assign_base<_Tp>
542 {
543     using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
544 };
545
546 template <class _Tp>
547 struct __optional_move_assign_base<_Tp, false> : __optional_copy_assign_base<_Tp>
548 {
549     using value_type = _Tp;
550     using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
551
552     _LIBCPP_INLINE_VISIBILITY
553     __optional_move_assign_base() = default;
554     _LIBCPP_INLINE_VISIBILITY
555     __optional_move_assign_base(const __optional_move_assign_base& __opt) = default;
556     _LIBCPP_INLINE_VISIBILITY
557     __optional_move_assign_base(__optional_move_assign_base&&) = default;
558     _LIBCPP_INLINE_VISIBILITY
559     __optional_move_assign_base& operator=(const __optional_move_assign_base&) = default;
560
561     _LIBCPP_INLINE_VISIBILITY
562     __optional_move_assign_base& operator=(__optional_move_assign_base&& __opt)
563         noexcept(is_nothrow_move_assignable_v<value_type> &&
564                  is_nothrow_move_constructible_v<value_type>)
565     {
566         this->__assign_from(_VSTD::move(__opt));
567         return *this;
568     }
569 };
570
571 template <class _Tp>
572 using __optional_sfinae_ctor_base_t = __sfinae_ctor_base<
573     is_copy_constructible<_Tp>::value,
574     is_move_constructible<_Tp>::value
575 >;
576
577 template <class _Tp>
578 using __optional_sfinae_assign_base_t = __sfinae_assign_base<
579     (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value),
580     (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value)
581 >;
582
583 template <class _Tp>
584 class optional
585     : private __optional_move_assign_base<_Tp>
586     , private __optional_sfinae_ctor_base_t<_Tp>
587     , private __optional_sfinae_assign_base_t<_Tp>
588 {
589     using __base = __optional_move_assign_base<_Tp>;
590 public:
591     using value_type = _Tp;
592
593 private:
594      // Disable the reference extension using this static assert.
595     static_assert(!is_same_v<__uncvref_t<value_type>, in_place_t>,
596         "instantiation of optional with in_place_t is ill-formed");
597     static_assert(!is_same_v<__uncvref_t<value_type>, nullopt_t>,
598         "instantiation of optional with nullopt_t is ill-formed");
599     static_assert(!is_reference_v<value_type>,
600         "instantiation of optional with a reference type is ill-formed");
601     static_assert(is_destructible_v<value_type>,
602         "instantiation of optional with a non-destructible type is ill-formed");
603     static_assert(!is_array_v<value_type>,
604         "instantiation of optional with an array type is ill-formed");
605
606     // LWG2756: conditionally explicit conversion from _Up
607     struct _CheckOptionalArgsConstructor {
608       template <class _Up>
609       static constexpr bool __enable_implicit() {
610           return is_constructible_v<_Tp, _Up&&> &&
611                  is_convertible_v<_Up&&, _Tp>;
612       }
613
614       template <class _Up>
615       static constexpr bool __enable_explicit() {
616           return is_constructible_v<_Tp, _Up&&> &&
617                  !is_convertible_v<_Up&&, _Tp>;
618       }
619     };
620     template <class _Up>
621     using _CheckOptionalArgsCtor = _If<
622         _IsNotSame<__uncvref_t<_Up>, in_place_t>::value &&
623         _IsNotSame<__uncvref_t<_Up>, optional>::value,
624         _CheckOptionalArgsConstructor,
625         __check_tuple_constructor_fail
626     >;
627     template <class _QualUp>
628     struct _CheckOptionalLikeConstructor {
629       template <class _Up, class _Opt = optional<_Up>>
630       using __check_constructible_from_opt = _Or<
631           is_constructible<_Tp, _Opt&>,
632           is_constructible<_Tp, _Opt const&>,
633           is_constructible<_Tp, _Opt&&>,
634           is_constructible<_Tp, _Opt const&&>,
635           is_convertible<_Opt&, _Tp>,
636           is_convertible<_Opt const&, _Tp>,
637           is_convertible<_Opt&&, _Tp>,
638           is_convertible<_Opt const&&, _Tp>
639       >;
640       template <class _Up, class _Opt = optional<_Up>>
641       using __check_assignable_from_opt = _Or<
642           is_assignable<_Tp&, _Opt&>,
643           is_assignable<_Tp&, _Opt const&>,
644           is_assignable<_Tp&, _Opt&&>,
645           is_assignable<_Tp&, _Opt const&&>
646       >;
647       template <class _Up, class _QUp = _QualUp>
648       static constexpr bool __enable_implicit() {
649           return is_convertible<_QUp, _Tp>::value &&
650               !__check_constructible_from_opt<_Up>::value;
651       }
652       template <class _Up, class _QUp = _QualUp>
653       static constexpr bool __enable_explicit() {
654           return !is_convertible<_QUp, _Tp>::value &&
655               !__check_constructible_from_opt<_Up>::value;
656       }
657       template <class _Up, class _QUp = _QualUp>
658       static constexpr bool __enable_assign() {
659           // Construction and assignability of _Qup to _Tp has already been
660           // checked.
661           return !__check_constructible_from_opt<_Up>::value &&
662               !__check_assignable_from_opt<_Up>::value;
663       }
664     };
665
666     template <class _Up, class _QualUp>
667     using _CheckOptionalLikeCtor = _If<
668       _And<
669          _IsNotSame<_Up, _Tp>,
670           is_constructible<_Tp, _QualUp>
671       >::value,
672       _CheckOptionalLikeConstructor<_QualUp>,
673       __check_tuple_constructor_fail
674     >;
675     template <class _Up, class _QualUp>
676     using _CheckOptionalLikeAssign = _If<
677       _And<
678           _IsNotSame<_Up, _Tp>,
679           is_constructible<_Tp, _QualUp>,
680           is_assignable<_Tp&, _QualUp>
681       >::value,
682       _CheckOptionalLikeConstructor<_QualUp>,
683       __check_tuple_constructor_fail
684     >;
685 public:
686
687     _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
688     _LIBCPP_INLINE_VISIBILITY constexpr optional(const optional&) = default;
689     _LIBCPP_INLINE_VISIBILITY constexpr optional(optional&&) = default;
690     _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
691
692     template <class _InPlaceT, class... _Args, class = _EnableIf<
693           _And<
694               _IsSame<_InPlaceT, in_place_t>,
695               is_constructible<value_type, _Args...>
696             >::value
697         >
698     >
699     _LIBCPP_INLINE_VISIBILITY
700     constexpr explicit optional(_InPlaceT, _Args&&... __args)
701         : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
702
703     template <class _Up, class... _Args, class = _EnableIf<
704         is_constructible_v<value_type, initializer_list<_Up>&, _Args...>>
705     >
706     _LIBCPP_INLINE_VISIBILITY
707     constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
708         : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
709
710     template <class _Up = value_type, _EnableIf<
711         _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>()
712     , int> = 0>
713     _LIBCPP_INLINE_VISIBILITY
714     constexpr optional(_Up&& __v)
715         : __base(in_place, _VSTD::forward<_Up>(__v)) {}
716
717     template <class _Up, _EnableIf<
718         _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>()
719     , int> = 0>
720     _LIBCPP_INLINE_VISIBILITY
721     constexpr explicit optional(_Up&& __v)
722         : __base(in_place, _VSTD::forward<_Up>(__v)) {}
723
724     // LWG2756: conditionally explicit conversion from const optional<_Up>&
725     template <class _Up, _EnableIf<
726         _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>()
727     , int> = 0>
728     _LIBCPP_INLINE_VISIBILITY
729     optional(const optional<_Up>& __v)
730     {
731         this->__construct_from(__v);
732     }
733     template <class _Up, _EnableIf<
734         _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>()
735     , int> = 0>
736     _LIBCPP_INLINE_VISIBILITY
737     explicit optional(const optional<_Up>& __v)
738     {
739         this->__construct_from(__v);
740     }
741
742     // LWG2756: conditionally explicit conversion from optional<_Up>&&
743     template <class _Up, _EnableIf<
744         _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>()
745     , int> = 0>
746     _LIBCPP_INLINE_VISIBILITY
747     optional(optional<_Up>&& __v)
748     {
749         this->__construct_from(_VSTD::move(__v));
750     }
751     template <class _Up, _EnableIf<
752         _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>()
753     , int> = 0>
754     _LIBCPP_INLINE_VISIBILITY
755     explicit optional(optional<_Up>&& __v)
756     {
757         this->__construct_from(_VSTD::move(__v));
758     }
759
760     _LIBCPP_INLINE_VISIBILITY
761     optional& operator=(nullopt_t) noexcept
762     {
763         reset();
764         return *this;
765     }
766
767     _LIBCPP_INLINE_VISIBILITY optional& operator=(const optional&) = default;
768     _LIBCPP_INLINE_VISIBILITY optional& operator=(optional&&) = default;
769
770     // LWG2756
771     template <class _Up = value_type,
772               class = _EnableIf<
773                       _And<
774                           _IsNotSame<__uncvref_t<_Up>, optional>,
775                           _Or<
776                               _IsNotSame<__uncvref_t<_Up>, value_type>,
777                               _Not<is_scalar<value_type>>
778                           >,
779                           is_constructible<value_type, _Up>,
780                           is_assignable<value_type&, _Up>
781                       >::value>
782              >
783     _LIBCPP_INLINE_VISIBILITY
784     optional&
785     operator=(_Up&& __v)
786     {
787         if (this->has_value())
788             this->__get() = _VSTD::forward<_Up>(__v);
789         else
790             this->__construct(_VSTD::forward<_Up>(__v));
791         return *this;
792     }
793
794     // LWG2756
795     template <class _Up, _EnableIf<
796         _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>()
797     , int> = 0>
798     _LIBCPP_INLINE_VISIBILITY
799     optional&
800     operator=(const optional<_Up>& __v)
801     {
802         this->__assign_from(__v);
803         return *this;
804     }
805
806     // LWG2756
807     template <class _Up, _EnableIf<
808         _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>()
809     , int> = 0>
810     _LIBCPP_INLINE_VISIBILITY
811     optional&
812     operator=(optional<_Up>&& __v)
813     {
814         this->__assign_from(_VSTD::move(__v));
815         return *this;
816     }
817
818     template <class... _Args,
819               class = _EnableIf
820                       <
821                           is_constructible_v<value_type, _Args...>
822                       >
823              >
824     _LIBCPP_INLINE_VISIBILITY
825     _Tp &
826     emplace(_Args&&... __args)
827     {
828         reset();
829         this->__construct(_VSTD::forward<_Args>(__args)...);
830         return this->__get();
831     }
832
833     template <class _Up, class... _Args,
834               class = _EnableIf
835                       <
836                           is_constructible_v<value_type, initializer_list<_Up>&, _Args...>
837                       >
838              >
839     _LIBCPP_INLINE_VISIBILITY
840     _Tp &
841     emplace(initializer_list<_Up> __il, _Args&&... __args)
842     {
843         reset();
844         this->__construct(__il, _VSTD::forward<_Args>(__args)...);
845         return this->__get();
846     }
847
848     _LIBCPP_INLINE_VISIBILITY
849     void swap(optional& __opt)
850         noexcept(is_nothrow_move_constructible_v<value_type> &&
851                  is_nothrow_swappable_v<value_type>)
852     {
853         if (this->has_value() == __opt.has_value())
854         {
855             using _VSTD::swap;
856             if (this->has_value())
857                 swap(this->__get(), __opt.__get());
858         }
859         else
860         {
861             if (this->has_value())
862             {
863                 __opt.__construct(_VSTD::move(this->__get()));
864                 reset();
865             }
866             else
867             {
868                 this->__construct(_VSTD::move(__opt.__get()));
869                 __opt.reset();
870             }
871         }
872     }
873
874     _LIBCPP_INLINE_VISIBILITY
875     constexpr
876     add_pointer_t<value_type const>
877     operator->() const
878     {
879         _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
880 #ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
881         return _VSTD::addressof(this->__get());
882 #else
883         return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
884 #endif
885     }
886
887     _LIBCPP_INLINE_VISIBILITY
888     constexpr
889     add_pointer_t<value_type>
890     operator->()
891     {
892         _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
893 #ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
894         return _VSTD::addressof(this->__get());
895 #else
896         return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
897 #endif
898     }
899
900     _LIBCPP_INLINE_VISIBILITY
901     constexpr
902     const value_type&
903     operator*() const&
904     {
905         _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
906         return this->__get();
907     }
908
909     _LIBCPP_INLINE_VISIBILITY
910     constexpr
911     value_type&
912     operator*() &
913     {
914         _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
915         return this->__get();
916     }
917
918     _LIBCPP_INLINE_VISIBILITY
919     constexpr
920     value_type&&
921     operator*() &&
922     {
923         _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
924         return _VSTD::move(this->__get());
925     }
926
927     _LIBCPP_INLINE_VISIBILITY
928     constexpr
929     const value_type&&
930     operator*() const&&
931     {
932         _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
933         return _VSTD::move(this->__get());
934     }
935
936     _LIBCPP_INLINE_VISIBILITY
937     constexpr explicit operator bool() const noexcept { return has_value(); }
938
939     using __base::has_value;
940     using __base::__get;
941
942     _LIBCPP_INLINE_VISIBILITY
943     _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
944     constexpr value_type const& value() const&
945     {
946         if (!this->has_value())
947             __throw_bad_optional_access();
948         return this->__get();
949     }
950
951     _LIBCPP_INLINE_VISIBILITY
952     _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
953     constexpr value_type& value() &
954     {
955         if (!this->has_value())
956             __throw_bad_optional_access();
957         return this->__get();
958     }
959
960     _LIBCPP_INLINE_VISIBILITY
961     _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
962     constexpr value_type&& value() &&
963     {
964         if (!this->has_value())
965             __throw_bad_optional_access();
966         return _VSTD::move(this->__get());
967     }
968
969     _LIBCPP_INLINE_VISIBILITY
970     _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
971     constexpr value_type const&& value() const&&
972     {
973         if (!this->has_value())
974             __throw_bad_optional_access();
975         return _VSTD::move(this->__get());
976     }
977
978     template <class _Up>
979     _LIBCPP_INLINE_VISIBILITY
980     constexpr value_type value_or(_Up&& __v) const&
981     {
982         static_assert(is_copy_constructible_v<value_type>,
983                       "optional<T>::value_or: T must be copy constructible");
984         static_assert(is_convertible_v<_Up, value_type>,
985                       "optional<T>::value_or: U must be convertible to T");
986         return this->has_value() ? this->__get() :
987                                   static_cast<value_type>(_VSTD::forward<_Up>(__v));
988     }
989
990     template <class _Up>
991     _LIBCPP_INLINE_VISIBILITY
992     constexpr value_type value_or(_Up&& __v) &&
993     {
994         static_assert(is_move_constructible_v<value_type>,
995                       "optional<T>::value_or: T must be move constructible");
996         static_assert(is_convertible_v<_Up, value_type>,
997                       "optional<T>::value_or: U must be convertible to T");
998         return this->has_value() ? _VSTD::move(this->__get()) :
999                                   static_cast<value_type>(_VSTD::forward<_Up>(__v));
1000     }
1001
1002     using __base::reset;
1003
1004 private:
1005     template <class _Up>
1006     _LIBCPP_INLINE_VISIBILITY
1007     static _Up*
1008     __operator_arrow(true_type, _Up& __x)
1009     {
1010         return _VSTD::addressof(__x);
1011     }
1012
1013     template <class _Up>
1014     _LIBCPP_INLINE_VISIBILITY
1015     static constexpr _Up*
1016     __operator_arrow(false_type, _Up& __x)
1017     {
1018         return &__x;
1019     }
1020 };
1021
1022 #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
1023 template<class T>
1024     optional(T) -> optional<T>;
1025 #endif
1026
1027 // Comparisons between optionals
1028 template <class _Tp, class _Up>
1029 _LIBCPP_INLINE_VISIBILITY constexpr
1030 _EnableIf<
1031     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1032         _VSTD::declval<const _Up&>()), bool>,
1033     bool
1034 >
1035 operator==(const optional<_Tp>& __x, const optional<_Up>& __y)
1036 {
1037     if (static_cast<bool>(__x) != static_cast<bool>(__y))
1038         return false;
1039     if (!static_cast<bool>(__x))
1040         return true;
1041     return *__x == *__y;
1042 }
1043
1044 template <class _Tp, class _Up>
1045 _LIBCPP_INLINE_VISIBILITY constexpr
1046 _EnableIf<
1047     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1048         _VSTD::declval<const _Up&>()), bool>,
1049     bool
1050 >
1051 operator!=(const optional<_Tp>& __x, const optional<_Up>& __y)
1052 {
1053     if (static_cast<bool>(__x) != static_cast<bool>(__y))
1054         return true;
1055     if (!static_cast<bool>(__x))
1056         return false;
1057     return *__x != *__y;
1058 }
1059
1060 template <class _Tp, class _Up>
1061 _LIBCPP_INLINE_VISIBILITY constexpr
1062 _EnableIf<
1063     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1064         _VSTD::declval<const _Up&>()), bool>,
1065     bool
1066 >
1067 operator<(const optional<_Tp>& __x, const optional<_Up>& __y)
1068 {
1069     if (!static_cast<bool>(__y))
1070         return false;
1071     if (!static_cast<bool>(__x))
1072         return true;
1073     return *__x < *__y;
1074 }
1075
1076 template <class _Tp, class _Up>
1077 _LIBCPP_INLINE_VISIBILITY constexpr
1078 _EnableIf<
1079     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1080         _VSTD::declval<const _Up&>()), bool>,
1081     bool
1082 >
1083 operator>(const optional<_Tp>& __x, const optional<_Up>& __y)
1084 {
1085     if (!static_cast<bool>(__x))
1086         return false;
1087     if (!static_cast<bool>(__y))
1088         return true;
1089     return *__x > *__y;
1090 }
1091
1092 template <class _Tp, class _Up>
1093 _LIBCPP_INLINE_VISIBILITY constexpr
1094 _EnableIf<
1095     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1096         _VSTD::declval<const _Up&>()), bool>,
1097     bool
1098 >
1099 operator<=(const optional<_Tp>& __x, const optional<_Up>& __y)
1100 {
1101     if (!static_cast<bool>(__x))
1102         return true;
1103     if (!static_cast<bool>(__y))
1104         return false;
1105     return *__x <= *__y;
1106 }
1107
1108 template <class _Tp, class _Up>
1109 _LIBCPP_INLINE_VISIBILITY constexpr
1110 _EnableIf<
1111     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1112         _VSTD::declval<const _Up&>()), bool>,
1113     bool
1114 >
1115 operator>=(const optional<_Tp>& __x, const optional<_Up>& __y)
1116 {
1117     if (!static_cast<bool>(__y))
1118         return true;
1119     if (!static_cast<bool>(__x))
1120         return false;
1121     return *__x >= *__y;
1122 }
1123
1124 // Comparisons with nullopt
1125 template <class _Tp>
1126 _LIBCPP_INLINE_VISIBILITY constexpr
1127 bool
1128 operator==(const optional<_Tp>& __x, nullopt_t) noexcept
1129 {
1130     return !static_cast<bool>(__x);
1131 }
1132
1133 template <class _Tp>
1134 _LIBCPP_INLINE_VISIBILITY constexpr
1135 bool
1136 operator==(nullopt_t, const optional<_Tp>& __x) noexcept
1137 {
1138     return !static_cast<bool>(__x);
1139 }
1140
1141 template <class _Tp>
1142 _LIBCPP_INLINE_VISIBILITY constexpr
1143 bool
1144 operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
1145 {
1146     return static_cast<bool>(__x);
1147 }
1148
1149 template <class _Tp>
1150 _LIBCPP_INLINE_VISIBILITY constexpr
1151 bool
1152 operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
1153 {
1154     return static_cast<bool>(__x);
1155 }
1156
1157 template <class _Tp>
1158 _LIBCPP_INLINE_VISIBILITY constexpr
1159 bool
1160 operator<(const optional<_Tp>&, nullopt_t) noexcept
1161 {
1162     return false;
1163 }
1164
1165 template <class _Tp>
1166 _LIBCPP_INLINE_VISIBILITY constexpr
1167 bool
1168 operator<(nullopt_t, const optional<_Tp>& __x) noexcept
1169 {
1170     return static_cast<bool>(__x);
1171 }
1172
1173 template <class _Tp>
1174 _LIBCPP_INLINE_VISIBILITY constexpr
1175 bool
1176 operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
1177 {
1178     return !static_cast<bool>(__x);
1179 }
1180
1181 template <class _Tp>
1182 _LIBCPP_INLINE_VISIBILITY constexpr
1183 bool
1184 operator<=(nullopt_t, const optional<_Tp>&) noexcept
1185 {
1186     return true;
1187 }
1188
1189 template <class _Tp>
1190 _LIBCPP_INLINE_VISIBILITY constexpr
1191 bool
1192 operator>(const optional<_Tp>& __x, nullopt_t) noexcept
1193 {
1194     return static_cast<bool>(__x);
1195 }
1196
1197 template <class _Tp>
1198 _LIBCPP_INLINE_VISIBILITY constexpr
1199 bool
1200 operator>(nullopt_t, const optional<_Tp>&) noexcept
1201 {
1202     return false;
1203 }
1204
1205 template <class _Tp>
1206 _LIBCPP_INLINE_VISIBILITY constexpr
1207 bool
1208 operator>=(const optional<_Tp>&, nullopt_t) noexcept
1209 {
1210     return true;
1211 }
1212
1213 template <class _Tp>
1214 _LIBCPP_INLINE_VISIBILITY constexpr
1215 bool
1216 operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
1217 {
1218     return !static_cast<bool>(__x);
1219 }
1220
1221 // Comparisons with T
1222 template <class _Tp, class _Up>
1223 _LIBCPP_INLINE_VISIBILITY constexpr
1224 _EnableIf<
1225     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1226         _VSTD::declval<const _Up&>()), bool>,
1227     bool
1228 >
1229 operator==(const optional<_Tp>& __x, const _Up& __v)
1230 {
1231     return static_cast<bool>(__x) ? *__x == __v : false;
1232 }
1233
1234 template <class _Tp, class _Up>
1235 _LIBCPP_INLINE_VISIBILITY constexpr
1236 _EnableIf<
1237     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1238         _VSTD::declval<const _Up&>()), bool>,
1239     bool
1240 >
1241 operator==(const _Tp& __v, const optional<_Up>& __x)
1242 {
1243     return static_cast<bool>(__x) ? __v == *__x : false;
1244 }
1245
1246 template <class _Tp, class _Up>
1247 _LIBCPP_INLINE_VISIBILITY constexpr
1248 _EnableIf<
1249     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1250         _VSTD::declval<const _Up&>()), bool>,
1251     bool
1252 >
1253 operator!=(const optional<_Tp>& __x, const _Up& __v)
1254 {
1255     return static_cast<bool>(__x) ? *__x != __v : true;
1256 }
1257
1258 template <class _Tp, class _Up>
1259 _LIBCPP_INLINE_VISIBILITY constexpr
1260 _EnableIf<
1261     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1262         _VSTD::declval<const _Up&>()), bool>,
1263     bool
1264 >
1265 operator!=(const _Tp& __v, const optional<_Up>& __x)
1266 {
1267     return static_cast<bool>(__x) ? __v != *__x : true;
1268 }
1269
1270 template <class _Tp, class _Up>
1271 _LIBCPP_INLINE_VISIBILITY constexpr
1272 _EnableIf<
1273     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1274         _VSTD::declval<const _Up&>()), bool>,
1275     bool
1276 >
1277 operator<(const optional<_Tp>& __x, const _Up& __v)
1278 {
1279     return static_cast<bool>(__x) ? *__x < __v : true;
1280 }
1281
1282 template <class _Tp, class _Up>
1283 _LIBCPP_INLINE_VISIBILITY constexpr
1284 _EnableIf<
1285     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1286         _VSTD::declval<const _Up&>()), bool>,
1287     bool
1288 >
1289 operator<(const _Tp& __v, const optional<_Up>& __x)
1290 {
1291     return static_cast<bool>(__x) ? __v < *__x : false;
1292 }
1293
1294 template <class _Tp, class _Up>
1295 _LIBCPP_INLINE_VISIBILITY constexpr
1296 _EnableIf<
1297     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1298         _VSTD::declval<const _Up&>()), bool>,
1299     bool
1300 >
1301 operator<=(const optional<_Tp>& __x, const _Up& __v)
1302 {
1303     return static_cast<bool>(__x) ? *__x <= __v : true;
1304 }
1305
1306 template <class _Tp, class _Up>
1307 _LIBCPP_INLINE_VISIBILITY constexpr
1308 _EnableIf<
1309     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1310         _VSTD::declval<const _Up&>()), bool>,
1311     bool
1312 >
1313 operator<=(const _Tp& __v, const optional<_Up>& __x)
1314 {
1315     return static_cast<bool>(__x) ? __v <= *__x : false;
1316 }
1317
1318 template <class _Tp, class _Up>
1319 _LIBCPP_INLINE_VISIBILITY constexpr
1320 _EnableIf<
1321     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1322         _VSTD::declval<const _Up&>()), bool>,
1323     bool
1324 >
1325 operator>(const optional<_Tp>& __x, const _Up& __v)
1326 {
1327     return static_cast<bool>(__x) ? *__x > __v : false;
1328 }
1329
1330 template <class _Tp, class _Up>
1331 _LIBCPP_INLINE_VISIBILITY constexpr
1332 _EnableIf<
1333     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1334         _VSTD::declval<const _Up&>()), bool>,
1335     bool
1336 >
1337 operator>(const _Tp& __v, const optional<_Up>& __x)
1338 {
1339     return static_cast<bool>(__x) ? __v > *__x : true;
1340 }
1341
1342 template <class _Tp, class _Up>
1343 _LIBCPP_INLINE_VISIBILITY constexpr
1344 _EnableIf<
1345     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1346         _VSTD::declval<const _Up&>()), bool>,
1347     bool
1348 >
1349 operator>=(const optional<_Tp>& __x, const _Up& __v)
1350 {
1351     return static_cast<bool>(__x) ? *__x >= __v : false;
1352 }
1353
1354 template <class _Tp, class _Up>
1355 _LIBCPP_INLINE_VISIBILITY constexpr
1356 _EnableIf<
1357     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1358         _VSTD::declval<const _Up&>()), bool>,
1359     bool
1360 >
1361 operator>=(const _Tp& __v, const optional<_Up>& __x)
1362 {
1363     return static_cast<bool>(__x) ? __v >= *__x : true;
1364 }
1365
1366
1367 template <class _Tp>
1368 inline _LIBCPP_INLINE_VISIBILITY
1369 _EnableIf<
1370     is_move_constructible_v<_Tp> && is_swappable_v<_Tp>,
1371     void
1372 >
1373 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
1374 {
1375     __x.swap(__y);
1376 }
1377
1378 template <class _Tp>
1379 _LIBCPP_INLINE_VISIBILITY constexpr
1380 optional<decay_t<_Tp>> make_optional(_Tp&& __v)
1381 {
1382     return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v));
1383 }
1384
1385 template <class _Tp, class... _Args>
1386 _LIBCPP_INLINE_VISIBILITY constexpr
1387 optional<_Tp> make_optional(_Args&&... __args)
1388 {
1389     return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...);
1390 }
1391
1392 template <class _Tp, class _Up, class... _Args>
1393 _LIBCPP_INLINE_VISIBILITY constexpr
1394 optional<_Tp> make_optional(initializer_list<_Up> __il,  _Args&&... __args)
1395 {
1396     return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...);
1397 }
1398
1399 template <class _Tp>
1400 struct _LIBCPP_TEMPLATE_VIS hash<
1401     __enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>>
1402 >
1403 {
1404     typedef optional<_Tp> argument_type;
1405     typedef size_t        result_type;
1406
1407     _LIBCPP_INLINE_VISIBILITY
1408     result_type operator()(const argument_type& __opt) const
1409     {
1410         return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0;
1411     }
1412 };
1413
1414 _LIBCPP_END_NAMESPACE_STD
1415
1416 #endif  // _LIBCPP_STD_VER > 14
1417
1418 _LIBCPP_POP_MACROS
1419
1420 #endif  // _LIBCPP_OPTIONAL