]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libc++/include/experimental/optional
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r302418, and update
[FreeBSD/FreeBSD.git] / contrib / libc++ / include / experimental / optional
1 // -*- C++ -*-
2 //===-------------------------- optional ----------------------------------===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10
11 #ifndef _LIBCPP_EXPERIMENTAL_OPTIONAL
12 #define _LIBCPP_EXPERIMENTAL_OPTIONAL
13
14 /*
15     optional synopsis
16
17 // C++1y
18
19 namespace std { namespace experimental { inline namespace fundamentals_v1 {
20
21     // 5.3, optional for object types
22     template <class T> class optional;
23
24     // 5.4, In-place construction
25     struct in_place_t{};
26     constexpr in_place_t in_place{};
27
28     // 5.5, No-value state indicator
29     struct nullopt_t{see below};
30     constexpr nullopt_t nullopt(unspecified);
31
32     // 5.6, Class bad_optional_access
33     class bad_optional_access;
34
35     // 5.7, Relational operators
36     template <class T>
37       constexpr bool operator==(const optional<T>&, const optional<T>&);
38     template <class T>
39       constexpr bool operator!=(const optional<T>&, const optional<T>&);
40     template <class T>
41       constexpr bool operator<(const optional<T>&, const optional<T>&);
42     template <class T>
43       constexpr bool operator>(const optional<T>&, const optional<T>&);
44     template <class T>
45       constexpr bool operator<=(const optional<T>&, const optional<T>&);
46     template <class T>
47       constexpr bool operator>=(const optional<T>&, const optional<T>&);
48
49     // 5.8, Comparison with nullopt
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     template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept;
57     template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept;
58     template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept;
59     template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept;
60     template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept;
61     template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept;
62
63     // 5.9, Comparison with T
64     template <class T> constexpr bool operator==(const optional<T>&, const T&);
65     template <class T> constexpr bool operator==(const T&, const optional<T>&);
66     template <class T> constexpr bool operator!=(const optional<T>&, const T&);
67     template <class T> constexpr bool operator!=(const T&, const optional<T>&);
68     template <class T> constexpr bool operator<(const optional<T>&, const T&);
69     template <class T> constexpr bool operator<(const T&, const optional<T>&);
70     template <class T> constexpr bool operator<=(const optional<T>&, const T&);
71     template <class T> constexpr bool operator<=(const T&, const optional<T>&);
72     template <class T> constexpr bool operator>(const optional<T>&, const T&);
73     template <class T> constexpr bool operator>(const T&, const optional<T>&);
74     template <class T> constexpr bool operator>=(const optional<T>&, const T&);
75     template <class T> constexpr bool operator>=(const T&, const optional<T>&);
76
77     // 5.10, Specialized algorithms
78     template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below);
79     template <class T> constexpr optional<see below> make_optional(T&&);
80
81         template <class T>
82         class optional
83         {
84         public:
85           typedef T value_type;
86
87           // 5.3.1, Constructors
88           constexpr optional() noexcept;
89           constexpr optional(nullopt_t) noexcept;
90           optional(const optional&);
91           optional(optional&&) noexcept(see below);
92           constexpr optional(const T&);
93           constexpr optional(T&&);
94           template <class... Args> constexpr explicit optional(in_place_t, Args&&...);
95           template <class U, class... Args>
96                 constexpr explicit optional(in_place_t, initializer_list<U>, Args&&...);
97
98           // 5.3.2, Destructor
99           ~optional();
100
101           // 5.3.3, Assignment
102           optional& operator=(nullopt_t) noexcept;
103           optional& operator=(const optional&);
104           optional& operator=(optional&&) noexcept(see below);
105           template <class U> optional& operator=(U&&);
106           template <class... Args> void emplace(Args&&...);
107           template <class U, class... Args>
108                 void emplace(initializer_list<U>, Args&&...);
109
110           // 5.3.4, Swap
111           void swap(optional&) noexcept(see below);
112
113           // 5.3.5, Observers
114           constexpr T const* operator ->() const;
115           constexpr T* operator ->();
116           constexpr T const& operator *() const &;
117           constexpr T& operator *() &;
118           constexpr T&& operator *() &&;
119           constexpr const T&& operator *() const &&;
120           constexpr explicit operator bool() const noexcept;
121           constexpr T const& value() const &;
122           constexpr T& value() &;
123           constexpr T&& value() &&;
124           constexpr const T&& value() const &&;
125           template <class U> constexpr T value_or(U&&) const &;
126           template <class U> constexpr T value_or(U&&) &&;
127
128         private:
129           T*   val;  // exposition only
130         };
131
132   } // namespace fundamentals_v1
133   } // namespace experimental
134
135   // 5.11, Hash support
136   template <class T> struct hash;
137   template <class T> struct hash<experimental::optional<T>>;
138
139 } // namespace std
140
141 */
142
143 #include <experimental/__config>
144 #include <functional>
145 #include <stdexcept>
146
147 _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
148 class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
149     : public std::logic_error
150 {
151 public:
152         bad_optional_access() : std::logic_error("Bad optional Access") {}
153
154 //      Get the key function ~bad_optional_access() into the dylib
155     virtual ~bad_optional_access() _NOEXCEPT;
156 };
157
158 _LIBCPP_END_NAMESPACE_EXPERIMENTAL
159
160
161 #if _LIBCPP_STD_VER > 11
162
163 #include <initializer_list>
164 #include <type_traits>
165 #include <new>
166 #include <__functional_base>
167 #include <__undef_min_max>
168 #include <__debug>
169
170 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
171 #pragma GCC system_header
172 #endif
173
174 _LIBCPP_BEGIN_NAMESPACE_LFTS
175
176 struct in_place_t {};
177 constexpr in_place_t in_place{};
178
179 struct nullopt_t
180 {
181     explicit constexpr nullopt_t(int) noexcept {}
182 };
183
184 constexpr nullopt_t nullopt{0};
185
186 template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
187 class __optional_storage
188 {
189 protected:
190     typedef _Tp value_type;
191     union
192     {
193         char __null_state_;
194         value_type __val_;
195     };
196     bool __engaged_ = false;
197
198     _LIBCPP_INLINE_VISIBILITY
199     ~__optional_storage()
200     {
201         if (__engaged_)
202             __val_.~value_type();
203     }
204
205     _LIBCPP_INLINE_VISIBILITY
206     constexpr __optional_storage() noexcept
207         :  __null_state_('\0') {}
208
209     _LIBCPP_INLINE_VISIBILITY
210     __optional_storage(const __optional_storage& __x)
211         :  __engaged_(__x.__engaged_)
212         {
213             if (__engaged_)
214                 ::new((void*)_VSTD::addressof(__val_)) value_type(__x.__val_);
215         }
216
217     _LIBCPP_INLINE_VISIBILITY
218     __optional_storage(__optional_storage&& __x)
219                       noexcept(is_nothrow_move_constructible<value_type>::value)
220         :  __engaged_(__x.__engaged_)
221         {
222             if (__engaged_)
223                 ::new((void*)_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_));
224         }
225
226     _LIBCPP_INLINE_VISIBILITY
227     constexpr __optional_storage(const value_type& __v)
228         :  __val_(__v),
229            __engaged_(true) {}
230
231     _LIBCPP_INLINE_VISIBILITY
232     constexpr __optional_storage(value_type&& __v)
233         :  __val_(_VSTD::move(__v)),
234            __engaged_(true) {}
235
236     template <class... _Args>
237     _LIBCPP_INLINE_VISIBILITY
238     constexpr
239     explicit __optional_storage(in_place_t, _Args&&... __args)
240        :  __val_(_VSTD::forward<_Args>(__args)...),
241            __engaged_(true) {}
242 };
243
244 template <class _Tp>
245 class __optional_storage<_Tp, true>
246 {
247 protected:
248     typedef _Tp value_type;
249     union
250     {
251         char __null_state_;
252         value_type __val_;
253     };
254     bool __engaged_ = false;
255
256     _LIBCPP_INLINE_VISIBILITY
257     constexpr __optional_storage() noexcept
258         :  __null_state_('\0') {}
259
260     _LIBCPP_INLINE_VISIBILITY
261     __optional_storage(const __optional_storage& __x)
262         :  __engaged_(__x.__engaged_)
263         {
264             if (__engaged_)
265                 ::new((void*)_VSTD::addressof(__val_)) value_type(__x.__val_);
266         }
267
268     _LIBCPP_INLINE_VISIBILITY
269     __optional_storage(__optional_storage&& __x)
270                       noexcept(is_nothrow_move_constructible<value_type>::value)
271         :  __engaged_(__x.__engaged_)
272         {
273             if (__engaged_)
274                 ::new((void*)_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_));
275         }
276
277     _LIBCPP_INLINE_VISIBILITY
278     constexpr __optional_storage(const value_type& __v)
279         :  __val_(__v),
280            __engaged_(true) {}
281
282     _LIBCPP_INLINE_VISIBILITY
283     constexpr __optional_storage(value_type&& __v)
284         :  __val_(_VSTD::move(__v)),
285            __engaged_(true) {}
286
287     template <class... _Args>
288     _LIBCPP_INLINE_VISIBILITY
289     constexpr
290     explicit __optional_storage(in_place_t, _Args&&... __args)
291        :  __val_(_VSTD::forward<_Args>(__args)...),
292            __engaged_(true) {}
293 };
294
295 template <class _Tp>
296 class optional
297     : private __optional_storage<_Tp>
298 {
299     typedef __optional_storage<_Tp> __base;
300 public:
301     typedef _Tp value_type;
302
303     static_assert(!is_reference<value_type>::value,
304               "Instantiation of optional with a reference type is ill-formed.");
305     static_assert(!is_same<typename remove_cv<value_type>::type, in_place_t>::value,
306               "Instantiation of optional with a in_place_t type is ill-formed.");
307     static_assert(!is_same<typename remove_cv<value_type>::type, nullopt_t>::value,
308               "Instantiation of optional with a nullopt_t type is ill-formed.");
309     static_assert(is_object<value_type>::value,
310         "Instantiation of optional with a non-object type is undefined behavior.");
311     static_assert(is_nothrow_destructible<value_type>::value,
312         "Instantiation of optional with an object type that is not noexcept destructible is undefined behavior.");
313
314     _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
315     _LIBCPP_INLINE_VISIBILITY optional(const optional&) = default;
316     _LIBCPP_INLINE_VISIBILITY optional(optional&&) = default;
317     _LIBCPP_INLINE_VISIBILITY ~optional() = default;
318     _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
319     _LIBCPP_INLINE_VISIBILITY constexpr optional(const value_type& __v)
320         : __base(__v) {}
321     _LIBCPP_INLINE_VISIBILITY constexpr optional(value_type&& __v)
322         : __base(_VSTD::move(__v)) {}
323
324     template <class... _Args,
325               class = typename enable_if
326                       <
327                            is_constructible<value_type, _Args...>::value
328                       >::type
329              >
330     _LIBCPP_INLINE_VISIBILITY
331     constexpr
332     explicit optional(in_place_t, _Args&&... __args)
333         : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
334
335     template <class _Up, class... _Args,
336               class = typename enable_if
337                       <
338                            is_constructible<value_type, initializer_list<_Up>&, _Args...>::value
339                       >::type
340              >
341     _LIBCPP_INLINE_VISIBILITY
342     constexpr
343     explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
344         : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
345
346     _LIBCPP_INLINE_VISIBILITY
347     optional& operator=(nullopt_t) noexcept
348     {
349         if (this->__engaged_)
350         {
351             this->__val_.~value_type();
352             this->__engaged_ = false;
353         }
354         return *this;
355     }
356
357     _LIBCPP_INLINE_VISIBILITY
358     optional&
359     operator=(const optional& __opt)
360     {
361         if (this->__engaged_ == __opt.__engaged_)
362         {
363             if (this->__engaged_)
364                 this->__val_ = __opt.__val_;
365         }
366         else
367         {
368             if (this->__engaged_)
369                 this->__val_.~value_type();
370             else
371                 ::new((void*)_VSTD::addressof(this->__val_)) value_type(__opt.__val_);
372             this->__engaged_ = __opt.__engaged_;
373         }
374         return *this;
375     }
376
377     _LIBCPP_INLINE_VISIBILITY
378     optional&
379     operator=(optional&& __opt)
380         noexcept(is_nothrow_move_assignable<value_type>::value &&
381                  is_nothrow_move_constructible<value_type>::value)
382     {
383         if (this->__engaged_ == __opt.__engaged_)
384         {
385             if (this->__engaged_)
386                 this->__val_ = _VSTD::move(__opt.__val_);
387         }
388         else
389         {
390             if (this->__engaged_)
391                 this->__val_.~value_type();
392             else
393                 ::new((void*)_VSTD::addressof(this->__val_))
394                     value_type(_VSTD::move(__opt.__val_));
395             this->__engaged_ = __opt.__engaged_;
396         }
397         return *this;
398     }
399
400     template <class _Up,
401               class = typename enable_if
402                       <
403                           is_same<typename remove_reference<_Up>::type, value_type>::value &&
404                           is_constructible<value_type, _Up>::value &&
405                           is_assignable<value_type&, _Up>::value
406                       >::type
407              >
408     _LIBCPP_INLINE_VISIBILITY
409     optional&
410     operator=(_Up&& __v)
411     {
412         if (this->__engaged_)
413             this->__val_ = _VSTD::forward<_Up>(__v);
414         else
415         {
416             ::new((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Up>(__v));
417             this->__engaged_ = true;
418         }
419         return *this;
420     }
421
422     template <class... _Args,
423               class = typename enable_if
424                       <
425                           is_constructible<value_type, _Args...>::value
426                       >::type
427              >
428     _LIBCPP_INLINE_VISIBILITY
429     void
430     emplace(_Args&&... __args)
431     {
432         *this = nullopt;
433         ::new((void*)_VSTD::addressof(this->__val_))
434             value_type(_VSTD::forward<_Args>(__args)...);
435         this->__engaged_ = true;
436     }
437
438     template <class _Up, class... _Args,
439               class = typename enable_if
440                       <
441                           is_constructible<value_type, initializer_list<_Up>&, _Args...>::value
442                       >::type
443              >
444     _LIBCPP_INLINE_VISIBILITY
445     void
446     emplace(initializer_list<_Up> __il, _Args&&... __args)
447     {
448         *this = nullopt;
449         ::new((void*)_VSTD::addressof(this->__val_))
450             value_type(__il, _VSTD::forward<_Args>(__args)...);
451         this->__engaged_ = true;
452     }
453
454     _LIBCPP_INLINE_VISIBILITY
455     void
456     swap(optional& __opt)
457         noexcept(is_nothrow_move_constructible<value_type>::value &&
458                  __is_nothrow_swappable<value_type>::value)
459     {
460         using _VSTD::swap;
461         if (this->__engaged_ == __opt.__engaged_)
462         {
463             if (this->__engaged_)
464                 swap(this->__val_, __opt.__val_);
465         }
466         else
467         {
468             if (this->__engaged_)
469             {
470                 ::new((void*)_VSTD::addressof(__opt.__val_))
471                     value_type(_VSTD::move(this->__val_));
472                 this->__val_.~value_type();
473             }
474             else
475             {
476                 ::new((void*)_VSTD::addressof(this->__val_))
477                     value_type(_VSTD::move(__opt.__val_));
478                 __opt.__val_.~value_type();
479             }
480             swap(this->__engaged_, __opt.__engaged_);
481         }
482     }
483
484     _LIBCPP_INLINE_VISIBILITY
485     constexpr
486     value_type const*
487     operator->() const
488     {
489         _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
490 #ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
491         return __builtin_addressof(this->__val_);
492 #else
493         return __operator_arrow(__has_operator_addressof<value_type>{});
494 #endif
495     }
496
497     _LIBCPP_INLINE_VISIBILITY
498     value_type*
499     operator->()
500     {
501         _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
502         return _VSTD::addressof(this->__val_);
503     }
504
505     _LIBCPP_INLINE_VISIBILITY
506     constexpr
507     const value_type&
508     operator*() const
509     {
510         _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
511         return this->__val_;
512     }
513
514     _LIBCPP_INLINE_VISIBILITY
515     value_type&
516     operator*()
517     {
518         _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
519         return this->__val_;
520     }
521
522     _LIBCPP_INLINE_VISIBILITY
523     constexpr explicit operator bool() const noexcept {return this->__engaged_;}
524
525         _LIBCPP_NORETURN _LIBCPP_INLINE_VISIBILITY 
526 #ifndef _LIBCPP_NO_EXCEPTIONS
527 _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
528 #endif
529         constexpr void __throw_bad_optional_access() const
530         {
531 #ifndef _LIBCPP_NO_EXCEPTIONS
532         throw bad_optional_access();
533 #else
534         _VSTD::abort();
535 #endif
536         }
537         
538     _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
539     constexpr value_type const& value() const
540     {
541         if (!this->__engaged_)
542             __throw_bad_optional_access();
543         return this->__val_;
544     }
545
546     _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
547     value_type& value()
548     {
549         if (!this->__engaged_)
550             __throw_bad_optional_access();
551         return this->__val_;
552     }
553
554     template <class _Up>
555     _LIBCPP_INLINE_VISIBILITY
556     constexpr value_type value_or(_Up&& __v) const&
557     {
558         static_assert(is_copy_constructible<value_type>::value,
559                       "optional<T>::value_or: T must be copy constructible");
560         static_assert(is_convertible<_Up, value_type>::value,
561                       "optional<T>::value_or: U must be convertible to T");
562         return this->__engaged_ ? this->__val_ :
563                                   static_cast<value_type>(_VSTD::forward<_Up>(__v));
564     }
565
566     template <class _Up>
567     _LIBCPP_INLINE_VISIBILITY
568     value_type value_or(_Up&& __v) &&
569     {
570         static_assert(is_move_constructible<value_type>::value,
571                       "optional<T>::value_or: T must be move constructible");
572         static_assert(is_convertible<_Up, value_type>::value,
573                       "optional<T>::value_or: U must be convertible to T");
574         return this->__engaged_ ? _VSTD::move(this->__val_) :
575                                   static_cast<value_type>(_VSTD::forward<_Up>(__v));
576     }
577
578 private:
579     _LIBCPP_INLINE_VISIBILITY
580     value_type const*
581     __operator_arrow(true_type) const
582     {
583         return _VSTD::addressof(this->__val_);
584     }
585
586     _LIBCPP_INLINE_VISIBILITY
587     constexpr
588     value_type const*
589     __operator_arrow(false_type) const
590     {
591         return &this->__val_;
592     }
593 };
594
595 // Comparisons between optionals
596 template <class _Tp>
597 inline _LIBCPP_INLINE_VISIBILITY
598 constexpr
599 bool
600 operator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
601 {
602     if (static_cast<bool>(__x) != static_cast<bool>(__y))
603         return false;
604     if (!static_cast<bool>(__x))
605         return true;
606     return *__x == *__y;
607 }
608
609 template <class _Tp>
610 inline _LIBCPP_INLINE_VISIBILITY
611 constexpr
612 bool
613 operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y)
614 {
615     return !(__x == __y);
616 }
617
618 template <class _Tp>
619 inline _LIBCPP_INLINE_VISIBILITY
620 constexpr
621 bool
622 operator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
623 {
624     if (!static_cast<bool>(__y))
625         return false;
626     if (!static_cast<bool>(__x))
627         return true;
628     return *__x < *__y;
629 }
630
631 template <class _Tp>
632 inline _LIBCPP_INLINE_VISIBILITY
633 constexpr
634 bool
635 operator>(const optional<_Tp>& __x, const optional<_Tp>& __y)
636 {
637     return __y < __x;
638 }
639
640 template <class _Tp>
641 inline _LIBCPP_INLINE_VISIBILITY
642 constexpr
643 bool
644 operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y)
645 {
646     return !(__y < __x);
647 }
648
649 template <class _Tp>
650 inline _LIBCPP_INLINE_VISIBILITY
651 constexpr
652 bool
653 operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y)
654 {
655     return !(__x < __y);
656 }
657
658
659 // Comparisons with nullopt
660 template <class _Tp>
661 inline _LIBCPP_INLINE_VISIBILITY
662 constexpr
663 bool
664 operator==(const optional<_Tp>& __x, nullopt_t) noexcept
665 {
666     return !static_cast<bool>(__x);
667 }
668
669 template <class _Tp>
670 inline _LIBCPP_INLINE_VISIBILITY
671 constexpr
672 bool
673 operator==(nullopt_t, const optional<_Tp>& __x) noexcept
674 {
675     return !static_cast<bool>(__x);
676 }
677
678 template <class _Tp>
679 inline _LIBCPP_INLINE_VISIBILITY
680 constexpr
681 bool
682 operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
683 {
684     return static_cast<bool>(__x);
685 }
686
687 template <class _Tp>
688 inline _LIBCPP_INLINE_VISIBILITY
689 constexpr
690 bool
691 operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
692 {
693     return static_cast<bool>(__x);
694 }
695
696 template <class _Tp>
697 inline _LIBCPP_INLINE_VISIBILITY
698 constexpr
699 bool
700 operator<(const optional<_Tp>&, nullopt_t) noexcept
701 {
702     return false;
703 }
704
705 template <class _Tp>
706 inline _LIBCPP_INLINE_VISIBILITY
707 constexpr
708 bool
709 operator<(nullopt_t, const optional<_Tp>& __x) noexcept
710 {
711     return static_cast<bool>(__x);
712 }
713
714 template <class _Tp>
715 inline _LIBCPP_INLINE_VISIBILITY
716 constexpr
717 bool
718 operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
719 {
720     return !static_cast<bool>(__x);
721 }
722
723 template <class _Tp>
724 inline _LIBCPP_INLINE_VISIBILITY
725 constexpr
726 bool
727 operator<=(nullopt_t, const optional<_Tp>&) noexcept
728 {
729     return true;
730 }
731
732 template <class _Tp>
733 inline _LIBCPP_INLINE_VISIBILITY
734 constexpr
735 bool
736 operator>(const optional<_Tp>& __x, nullopt_t) noexcept
737 {
738     return static_cast<bool>(__x);
739 }
740
741 template <class _Tp>
742 inline _LIBCPP_INLINE_VISIBILITY
743 constexpr
744 bool
745 operator>(nullopt_t, const optional<_Tp>&) noexcept
746 {
747     return false;
748 }
749
750 template <class _Tp>
751 inline _LIBCPP_INLINE_VISIBILITY
752 constexpr
753 bool
754 operator>=(const optional<_Tp>&, nullopt_t) noexcept
755 {
756     return true;
757 }
758
759 template <class _Tp>
760 inline _LIBCPP_INLINE_VISIBILITY
761 constexpr
762 bool
763 operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
764 {
765     return !static_cast<bool>(__x);
766 }
767
768 // Comparisons with T
769 template <class _Tp>
770 inline _LIBCPP_INLINE_VISIBILITY
771 constexpr
772 bool
773 operator==(const optional<_Tp>& __x, const _Tp& __v)
774 {
775     return static_cast<bool>(__x) ? *__x == __v : false;
776 }
777
778 template <class _Tp>
779 inline _LIBCPP_INLINE_VISIBILITY
780 constexpr
781 bool
782 operator==(const _Tp& __v, const optional<_Tp>& __x)
783 {
784     return static_cast<bool>(__x) ? *__x == __v : false;
785 }
786
787 template <class _Tp>
788 inline _LIBCPP_INLINE_VISIBILITY
789 constexpr
790 bool
791 operator!=(const optional<_Tp>& __x, const _Tp& __v)
792 {
793     return static_cast<bool>(__x) ? !(*__x == __v) : true;
794 }
795
796 template <class _Tp>
797 inline _LIBCPP_INLINE_VISIBILITY
798 constexpr
799 bool
800 operator!=(const _Tp& __v, const optional<_Tp>& __x)
801 {
802     return static_cast<bool>(__x) ? !(*__x == __v) : true;
803 }
804
805 template <class _Tp>
806 inline _LIBCPP_INLINE_VISIBILITY
807 constexpr
808 bool
809 operator<(const optional<_Tp>& __x, const _Tp& __v)
810 {
811     return static_cast<bool>(__x) ? less<_Tp>{}(*__x, __v) : true;
812 }
813
814 template <class _Tp>
815 inline _LIBCPP_INLINE_VISIBILITY
816 constexpr
817 bool
818 operator<(const _Tp& __v, const optional<_Tp>& __x)
819 {
820     return static_cast<bool>(__x) ? less<_Tp>{}(__v, *__x) : false;
821 }
822
823 template <class _Tp>
824 inline _LIBCPP_INLINE_VISIBILITY
825 constexpr
826 bool
827 operator<=(const optional<_Tp>& __x, const _Tp& __v)
828 {
829     return !(__x > __v);
830 }
831
832 template <class _Tp>
833 inline _LIBCPP_INLINE_VISIBILITY
834 constexpr
835 bool
836 operator<=(const _Tp& __v, const optional<_Tp>& __x)
837 {
838     return !(__v > __x);
839 }
840
841 template <class _Tp>
842 inline _LIBCPP_INLINE_VISIBILITY
843 constexpr
844 bool
845 operator>(const optional<_Tp>& __x, const _Tp& __v)
846 {
847     return static_cast<bool>(__x) ? __v < __x : false;
848 }
849
850 template <class _Tp>
851 inline _LIBCPP_INLINE_VISIBILITY
852 constexpr
853 bool
854 operator>(const _Tp& __v, const optional<_Tp>& __x)
855 {
856     return static_cast<bool>(__x) ? __x < __v : true;
857 }
858
859 template <class _Tp>
860 inline _LIBCPP_INLINE_VISIBILITY
861 constexpr
862 bool
863 operator>=(const optional<_Tp>& __x, const _Tp& __v)
864 {
865     return !(__x < __v);
866 }
867
868 template <class _Tp>
869 inline _LIBCPP_INLINE_VISIBILITY
870 constexpr
871 bool
872 operator>=(const _Tp& __v, const optional<_Tp>& __x)
873 {
874     return !(__v < __x);
875 }
876
877
878 template <class _Tp>
879 inline _LIBCPP_INLINE_VISIBILITY
880 void
881 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
882 {
883     __x.swap(__y);
884 }
885
886 template <class _Tp>
887 inline _LIBCPP_INLINE_VISIBILITY
888 constexpr
889 optional<typename decay<_Tp>::type>
890 make_optional(_Tp&& __v)
891 {
892     return optional<typename decay<_Tp>::type>(_VSTD::forward<_Tp>(__v));
893 }
894
895 _LIBCPP_END_NAMESPACE_LFTS
896
897 _LIBCPP_BEGIN_NAMESPACE_STD
898
899 template <class _Tp>
900 struct _LIBCPP_TEMPLATE_VIS hash<std::experimental::optional<_Tp> >
901 {
902     typedef std::experimental::optional<_Tp> argument_type;
903     typedef size_t        result_type;
904
905     _LIBCPP_INLINE_VISIBILITY
906     result_type operator()(const argument_type& __opt) const _NOEXCEPT
907     {
908         return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0;
909     }
910 };
911
912 _LIBCPP_END_NAMESPACE_STD
913
914 #endif  // _LIBCPP_STD_VER > 11
915
916 #endif  // _LIBCPP_EXPERIMENTAL_OPTIONAL