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
19namespace 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
163class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
164    : public std::logic_error
165{
166public:
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
180struct in_place_t {};
181constexpr in_place_t in_place{};
182
183struct nullopt_t
184{
185    explicit constexpr nullopt_t(int) noexcept {}
186};
187
188constexpr nullopt_t nullopt{0};
189
190template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
191class __optional_storage
192{
193protected:
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
248template <class _Tp>
249class __optional_storage<_Tp, true>
250{
251protected:
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
299template <class _Tp>
300class optional
301    : private __optional_storage<_Tp>
302{
303    typedef __optional_storage<_Tp> __base;
304public:
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
582private:
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
600template <class _Tp>
601inline _LIBCPP_INLINE_VISIBILITY
602constexpr
603bool
604operator==(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
613template <class _Tp>
614inline _LIBCPP_INLINE_VISIBILITY
615constexpr
616bool
617operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y)
618{
619    return !(__x == __y);
620}
621
622template <class _Tp>
623inline _LIBCPP_INLINE_VISIBILITY
624constexpr
625bool
626operator<(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
635template <class _Tp>
636inline _LIBCPP_INLINE_VISIBILITY
637constexpr
638bool
639operator>(const optional<_Tp>& __x, const optional<_Tp>& __y)
640{
641    return __y < __x;
642}
643
644template <class _Tp>
645inline _LIBCPP_INLINE_VISIBILITY
646constexpr
647bool
648operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y)
649{
650    return !(__y < __x);
651}
652
653template <class _Tp>
654inline _LIBCPP_INLINE_VISIBILITY
655constexpr
656bool
657operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y)
658{
659    return !(__x < __y);
660}
661
662
663// Comparisons with nullopt
664template <class _Tp>
665inline _LIBCPP_INLINE_VISIBILITY
666constexpr
667bool
668operator==(const optional<_Tp>& __x, nullopt_t) noexcept
669{
670    return !static_cast<bool>(__x);
671}
672
673template <class _Tp>
674inline _LIBCPP_INLINE_VISIBILITY
675constexpr
676bool
677operator==(nullopt_t, const optional<_Tp>& __x) noexcept
678{
679    return !static_cast<bool>(__x);
680}
681
682template <class _Tp>
683inline _LIBCPP_INLINE_VISIBILITY
684constexpr
685bool
686operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
687{
688    return static_cast<bool>(__x);
689}
690
691template <class _Tp>
692inline _LIBCPP_INLINE_VISIBILITY
693constexpr
694bool
695operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
696{
697    return static_cast<bool>(__x);
698}
699
700template <class _Tp>
701inline _LIBCPP_INLINE_VISIBILITY
702constexpr
703bool
704operator<(const optional<_Tp>&, nullopt_t) noexcept
705{
706    return false;
707}
708
709template <class _Tp>
710inline _LIBCPP_INLINE_VISIBILITY
711constexpr
712bool
713operator<(nullopt_t, const optional<_Tp>& __x) noexcept
714{
715    return static_cast<bool>(__x);
716}
717
718template <class _Tp>
719inline _LIBCPP_INLINE_VISIBILITY
720constexpr
721bool
722operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
723{
724    return !static_cast<bool>(__x);
725}
726
727template <class _Tp>
728inline _LIBCPP_INLINE_VISIBILITY
729constexpr
730bool
731operator<=(nullopt_t, const optional<_Tp>&) noexcept
732{
733    return true;
734}
735
736template <class _Tp>
737inline _LIBCPP_INLINE_VISIBILITY
738constexpr
739bool
740operator>(const optional<_Tp>& __x, nullopt_t) noexcept
741{
742    return static_cast<bool>(__x);
743}
744
745template <class _Tp>
746inline _LIBCPP_INLINE_VISIBILITY
747constexpr
748bool
749operator>(nullopt_t, const optional<_Tp>&) noexcept
750{
751    return false;
752}
753
754template <class _Tp>
755inline _LIBCPP_INLINE_VISIBILITY
756constexpr
757bool
758operator>=(const optional<_Tp>&, nullopt_t) noexcept
759{
760    return true;
761}
762
763template <class _Tp>
764inline _LIBCPP_INLINE_VISIBILITY
765constexpr
766bool
767operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
768{
769    return !static_cast<bool>(__x);
770}
771
772// Comparisons with T
773template <class _Tp>
774inline _LIBCPP_INLINE_VISIBILITY
775constexpr
776bool
777operator==(const optional<_Tp>& __x, const _Tp& __v)
778{
779    return static_cast<bool>(__x) ? *__x == __v : false;
780}
781
782template <class _Tp>
783inline _LIBCPP_INLINE_VISIBILITY
784constexpr
785bool
786operator==(const _Tp& __v, const optional<_Tp>& __x)
787{
788    return static_cast<bool>(__x) ? *__x == __v : false;
789}
790
791template <class _Tp>
792inline _LIBCPP_INLINE_VISIBILITY
793constexpr
794bool
795operator!=(const optional<_Tp>& __x, const _Tp& __v)
796{
797    return static_cast<bool>(__x) ? !(*__x == __v) : true;
798}
799
800template <class _Tp>
801inline _LIBCPP_INLINE_VISIBILITY
802constexpr
803bool
804operator!=(const _Tp& __v, const optional<_Tp>& __x)
805{
806    return static_cast<bool>(__x) ? !(*__x == __v) : true;
807}
808
809template <class _Tp>
810inline _LIBCPP_INLINE_VISIBILITY
811constexpr
812bool
813operator<(const optional<_Tp>& __x, const _Tp& __v)
814{
815    return static_cast<bool>(__x) ? less<_Tp>{}(*__x, __v) : true;
816}
817
818template <class _Tp>
819inline _LIBCPP_INLINE_VISIBILITY
820constexpr
821bool
822operator<(const _Tp& __v, const optional<_Tp>& __x)
823{
824    return static_cast<bool>(__x) ? less<_Tp>{}(__v, *__x) : false;
825}
826
827template <class _Tp>
828inline _LIBCPP_INLINE_VISIBILITY
829constexpr
830bool
831operator<=(const optional<_Tp>& __x, const _Tp& __v)
832{
833    return !(__x > __v);
834}
835
836template <class _Tp>
837inline _LIBCPP_INLINE_VISIBILITY
838constexpr
839bool
840operator<=(const _Tp& __v, const optional<_Tp>& __x)
841{
842    return !(__v > __x);
843}
844
845template <class _Tp>
846inline _LIBCPP_INLINE_VISIBILITY
847constexpr
848bool
849operator>(const optional<_Tp>& __x, const _Tp& __v)
850{
851    return static_cast<bool>(__x) ? __v < __x : false;
852}
853
854template <class _Tp>
855inline _LIBCPP_INLINE_VISIBILITY
856constexpr
857bool
858operator>(const _Tp& __v, const optional<_Tp>& __x)
859{
860    return static_cast<bool>(__x) ? __x < __v : true;
861}
862
863template <class _Tp>
864inline _LIBCPP_INLINE_VISIBILITY
865constexpr
866bool
867operator>=(const optional<_Tp>& __x, const _Tp& __v)
868{
869    return !(__x < __v);
870}
871
872template <class _Tp>
873inline _LIBCPP_INLINE_VISIBILITY
874constexpr
875bool
876operator>=(const _Tp& __v, const optional<_Tp>& __x)
877{
878    return !(__v < __x);
879}
880
881
882template <class _Tp>
883inline _LIBCPP_INLINE_VISIBILITY
884void
885swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
886{
887    __x.swap(__y);
888}
889
890template <class _Tp>
891inline _LIBCPP_INLINE_VISIBILITY
892constexpr
893optional<typename decay<_Tp>::type>
894make_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
903template <class _Tp>
904struct _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
923