]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libc++/include/experimental/optional
MFC r309362:
[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_OPTIONAL
12 #define _LIBCPP_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(_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(_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(_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(_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(_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(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_));
394             this->__engaged_ = __opt.__engaged_;
395         }
396         return *this;
397     }
398
399     template <class _Up,
400               class = typename enable_if
401                       <
402                           is_same<typename remove_reference<_Up>::type, value_type>::value &&
403                           is_constructible<value_type, _Up>::value &&
404                           is_assignable<value_type&, _Up>::value
405                       >::type
406              >
407     _LIBCPP_INLINE_VISIBILITY
408     optional&
409     operator=(_Up&& __v)
410     {
411         if (this->__engaged_)
412             this->__val_ = _VSTD::forward<_Up>(__v);
413         else
414         {
415             ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Up>(__v));
416             this->__engaged_ = true;
417         }
418         return *this;
419     }
420
421     template <class... _Args,
422               class = typename enable_if
423                       <
424                           is_constructible<value_type, _Args...>::value
425                       >::type
426              >
427     _LIBCPP_INLINE_VISIBILITY
428     void
429     emplace(_Args&&... __args)
430     {
431         *this = nullopt;
432         ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
433         this->__engaged_ = true;
434     }
435
436     template <class _Up, class... _Args,
437               class = typename enable_if
438                       <
439                           is_constructible<value_type, initializer_list<_Up>&, _Args...>::value
440                       >::type
441              >
442     _LIBCPP_INLINE_VISIBILITY
443     void
444     emplace(initializer_list<_Up> __il, _Args&&... __args)
445     {
446         *this = nullopt;
447         ::new(_VSTD::addressof(this->__val_)) value_type(__il, _VSTD::forward<_Args>(__args)...);
448         this->__engaged_ = true;
449     }
450
451     _LIBCPP_INLINE_VISIBILITY
452     void
453     swap(optional& __opt)
454         noexcept(is_nothrow_move_constructible<value_type>::value &&
455                  __is_nothrow_swappable<value_type>::value)
456     {
457         using _VSTD::swap;
458         if (this->__engaged_ == __opt.__engaged_)
459         {
460             if (this->__engaged_)
461                 swap(this->__val_, __opt.__val_);
462         }
463         else
464         {
465             if (this->__engaged_)
466             {
467                 ::new(_VSTD::addressof(__opt.__val_)) value_type(_VSTD::move(this->__val_));
468                 this->__val_.~value_type();
469             }
470             else
471             {
472                 ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_));
473                 __opt.__val_.~value_type();
474             }
475             swap(this->__engaged_, __opt.__engaged_);
476         }
477     }
478
479     _LIBCPP_INLINE_VISIBILITY
480     constexpr
481     value_type const*
482     operator->() const
483     {
484         _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
485         return __operator_arrow(__has_operator_addressof<value_type>{});
486     }
487
488     _LIBCPP_INLINE_VISIBILITY
489     value_type*
490     operator->()
491     {
492         _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
493         return _VSTD::addressof(this->__val_);
494     }
495
496     _LIBCPP_INLINE_VISIBILITY
497     constexpr
498     const value_type&
499     operator*() const
500     {
501         _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
502         return this->__val_;
503     }
504
505     _LIBCPP_INLINE_VISIBILITY
506     value_type&
507     operator*()
508     {
509         _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
510         return this->__val_;
511     }
512
513     _LIBCPP_INLINE_VISIBILITY
514     constexpr explicit operator bool() const noexcept {return this->__engaged_;}
515
516     _LIBCPP_INLINE_VISIBILITY
517     constexpr value_type const& value() const
518     {
519         if (!this->__engaged_)
520 #ifndef _LIBCPP_NO_EXCEPTIONS
521             throw bad_optional_access();
522 #else
523             assert(!"bad optional access");
524 #endif
525         return this->__val_;
526     }
527
528     _LIBCPP_INLINE_VISIBILITY
529     value_type& value()
530     {
531         if (!this->__engaged_)
532 #ifndef _LIBCPP_NO_EXCEPTIONS
533             throw bad_optional_access();
534 #else
535             assert(!"bad optional access");
536 #endif
537         return this->__val_;
538     }
539
540     template <class _Up>
541     _LIBCPP_INLINE_VISIBILITY
542     constexpr value_type value_or(_Up&& __v) const&
543     {
544         static_assert(is_copy_constructible<value_type>::value,
545                       "optional<T>::value_or: T must be copy constructible");
546         static_assert(is_convertible<_Up, value_type>::value,
547                       "optional<T>::value_or: U must be convertible to T");
548         return this->__engaged_ ? this->__val_ :
549                                   static_cast<value_type>(_VSTD::forward<_Up>(__v));
550     }
551
552     template <class _Up>
553     _LIBCPP_INLINE_VISIBILITY
554     value_type value_or(_Up&& __v) &&
555     {
556         static_assert(is_move_constructible<value_type>::value,
557                       "optional<T>::value_or: T must be move constructible");
558         static_assert(is_convertible<_Up, value_type>::value,
559                       "optional<T>::value_or: U must be convertible to T");
560         return this->__engaged_ ? _VSTD::move(this->__val_) :
561                                   static_cast<value_type>(_VSTD::forward<_Up>(__v));
562     }
563
564 private:
565     _LIBCPP_INLINE_VISIBILITY
566     value_type const*
567     __operator_arrow(true_type) const
568     {
569         return _VSTD::addressof(this->__val_);
570     }
571
572     _LIBCPP_INLINE_VISIBILITY
573     constexpr
574     value_type const*
575     __operator_arrow(false_type) const
576     {
577         return &this->__val_;
578     }
579 };
580
581 // Comparisons between optionals
582 template <class _Tp>
583 inline _LIBCPP_INLINE_VISIBILITY
584 constexpr
585 bool
586 operator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
587 {
588     if (static_cast<bool>(__x) != static_cast<bool>(__y))
589         return false;
590     if (!static_cast<bool>(__x))
591         return true;
592     return *__x == *__y;
593 }
594
595 template <class _Tp>
596 inline _LIBCPP_INLINE_VISIBILITY
597 constexpr
598 bool
599 operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y)
600 {
601     return !(__x == __y);
602 }
603
604 template <class _Tp>
605 inline _LIBCPP_INLINE_VISIBILITY
606 constexpr
607 bool
608 operator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
609 {
610     if (!static_cast<bool>(__y))
611         return false;
612     if (!static_cast<bool>(__x))
613         return true;
614     return *__x < *__y;
615 }
616
617 template <class _Tp>
618 inline _LIBCPP_INLINE_VISIBILITY
619 constexpr
620 bool
621 operator>(const optional<_Tp>& __x, const optional<_Tp>& __y)
622 {
623     return __y < __x;
624 }
625
626 template <class _Tp>
627 inline _LIBCPP_INLINE_VISIBILITY
628 constexpr
629 bool
630 operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y)
631 {
632     return !(__y < __x);
633 }
634
635 template <class _Tp>
636 inline _LIBCPP_INLINE_VISIBILITY
637 constexpr
638 bool
639 operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y)
640 {
641     return !(__x < __y);
642 }
643
644
645 // Comparisons with nullopt
646 template <class _Tp>
647 inline _LIBCPP_INLINE_VISIBILITY
648 constexpr
649 bool
650 operator==(const optional<_Tp>& __x, nullopt_t) noexcept
651 {
652     return !static_cast<bool>(__x);
653 }
654
655 template <class _Tp>
656 inline _LIBCPP_INLINE_VISIBILITY
657 constexpr
658 bool
659 operator==(nullopt_t, const optional<_Tp>& __x) noexcept
660 {
661     return !static_cast<bool>(__x);
662 }
663
664 template <class _Tp>
665 inline _LIBCPP_INLINE_VISIBILITY
666 constexpr
667 bool
668 operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
669 {
670     return static_cast<bool>(__x);
671 }
672
673 template <class _Tp>
674 inline _LIBCPP_INLINE_VISIBILITY
675 constexpr
676 bool
677 operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
678 {
679     return static_cast<bool>(__x);
680 }
681
682 template <class _Tp>
683 inline _LIBCPP_INLINE_VISIBILITY
684 constexpr
685 bool
686 operator<(const optional<_Tp>&, nullopt_t) noexcept
687 {
688     return false;
689 }
690
691 template <class _Tp>
692 inline _LIBCPP_INLINE_VISIBILITY
693 constexpr
694 bool
695 operator<(nullopt_t, const optional<_Tp>& __x) noexcept
696 {
697     return static_cast<bool>(__x);
698 }
699
700 template <class _Tp>
701 inline _LIBCPP_INLINE_VISIBILITY
702 constexpr
703 bool
704 operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
705 {
706     return !static_cast<bool>(__x);
707 }
708
709 template <class _Tp>
710 inline _LIBCPP_INLINE_VISIBILITY
711 constexpr
712 bool
713 operator<=(nullopt_t, const optional<_Tp>& __x) noexcept
714 {
715     return true;
716 }
717
718 template <class _Tp>
719 inline _LIBCPP_INLINE_VISIBILITY
720 constexpr
721 bool
722 operator>(const optional<_Tp>& __x, nullopt_t) noexcept
723 {
724     return static_cast<bool>(__x);
725 }
726
727 template <class _Tp>
728 inline _LIBCPP_INLINE_VISIBILITY
729 constexpr
730 bool
731 operator>(nullopt_t, const optional<_Tp>& __x) noexcept
732 {
733     return false;
734 }
735
736 template <class _Tp>
737 inline _LIBCPP_INLINE_VISIBILITY
738 constexpr
739 bool
740 operator>=(const optional<_Tp>&, nullopt_t) noexcept
741 {
742     return true;
743 }
744
745 template <class _Tp>
746 inline _LIBCPP_INLINE_VISIBILITY
747 constexpr
748 bool
749 operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
750 {
751     return !static_cast<bool>(__x);
752 }
753
754 // Comparisons with T
755 template <class _Tp>
756 inline _LIBCPP_INLINE_VISIBILITY
757 constexpr
758 bool
759 operator==(const optional<_Tp>& __x, const _Tp& __v)
760 {
761     return static_cast<bool>(__x) ? *__x == __v : false;
762 }
763
764 template <class _Tp>
765 inline _LIBCPP_INLINE_VISIBILITY
766 constexpr
767 bool
768 operator==(const _Tp& __v, const optional<_Tp>& __x)
769 {
770     return static_cast<bool>(__x) ? *__x == __v : false;
771 }
772
773 template <class _Tp>
774 inline _LIBCPP_INLINE_VISIBILITY
775 constexpr
776 bool
777 operator!=(const optional<_Tp>& __x, const _Tp& __v)
778 {
779     return static_cast<bool>(__x) ? !(*__x == __v) : true;
780 }
781
782 template <class _Tp>
783 inline _LIBCPP_INLINE_VISIBILITY
784 constexpr
785 bool
786 operator!=(const _Tp& __v, const optional<_Tp>& __x)
787 {
788     return static_cast<bool>(__x) ? !(*__x == __v) : true;
789 }
790
791 template <class _Tp>
792 inline _LIBCPP_INLINE_VISIBILITY
793 constexpr
794 bool
795 operator<(const optional<_Tp>& __x, const _Tp& __v)
796 {
797     return static_cast<bool>(__x) ? less<_Tp>{}(*__x, __v) : true;
798 }
799
800 template <class _Tp>
801 inline _LIBCPP_INLINE_VISIBILITY
802 constexpr
803 bool
804 operator<(const _Tp& __v, const optional<_Tp>& __x)
805 {
806     return static_cast<bool>(__x) ? less<_Tp>{}(__v, *__x) : false;
807 }
808
809 template <class _Tp>
810 inline _LIBCPP_INLINE_VISIBILITY
811 constexpr
812 bool
813 operator<=(const optional<_Tp>& __x, const _Tp& __v)
814 {
815     return !(__x > __v);
816 }
817
818 template <class _Tp>
819 inline _LIBCPP_INLINE_VISIBILITY
820 constexpr
821 bool
822 operator<=(const _Tp& __v, const optional<_Tp>& __x)
823 {
824     return !(__v > __x);
825 }
826
827 template <class _Tp>
828 inline _LIBCPP_INLINE_VISIBILITY
829 constexpr
830 bool
831 operator>(const optional<_Tp>& __x, const _Tp& __v)
832 {
833     return static_cast<bool>(__x) ? __v < __x : false;
834 }
835
836 template <class _Tp>
837 inline _LIBCPP_INLINE_VISIBILITY
838 constexpr
839 bool
840 operator>(const _Tp& __v, const optional<_Tp>& __x)
841 {
842     return static_cast<bool>(__x) ? __x < __v : true;
843 }
844
845 template <class _Tp>
846 inline _LIBCPP_INLINE_VISIBILITY
847 constexpr
848 bool
849 operator>=(const optional<_Tp>& __x, const _Tp& __v)
850 {
851     return !(__x < __v);
852 }
853
854 template <class _Tp>
855 inline _LIBCPP_INLINE_VISIBILITY
856 constexpr
857 bool
858 operator>=(const _Tp& __v, const optional<_Tp>& __x)
859 {
860     return !(__v < __x);
861 }
862
863
864 template <class _Tp>
865 inline _LIBCPP_INLINE_VISIBILITY
866 void
867 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
868 {
869     __x.swap(__y);
870 }
871
872 template <class _Tp>
873 inline _LIBCPP_INLINE_VISIBILITY
874 constexpr
875 optional<typename decay<_Tp>::type>
876 make_optional(_Tp&& __v)
877 {
878     return optional<typename decay<_Tp>::type>(_VSTD::forward<_Tp>(__v));
879 }
880
881 _LIBCPP_END_NAMESPACE_LFTS
882
883 _LIBCPP_BEGIN_NAMESPACE_STD
884
885 template <class _Tp>
886 struct _LIBCPP_TYPE_VIS_ONLY hash<std::experimental::optional<_Tp> >
887 {
888     typedef std::experimental::optional<_Tp> argument_type;
889     typedef size_t        result_type;
890
891     _LIBCPP_INLINE_VISIBILITY
892     result_type operator()(const argument_type& __opt) const _NOEXCEPT
893     {
894         return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0;
895     }
896 };
897
898 _LIBCPP_END_NAMESPACE_STD
899
900 #endif  // _LIBCPP_STD_VER > 11
901
902 #endif  // _LIBCPP_OPTIONAL