]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libc++/include/experimental/optional
Merge libc++ r291274, and update the library Makefile.
[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 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         constexpr void __throw_bad_optional_access() const
527         {
528 #ifndef _LIBCPP_NO_EXCEPTIONS
529         throw bad_optional_access();
530 #else
531         _VSTD::abort();
532 #endif
533         }
534         
535     _LIBCPP_INLINE_VISIBILITY
536     constexpr value_type const& value() const
537     {
538         if (!this->__engaged_)
539             __throw_bad_optional_access();
540         return this->__val_;
541     }
542
543     _LIBCPP_INLINE_VISIBILITY
544     value_type& value()
545     {
546         if (!this->__engaged_)
547             __throw_bad_optional_access();
548         return this->__val_;
549     }
550
551     template <class _Up>
552     _LIBCPP_INLINE_VISIBILITY
553     constexpr value_type value_or(_Up&& __v) const&
554     {
555         static_assert(is_copy_constructible<value_type>::value,
556                       "optional<T>::value_or: T must be copy constructible");
557         static_assert(is_convertible<_Up, value_type>::value,
558                       "optional<T>::value_or: U must be convertible to T");
559         return this->__engaged_ ? this->__val_ :
560                                   static_cast<value_type>(_VSTD::forward<_Up>(__v));
561     }
562
563     template <class _Up>
564     _LIBCPP_INLINE_VISIBILITY
565     value_type value_or(_Up&& __v) &&
566     {
567         static_assert(is_move_constructible<value_type>::value,
568                       "optional<T>::value_or: T must be move constructible");
569         static_assert(is_convertible<_Up, value_type>::value,
570                       "optional<T>::value_or: U must be convertible to T");
571         return this->__engaged_ ? _VSTD::move(this->__val_) :
572                                   static_cast<value_type>(_VSTD::forward<_Up>(__v));
573     }
574
575 private:
576     _LIBCPP_INLINE_VISIBILITY
577     value_type const*
578     __operator_arrow(true_type) const
579     {
580         return _VSTD::addressof(this->__val_);
581     }
582
583     _LIBCPP_INLINE_VISIBILITY
584     constexpr
585     value_type const*
586     __operator_arrow(false_type) const
587     {
588         return &this->__val_;
589     }
590 };
591
592 // Comparisons between optionals
593 template <class _Tp>
594 inline _LIBCPP_INLINE_VISIBILITY
595 constexpr
596 bool
597 operator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
598 {
599     if (static_cast<bool>(__x) != static_cast<bool>(__y))
600         return false;
601     if (!static_cast<bool>(__x))
602         return true;
603     return *__x == *__y;
604 }
605
606 template <class _Tp>
607 inline _LIBCPP_INLINE_VISIBILITY
608 constexpr
609 bool
610 operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y)
611 {
612     return !(__x == __y);
613 }
614
615 template <class _Tp>
616 inline _LIBCPP_INLINE_VISIBILITY
617 constexpr
618 bool
619 operator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
620 {
621     if (!static_cast<bool>(__y))
622         return false;
623     if (!static_cast<bool>(__x))
624         return true;
625     return *__x < *__y;
626 }
627
628 template <class _Tp>
629 inline _LIBCPP_INLINE_VISIBILITY
630 constexpr
631 bool
632 operator>(const optional<_Tp>& __x, const optional<_Tp>& __y)
633 {
634     return __y < __x;
635 }
636
637 template <class _Tp>
638 inline _LIBCPP_INLINE_VISIBILITY
639 constexpr
640 bool
641 operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y)
642 {
643     return !(__y < __x);
644 }
645
646 template <class _Tp>
647 inline _LIBCPP_INLINE_VISIBILITY
648 constexpr
649 bool
650 operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y)
651 {
652     return !(__x < __y);
653 }
654
655
656 // Comparisons with nullopt
657 template <class _Tp>
658 inline _LIBCPP_INLINE_VISIBILITY
659 constexpr
660 bool
661 operator==(const optional<_Tp>& __x, nullopt_t) noexcept
662 {
663     return !static_cast<bool>(__x);
664 }
665
666 template <class _Tp>
667 inline _LIBCPP_INLINE_VISIBILITY
668 constexpr
669 bool
670 operator==(nullopt_t, const optional<_Tp>& __x) noexcept
671 {
672     return !static_cast<bool>(__x);
673 }
674
675 template <class _Tp>
676 inline _LIBCPP_INLINE_VISIBILITY
677 constexpr
678 bool
679 operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
680 {
681     return static_cast<bool>(__x);
682 }
683
684 template <class _Tp>
685 inline _LIBCPP_INLINE_VISIBILITY
686 constexpr
687 bool
688 operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
689 {
690     return static_cast<bool>(__x);
691 }
692
693 template <class _Tp>
694 inline _LIBCPP_INLINE_VISIBILITY
695 constexpr
696 bool
697 operator<(const optional<_Tp>&, nullopt_t) noexcept
698 {
699     return false;
700 }
701
702 template <class _Tp>
703 inline _LIBCPP_INLINE_VISIBILITY
704 constexpr
705 bool
706 operator<(nullopt_t, const optional<_Tp>& __x) noexcept
707 {
708     return static_cast<bool>(__x);
709 }
710
711 template <class _Tp>
712 inline _LIBCPP_INLINE_VISIBILITY
713 constexpr
714 bool
715 operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
716 {
717     return !static_cast<bool>(__x);
718 }
719
720 template <class _Tp>
721 inline _LIBCPP_INLINE_VISIBILITY
722 constexpr
723 bool
724 operator<=(nullopt_t, const optional<_Tp>&) noexcept
725 {
726     return true;
727 }
728
729 template <class _Tp>
730 inline _LIBCPP_INLINE_VISIBILITY
731 constexpr
732 bool
733 operator>(const optional<_Tp>& __x, nullopt_t) noexcept
734 {
735     return static_cast<bool>(__x);
736 }
737
738 template <class _Tp>
739 inline _LIBCPP_INLINE_VISIBILITY
740 constexpr
741 bool
742 operator>(nullopt_t, const optional<_Tp>&) noexcept
743 {
744     return false;
745 }
746
747 template <class _Tp>
748 inline _LIBCPP_INLINE_VISIBILITY
749 constexpr
750 bool
751 operator>=(const optional<_Tp>&, nullopt_t) noexcept
752 {
753     return true;
754 }
755
756 template <class _Tp>
757 inline _LIBCPP_INLINE_VISIBILITY
758 constexpr
759 bool
760 operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
761 {
762     return !static_cast<bool>(__x);
763 }
764
765 // Comparisons with T
766 template <class _Tp>
767 inline _LIBCPP_INLINE_VISIBILITY
768 constexpr
769 bool
770 operator==(const optional<_Tp>& __x, const _Tp& __v)
771 {
772     return static_cast<bool>(__x) ? *__x == __v : false;
773 }
774
775 template <class _Tp>
776 inline _LIBCPP_INLINE_VISIBILITY
777 constexpr
778 bool
779 operator==(const _Tp& __v, const optional<_Tp>& __x)
780 {
781     return static_cast<bool>(__x) ? *__x == __v : false;
782 }
783
784 template <class _Tp>
785 inline _LIBCPP_INLINE_VISIBILITY
786 constexpr
787 bool
788 operator!=(const optional<_Tp>& __x, const _Tp& __v)
789 {
790     return static_cast<bool>(__x) ? !(*__x == __v) : true;
791 }
792
793 template <class _Tp>
794 inline _LIBCPP_INLINE_VISIBILITY
795 constexpr
796 bool
797 operator!=(const _Tp& __v, const optional<_Tp>& __x)
798 {
799     return static_cast<bool>(__x) ? !(*__x == __v) : true;
800 }
801
802 template <class _Tp>
803 inline _LIBCPP_INLINE_VISIBILITY
804 constexpr
805 bool
806 operator<(const optional<_Tp>& __x, const _Tp& __v)
807 {
808     return static_cast<bool>(__x) ? less<_Tp>{}(*__x, __v) : true;
809 }
810
811 template <class _Tp>
812 inline _LIBCPP_INLINE_VISIBILITY
813 constexpr
814 bool
815 operator<(const _Tp& __v, const optional<_Tp>& __x)
816 {
817     return static_cast<bool>(__x) ? less<_Tp>{}(__v, *__x) : false;
818 }
819
820 template <class _Tp>
821 inline _LIBCPP_INLINE_VISIBILITY
822 constexpr
823 bool
824 operator<=(const optional<_Tp>& __x, const _Tp& __v)
825 {
826     return !(__x > __v);
827 }
828
829 template <class _Tp>
830 inline _LIBCPP_INLINE_VISIBILITY
831 constexpr
832 bool
833 operator<=(const _Tp& __v, const optional<_Tp>& __x)
834 {
835     return !(__v > __x);
836 }
837
838 template <class _Tp>
839 inline _LIBCPP_INLINE_VISIBILITY
840 constexpr
841 bool
842 operator>(const optional<_Tp>& __x, const _Tp& __v)
843 {
844     return static_cast<bool>(__x) ? __v < __x : false;
845 }
846
847 template <class _Tp>
848 inline _LIBCPP_INLINE_VISIBILITY
849 constexpr
850 bool
851 operator>(const _Tp& __v, const optional<_Tp>& __x)
852 {
853     return static_cast<bool>(__x) ? __x < __v : true;
854 }
855
856 template <class _Tp>
857 inline _LIBCPP_INLINE_VISIBILITY
858 constexpr
859 bool
860 operator>=(const optional<_Tp>& __x, const _Tp& __v)
861 {
862     return !(__x < __v);
863 }
864
865 template <class _Tp>
866 inline _LIBCPP_INLINE_VISIBILITY
867 constexpr
868 bool
869 operator>=(const _Tp& __v, const optional<_Tp>& __x)
870 {
871     return !(__v < __x);
872 }
873
874
875 template <class _Tp>
876 inline _LIBCPP_INLINE_VISIBILITY
877 void
878 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
879 {
880     __x.swap(__y);
881 }
882
883 template <class _Tp>
884 inline _LIBCPP_INLINE_VISIBILITY
885 constexpr
886 optional<typename decay<_Tp>::type>
887 make_optional(_Tp&& __v)
888 {
889     return optional<typename decay<_Tp>::type>(_VSTD::forward<_Tp>(__v));
890 }
891
892 _LIBCPP_END_NAMESPACE_LFTS
893
894 _LIBCPP_BEGIN_NAMESPACE_STD
895
896 template <class _Tp>
897 struct _LIBCPP_TEMPLATE_VIS hash<std::experimental::optional<_Tp> >
898 {
899     typedef std::experimental::optional<_Tp> argument_type;
900     typedef size_t        result_type;
901
902     _LIBCPP_INLINE_VISIBILITY
903     result_type operator()(const argument_type& __opt) const _NOEXCEPT
904     {
905         return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0;
906     }
907 };
908
909 _LIBCPP_END_NAMESPACE_STD
910
911 #endif  // _LIBCPP_STD_VER > 11
912
913 #endif  // _LIBCPP_EXPERIMENTAL_OPTIONAL