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