]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libc++/include/experimental/optional
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r304460, 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 #if _LIBCPP_STD_VER > 11
147 #include <initializer_list>
148 #include <type_traits>
149 #include <new>
150 #include <__functional_base>
151 #include <__debug>
152 #endif
153
154 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
155 #pragma GCC system_header
156 #endif
157
158 _LIBCPP_PUSH_MACROS
159 #include <__undef_macros>
160
161
162 _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
163 class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
164     : public std::logic_error
165 {
166 public:
167         bad_optional_access() : std::logic_error("Bad optional Access") {}
168
169 //      Get the key function ~bad_optional_access() into the dylib
170     virtual ~bad_optional_access() _NOEXCEPT;
171 };
172
173 _LIBCPP_END_NAMESPACE_EXPERIMENTAL
174
175
176 #if _LIBCPP_STD_VER > 11
177
178 _LIBCPP_BEGIN_NAMESPACE_LFTS
179
180 struct in_place_t {};
181 constexpr in_place_t in_place{};
182
183 struct nullopt_t
184 {
185     explicit constexpr nullopt_t(int) noexcept {}
186 };
187
188 constexpr nullopt_t nullopt{0};
189
190 template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
191 class __optional_storage
192 {
193 protected:
194     typedef _Tp value_type;
195     union
196     {
197         char __null_state_;
198         value_type __val_;
199     };
200     bool __engaged_ = false;
201
202     _LIBCPP_INLINE_VISIBILITY
203     ~__optional_storage()
204     {
205         if (__engaged_)
206             __val_.~value_type();
207     }
208
209     _LIBCPP_INLINE_VISIBILITY
210     constexpr __optional_storage() noexcept
211         :  __null_state_('\0') {}
212
213     _LIBCPP_INLINE_VISIBILITY
214     __optional_storage(const __optional_storage& __x)
215         :  __engaged_(__x.__engaged_)
216         {
217             if (__engaged_)
218                 ::new((void*)_VSTD::addressof(__val_)) value_type(__x.__val_);
219         }
220
221     _LIBCPP_INLINE_VISIBILITY
222     __optional_storage(__optional_storage&& __x)
223                       noexcept(is_nothrow_move_constructible<value_type>::value)
224         :  __engaged_(__x.__engaged_)
225         {
226             if (__engaged_)
227                 ::new((void*)_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_));
228         }
229
230     _LIBCPP_INLINE_VISIBILITY
231     constexpr __optional_storage(const value_type& __v)
232         :  __val_(__v),
233            __engaged_(true) {}
234
235     _LIBCPP_INLINE_VISIBILITY
236     constexpr __optional_storage(value_type&& __v)
237         :  __val_(_VSTD::move(__v)),
238            __engaged_(true) {}
239
240     template <class... _Args>
241     _LIBCPP_INLINE_VISIBILITY
242     constexpr
243     explicit __optional_storage(in_place_t, _Args&&... __args)
244        :  __val_(_VSTD::forward<_Args>(__args)...),
245            __engaged_(true) {}
246 };
247
248 template <class _Tp>
249 class __optional_storage<_Tp, true>
250 {
251 protected:
252     typedef _Tp value_type;
253     union
254     {
255         char __null_state_;
256         value_type __val_;
257     };
258     bool __engaged_ = false;
259
260     _LIBCPP_INLINE_VISIBILITY
261     constexpr __optional_storage() noexcept
262         :  __null_state_('\0') {}
263
264     _LIBCPP_INLINE_VISIBILITY
265     __optional_storage(const __optional_storage& __x)
266         :  __engaged_(__x.__engaged_)
267         {
268             if (__engaged_)
269                 ::new((void*)_VSTD::addressof(__val_)) value_type(__x.__val_);
270         }
271
272     _LIBCPP_INLINE_VISIBILITY
273     __optional_storage(__optional_storage&& __x)
274                       noexcept(is_nothrow_move_constructible<value_type>::value)
275         :  __engaged_(__x.__engaged_)
276         {
277             if (__engaged_)
278                 ::new((void*)_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_));
279         }
280
281     _LIBCPP_INLINE_VISIBILITY
282     constexpr __optional_storage(const value_type& __v)
283         :  __val_(__v),
284            __engaged_(true) {}
285
286     _LIBCPP_INLINE_VISIBILITY
287     constexpr __optional_storage(value_type&& __v)
288         :  __val_(_VSTD::move(__v)),
289            __engaged_(true) {}
290
291     template <class... _Args>
292     _LIBCPP_INLINE_VISIBILITY
293     constexpr
294     explicit __optional_storage(in_place_t, _Args&&... __args)
295        :  __val_(_VSTD::forward<_Args>(__args)...),
296            __engaged_(true) {}
297 };
298
299 template <class _Tp>
300 class optional
301     : private __optional_storage<_Tp>
302 {
303     typedef __optional_storage<_Tp> __base;
304 public:
305     typedef _Tp value_type;
306
307     static_assert(!is_reference<value_type>::value,
308               "Instantiation of optional with a reference type is ill-formed.");
309     static_assert(!is_same<typename remove_cv<value_type>::type, in_place_t>::value,
310               "Instantiation of optional with a in_place_t type is ill-formed.");
311     static_assert(!is_same<typename remove_cv<value_type>::type, nullopt_t>::value,
312               "Instantiation of optional with a nullopt_t type is ill-formed.");
313     static_assert(is_object<value_type>::value,
314         "Instantiation of optional with a non-object type is undefined behavior.");
315     static_assert(is_nothrow_destructible<value_type>::value,
316         "Instantiation of optional with an object type that is not noexcept destructible is undefined behavior.");
317
318     _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
319     _LIBCPP_INLINE_VISIBILITY optional(const optional&) = default;
320     _LIBCPP_INLINE_VISIBILITY optional(optional&&) = default;
321     _LIBCPP_INLINE_VISIBILITY ~optional() = default;
322     _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
323     _LIBCPP_INLINE_VISIBILITY constexpr optional(const value_type& __v)
324         : __base(__v) {}
325     _LIBCPP_INLINE_VISIBILITY constexpr optional(value_type&& __v)
326         : __base(_VSTD::move(__v)) {}
327
328     template <class... _Args,
329               class = typename enable_if
330                       <
331                            is_constructible<value_type, _Args...>::value
332                       >::type
333              >
334     _LIBCPP_INLINE_VISIBILITY
335     constexpr
336     explicit optional(in_place_t, _Args&&... __args)
337         : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
338
339     template <class _Up, class... _Args,
340               class = typename enable_if
341                       <
342                            is_constructible<value_type, initializer_list<_Up>&, _Args...>::value
343                       >::type
344              >
345     _LIBCPP_INLINE_VISIBILITY
346     constexpr
347     explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
348         : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
349
350     _LIBCPP_INLINE_VISIBILITY
351     optional& operator=(nullopt_t) noexcept
352     {
353         if (this->__engaged_)
354         {
355             this->__val_.~value_type();
356             this->__engaged_ = false;
357         }
358         return *this;
359     }
360
361     _LIBCPP_INLINE_VISIBILITY
362     optional&
363     operator=(const optional& __opt)
364     {
365         if (this->__engaged_ == __opt.__engaged_)
366         {
367             if (this->__engaged_)
368                 this->__val_ = __opt.__val_;
369         }
370         else
371         {
372             if (this->__engaged_)
373                 this->__val_.~value_type();
374             else
375                 ::new((void*)_VSTD::addressof(this->__val_)) value_type(__opt.__val_);
376             this->__engaged_ = __opt.__engaged_;
377         }
378         return *this;
379     }
380
381     _LIBCPP_INLINE_VISIBILITY
382     optional&
383     operator=(optional&& __opt)
384         noexcept(is_nothrow_move_assignable<value_type>::value &&
385                  is_nothrow_move_constructible<value_type>::value)
386     {
387         if (this->__engaged_ == __opt.__engaged_)
388         {
389             if (this->__engaged_)
390                 this->__val_ = _VSTD::move(__opt.__val_);
391         }
392         else
393         {
394             if (this->__engaged_)
395                 this->__val_.~value_type();
396             else
397                 ::new((void*)_VSTD::addressof(this->__val_))
398                     value_type(_VSTD::move(__opt.__val_));
399             this->__engaged_ = __opt.__engaged_;
400         }
401         return *this;
402     }
403
404     template <class _Up,
405               class = typename enable_if
406                       <
407                           is_same<typename remove_reference<_Up>::type, value_type>::value &&
408                           is_constructible<value_type, _Up>::value &&
409                           is_assignable<value_type&, _Up>::value
410                       >::type
411              >
412     _LIBCPP_INLINE_VISIBILITY
413     optional&
414     operator=(_Up&& __v)
415     {
416         if (this->__engaged_)
417             this->__val_ = _VSTD::forward<_Up>(__v);
418         else
419         {
420             ::new((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Up>(__v));
421             this->__engaged_ = true;
422         }
423         return *this;
424     }
425
426     template <class... _Args,
427               class = typename enable_if
428                       <
429                           is_constructible<value_type, _Args...>::value
430                       >::type
431              >
432     _LIBCPP_INLINE_VISIBILITY
433     void
434     emplace(_Args&&... __args)
435     {
436         *this = nullopt;
437         ::new((void*)_VSTD::addressof(this->__val_))
438             value_type(_VSTD::forward<_Args>(__args)...);
439         this->__engaged_ = true;
440     }
441
442     template <class _Up, class... _Args,
443               class = typename enable_if
444                       <
445                           is_constructible<value_type, initializer_list<_Up>&, _Args...>::value
446                       >::type
447              >
448     _LIBCPP_INLINE_VISIBILITY
449     void
450     emplace(initializer_list<_Up> __il, _Args&&... __args)
451     {
452         *this = nullopt;
453         ::new((void*)_VSTD::addressof(this->__val_))
454             value_type(__il, _VSTD::forward<_Args>(__args)...);
455         this->__engaged_ = true;
456     }
457
458     _LIBCPP_INLINE_VISIBILITY
459     void
460     swap(optional& __opt)
461         noexcept(is_nothrow_move_constructible<value_type>::value &&
462                  __is_nothrow_swappable<value_type>::value)
463     {
464         using _VSTD::swap;
465         if (this->__engaged_ == __opt.__engaged_)
466         {
467             if (this->__engaged_)
468                 swap(this->__val_, __opt.__val_);
469         }
470         else
471         {
472             if (this->__engaged_)
473             {
474                 ::new((void*)_VSTD::addressof(__opt.__val_))
475                     value_type(_VSTD::move(this->__val_));
476                 this->__val_.~value_type();
477             }
478             else
479             {
480                 ::new((void*)_VSTD::addressof(this->__val_))
481                     value_type(_VSTD::move(__opt.__val_));
482                 __opt.__val_.~value_type();
483             }
484             swap(this->__engaged_, __opt.__engaged_);
485         }
486     }
487
488     _LIBCPP_INLINE_VISIBILITY
489     constexpr
490     value_type const*
491     operator->() const
492     {
493         _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
494 #ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
495         return __builtin_addressof(this->__val_);
496 #else
497         return __operator_arrow(__has_operator_addressof<value_type>{});
498 #endif
499     }
500
501     _LIBCPP_INLINE_VISIBILITY
502     value_type*
503     operator->()
504     {
505         _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
506         return _VSTD::addressof(this->__val_);
507     }
508
509     _LIBCPP_INLINE_VISIBILITY
510     constexpr
511     const value_type&
512     operator*() const
513     {
514         _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
515         return this->__val_;
516     }
517
518     _LIBCPP_INLINE_VISIBILITY
519     value_type&
520     operator*()
521     {
522         _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
523         return this->__val_;
524     }
525
526     _LIBCPP_INLINE_VISIBILITY
527     constexpr explicit operator bool() const noexcept {return this->__engaged_;}
528
529         _LIBCPP_NORETURN _LIBCPP_INLINE_VISIBILITY 
530 #ifndef _LIBCPP_NO_EXCEPTIONS
531 _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
532 #endif
533         constexpr void __throw_bad_optional_access() const
534         {
535 #ifndef _LIBCPP_NO_EXCEPTIONS
536         throw bad_optional_access();
537 #else
538         _VSTD::abort();
539 #endif
540         }
541         
542     _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
543     constexpr value_type const& value() const
544     {
545         if (!this->__engaged_)
546             __throw_bad_optional_access();
547         return this->__val_;
548     }
549
550     _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
551     value_type& value()
552     {
553         if (!this->__engaged_)
554             __throw_bad_optional_access();
555         return this->__val_;
556     }
557
558     template <class _Up>
559     _LIBCPP_INLINE_VISIBILITY
560     constexpr value_type value_or(_Up&& __v) const&
561     {
562         static_assert(is_copy_constructible<value_type>::value,
563                       "optional<T>::value_or: T must be copy constructible");
564         static_assert(is_convertible<_Up, value_type>::value,
565                       "optional<T>::value_or: U must be convertible to T");
566         return this->__engaged_ ? this->__val_ :
567                                   static_cast<value_type>(_VSTD::forward<_Up>(__v));
568     }
569
570     template <class _Up>
571     _LIBCPP_INLINE_VISIBILITY
572     value_type value_or(_Up&& __v) &&
573     {
574         static_assert(is_move_constructible<value_type>::value,
575                       "optional<T>::value_or: T must be move constructible");
576         static_assert(is_convertible<_Up, value_type>::value,
577                       "optional<T>::value_or: U must be convertible to T");
578         return this->__engaged_ ? _VSTD::move(this->__val_) :
579                                   static_cast<value_type>(_VSTD::forward<_Up>(__v));
580     }
581
582 private:
583     _LIBCPP_INLINE_VISIBILITY
584     value_type const*
585     __operator_arrow(true_type) const
586     {
587         return _VSTD::addressof(this->__val_);
588     }
589
590     _LIBCPP_INLINE_VISIBILITY
591     constexpr
592     value_type const*
593     __operator_arrow(false_type) const
594     {
595         return &this->__val_;
596     }
597 };
598
599 // Comparisons between optionals
600 template <class _Tp>
601 inline _LIBCPP_INLINE_VISIBILITY
602 constexpr
603 bool
604 operator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
605 {
606     if (static_cast<bool>(__x) != static_cast<bool>(__y))
607         return false;
608     if (!static_cast<bool>(__x))
609         return true;
610     return *__x == *__y;
611 }
612
613 template <class _Tp>
614 inline _LIBCPP_INLINE_VISIBILITY
615 constexpr
616 bool
617 operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y)
618 {
619     return !(__x == __y);
620 }
621
622 template <class _Tp>
623 inline _LIBCPP_INLINE_VISIBILITY
624 constexpr
625 bool
626 operator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
627 {
628     if (!static_cast<bool>(__y))
629         return false;
630     if (!static_cast<bool>(__x))
631         return true;
632     return *__x < *__y;
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 __y < __x;
642 }
643
644 template <class _Tp>
645 inline _LIBCPP_INLINE_VISIBILITY
646 constexpr
647 bool
648 operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y)
649 {
650     return !(__y < __x);
651 }
652
653 template <class _Tp>
654 inline _LIBCPP_INLINE_VISIBILITY
655 constexpr
656 bool
657 operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y)
658 {
659     return !(__x < __y);
660 }
661
662
663 // Comparisons with nullopt
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>& __x, nullopt_t) noexcept
687 {
688     return static_cast<bool>(__x);
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>&, nullopt_t) noexcept
705 {
706     return false;
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 static_cast<bool>(__x);
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>&) noexcept
732 {
733     return true;
734 }
735
736 template <class _Tp>
737 inline _LIBCPP_INLINE_VISIBILITY
738 constexpr
739 bool
740 operator>(const optional<_Tp>& __x, nullopt_t) noexcept
741 {
742     return static_cast<bool>(__x);
743 }
744
745 template <class _Tp>
746 inline _LIBCPP_INLINE_VISIBILITY
747 constexpr
748 bool
749 operator>(nullopt_t, const optional<_Tp>&) noexcept
750 {
751     return false;
752 }
753
754 template <class _Tp>
755 inline _LIBCPP_INLINE_VISIBILITY
756 constexpr
757 bool
758 operator>=(const optional<_Tp>&, nullopt_t) noexcept
759 {
760     return true;
761 }
762
763 template <class _Tp>
764 inline _LIBCPP_INLINE_VISIBILITY
765 constexpr
766 bool
767 operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
768 {
769     return !static_cast<bool>(__x);
770 }
771
772 // Comparisons with T
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 : false;
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 : false;
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) ? !(*__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) ? !(*__x == __v) : true;
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 static_cast<bool>(__x) ? less<_Tp>{}(*__x, __v) : true;
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 static_cast<bool>(__x) ? less<_Tp>{}(__v, *__x) : false;
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 !(__x > __v);
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 !(__v > __x);
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 static_cast<bool>(__x) ? __v < __x : false;
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 static_cast<bool>(__x) ? __x < __v : true;
861 }
862
863 template <class _Tp>
864 inline _LIBCPP_INLINE_VISIBILITY
865 constexpr
866 bool
867 operator>=(const optional<_Tp>& __x, const _Tp& __v)
868 {
869     return !(__x < __v);
870 }
871
872 template <class _Tp>
873 inline _LIBCPP_INLINE_VISIBILITY
874 constexpr
875 bool
876 operator>=(const _Tp& __v, const optional<_Tp>& __x)
877 {
878     return !(__v < __x);
879 }
880
881
882 template <class _Tp>
883 inline _LIBCPP_INLINE_VISIBILITY
884 void
885 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
886 {
887     __x.swap(__y);
888 }
889
890 template <class _Tp>
891 inline _LIBCPP_INLINE_VISIBILITY
892 constexpr
893 optional<typename decay<_Tp>::type>
894 make_optional(_Tp&& __v)
895 {
896     return optional<typename decay<_Tp>::type>(_VSTD::forward<_Tp>(__v));
897 }
898
899 _LIBCPP_END_NAMESPACE_LFTS
900
901 _LIBCPP_BEGIN_NAMESPACE_STD
902
903 template <class _Tp>
904 struct _LIBCPP_TEMPLATE_VIS hash<std::experimental::optional<_Tp> >
905 {
906     typedef std::experimental::optional<_Tp> argument_type;
907     typedef size_t        result_type;
908
909     _LIBCPP_INLINE_VISIBILITY
910     result_type operator()(const argument_type& __opt) const _NOEXCEPT
911     {
912         return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0;
913     }
914 };
915
916 _LIBCPP_END_NAMESPACE_STD
917
918 #endif  // _LIBCPP_STD_VER > 11
919
920 _LIBCPP_POP_MACROS
921
922 #endif  // _LIBCPP_EXPERIMENTAL_OPTIONAL