]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libc++/include/optional
Update to tcsh 6.20.00
[FreeBSD/FreeBSD.git] / contrib / libc++ / include / 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++1z
18
19 namespace std {
20   // 20.6.3, optional for object types
21   template <class T> class optional;
22
23   // 20.6.4, no-value state indicator
24   struct nullopt_t{see below };
25   constexpr nullopt_t nullopt(unspecified );
26
27   // 20.6.5, class bad_optional_access
28   class bad_optional_access;
29
30   // 20.6.6, relational operators
31   template <class T>
32   constexpr bool operator==(const optional<T>&, const optional<T>&);
33   template <class T>
34   constexpr bool operator!=(const optional<T>&, const optional<T>&);
35   template <class T>
36   constexpr bool operator<(const optional<T>&, const optional<T>&);
37   template <class T>
38   constexpr bool operator>(const optional<T>&, const optional<T>&);
39   template <class T>
40   constexpr bool operator<=(const optional<T>&, const optional<T>&);
41   template <class T>
42   constexpr bool operator>=(const optional<T>&, const optional<T>&);
43   template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
44   template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept;
45   template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept;
46   template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept;
47   template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept;
48   template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept;
49   template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept;
50   template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept;
51   template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept;
52   template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept;
53   template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept;
54   template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept;
55
56   // 20.6.8, comparison with T
57   template <class T> constexpr bool operator==(const optional<T>&, const T&);
58   template <class T> constexpr bool operator==(const T&, const optional<T>&);
59   template <class T> constexpr bool operator!=(const optional<T>&, const T&);
60   template <class T> constexpr bool operator!=(const T&, const optional<T>&);
61   template <class T> constexpr bool operator<(const optional<T>&, const T&);
62   template <class T> constexpr bool operator<(const T&, const optional<T>&);
63   template <class T> constexpr bool operator<=(const optional<T>&, const T&);
64   template <class T> constexpr bool operator<=(const T&, const optional<T>&);
65   template <class T> constexpr bool operator>(const optional<T>&, const T&);
66   template <class T> constexpr bool operator>(const T&, const optional<T>&);
67   template <class T> constexpr bool operator>=(const optional<T>&, const T&);
68   template <class T> constexpr bool operator>=(const T&, const optional<T>&);
69
70   // 20.6.9, specialized algorithms
71   template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below );
72   template <class T> constexpr optional<see below > make_optional(T&&);
73   template <class T, class... Args>
74     constexpr optional<T> make_optional(Args&&... args);
75   template <class T, class U, class... Args>
76     constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args);
77
78   // 20.6.10, hash support
79   template <class T> struct hash;
80   template <class T> struct hash<optional<T>>;
81
82   template <class T> class optional {
83   public:
84     using value_type = T;
85
86     // 20.6.3.1, constructors
87     constexpr optional() noexcept;
88     constexpr optional(nullopt_t) noexcept;
89     optional(const optional &);
90     optional(optional &&) noexcept(see below );
91     template <class... Args> constexpr explicit optional(in_place_t, Args &&...);
92     template <class U, class... Args>
93       constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...);
94     template <class U = T>
95       constexpr EXPLICIT optional(U &&);
96     template <class U>
97       constexpr EXPLICIT optional(const optional<U> &);
98     template <class U>
99       constexpr EXPLICIT optional(optional<U> &&);
100
101     // 20.6.3.2, destructor
102     ~optional();
103
104     // 20.6.3.3, assignment
105     optional &operator=(nullopt_t) noexcept;
106     optional &operator=(const optional &);
107     optional &operator=(optional &&) noexcept(see below );
108     template <class U = T> optional &operator=(U &&);
109     template <class U> optional &operator=(const optional<U> &);
110     template <class U> optional &operator=(optional<U> &&);
111     template <class... Args> void emplace(Args &&...);
112     template <class U, class... Args>
113       void emplace(initializer_list<U>, Args &&...);
114
115     // 20.6.3.4, swap
116     void swap(optional &) noexcept(see below );
117
118     // 20.6.3.5, observers
119     constexpr T const *operator->() const;
120     constexpr T *operator->();
121     constexpr T const &operator*() const &;
122     constexpr T &operator*() &;
123     constexpr T &&operator*() &&;
124     constexpr const T &&operator*() const &&;
125     constexpr explicit operator bool() const noexcept;
126     constexpr bool has_value() const noexcept;
127     constexpr T const &value() const &;
128     constexpr T &value() &;
129     constexpr T &&value() &&;
130     constexpr const T &&value() const &&;
131     template <class U> constexpr T value_or(U &&) const &;
132     template <class U> constexpr T value_or(U &&) &&;
133
134     // 20.6.3.6, modifiers
135     void reset() noexcept;
136
137   private:
138     T *val; // exposition only
139   };
140 } // namespace std
141
142 */
143
144 #include <__config>
145 #include <__debug>
146 #include <__functional_base>
147 #include <__undef_min_max>
148 #include <functional>
149 #include <initializer_list>
150 #include <new>
151 #include <stdexcept>
152 #include <type_traits>
153 #include <utility>
154
155 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
156 #pragma GCC system_header
157 #endif
158
159 namespace std  // purposefully not using versioning namespace
160 {
161
162 class _LIBCPP_EXCEPTION_ABI bad_optional_access
163     : public exception
164 {
165 public:
166     // Get the key function ~bad_optional_access() into the dylib
167     virtual ~bad_optional_access() _NOEXCEPT;
168     virtual const char* what() const _NOEXCEPT;
169 };
170
171 }  // std
172
173 #if _LIBCPP_STD_VER > 14
174
175 _LIBCPP_BEGIN_NAMESPACE_STD
176
177 _LIBCPP_NORETURN
178 inline _LIBCPP_INLINE_VISIBILITY
179 void __throw_bad_optional_access() {
180 #ifndef _LIBCPP_NO_EXCEPTIONS
181         throw bad_optional_access();
182 #else
183         _VSTD::abort();
184 #endif
185 }
186
187 struct nullopt_t
188 {
189     struct __secret_tag { _LIBCPP_INLINE_VISIBILITY explicit __secret_tag() = default; };
190     _LIBCPP_INLINE_VISIBILITY constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {}
191 };
192
193 /* inline */ constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}};
194
195 template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
196 struct __optional_destruct_base;
197
198 template <class _Tp>
199 struct __optional_destruct_base<_Tp, false>
200 {
201     typedef _Tp value_type;
202     static_assert(is_object_v<value_type>,
203         "instantiation of optional with a non-object type is undefined behavior");
204     union
205     {
206         char __null_state_;
207         value_type __val_;
208     };
209     bool __engaged_;
210
211     _LIBCPP_INLINE_VISIBILITY
212     ~__optional_destruct_base()
213     {
214         if (__engaged_)
215             __val_.~value_type();
216     }
217
218     _LIBCPP_INLINE_VISIBILITY
219     constexpr __optional_destruct_base() noexcept
220         :  __null_state_(),
221            __engaged_(false) {}
222
223     template <class... _Args>
224     _LIBCPP_INLINE_VISIBILITY
225     constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
226         :  __val_(_VSTD::forward<_Args>(__args)...),
227            __engaged_(true) {}
228
229     _LIBCPP_INLINE_VISIBILITY
230     void reset() noexcept
231     {
232         if (__engaged_)
233         {
234             __val_.~value_type();
235             __engaged_ = false;
236         }
237     }
238 };
239
240 template <class _Tp>
241 struct __optional_destruct_base<_Tp, true>
242 {
243     typedef _Tp value_type;
244     static_assert(is_object_v<value_type>,
245         "instantiation of optional with a non-object type is undefined behavior");
246     union
247     {
248         char __null_state_;
249         value_type __val_;
250     };
251     bool __engaged_;
252
253     _LIBCPP_INLINE_VISIBILITY
254     constexpr __optional_destruct_base() noexcept
255         :  __null_state_(),
256            __engaged_(false) {}
257
258     template <class... _Args>
259     _LIBCPP_INLINE_VISIBILITY
260     constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
261         :  __val_(_VSTD::forward<_Args>(__args)...),
262            __engaged_(true) {}
263
264     _LIBCPP_INLINE_VISIBILITY
265     void reset() noexcept
266     {
267         if (__engaged_)
268         {
269             __engaged_ = false;
270         }
271     }
272 };
273
274 template <class _Tp, bool = is_reference<_Tp>::value>
275 struct __optional_storage_base : __optional_destruct_base<_Tp>
276 {
277     using __base = __optional_destruct_base<_Tp>;
278     using value_type = _Tp;
279     using __base::__base;
280
281     _LIBCPP_INLINE_VISIBILITY
282     constexpr bool has_value() const noexcept
283     {
284         return this->__engaged_;
285     }
286
287     _LIBCPP_INLINE_VISIBILITY
288     constexpr value_type& __get() & noexcept
289     {
290         return this->__val_;
291     }
292     _LIBCPP_INLINE_VISIBILITY
293     constexpr const value_type& __get() const& noexcept
294     {
295         return this->__val_;
296     }
297     _LIBCPP_INLINE_VISIBILITY
298     constexpr value_type&& __get() && noexcept
299     {
300         return _VSTD::move(this->__val_);
301     }
302     _LIBCPP_INLINE_VISIBILITY
303     constexpr const value_type&& __get() const&& noexcept
304     {
305         return _VSTD::move(this->__val_);
306     }
307
308     template <class... _Args>
309     _LIBCPP_INLINE_VISIBILITY
310     void __construct(_Args&&... __args)
311     {
312         _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
313         ::new((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
314         this->__engaged_ = true;
315     }
316
317     template <class _That>
318     _LIBCPP_INLINE_VISIBILITY
319     void __construct_from(_That&& __opt)
320     {
321         if (__opt.has_value())
322             __construct(_VSTD::forward<_That>(__opt).__get());
323     }
324
325     template <class _That>
326     _LIBCPP_INLINE_VISIBILITY
327     void __assign_from(_That&& __opt)
328     {
329         if (this->__engaged_ == __opt.has_value())
330         {
331             if (this->__engaged_)
332                 this->__val_ = _VSTD::forward<_That>(__opt).__get();
333         }
334         else
335         {
336             if (this->__engaged_)
337                 this->reset();
338             else
339                 __construct(_VSTD::forward<_That>(__opt).__get());
340         }
341     }
342 };
343
344 // optional<T&> is currently required ill-formed, however it may to be in the
345 // future. For this reason it has already been implemented to ensure we can
346 // make the change in an ABI compatible manner.
347 template <class _Tp>
348 struct __optional_storage_base<_Tp, true>
349 {
350     using value_type = _Tp;
351     using __raw_type = remove_reference_t<_Tp>;
352     __raw_type* __value_;
353
354     template <class _Up>
355     static constexpr bool __can_bind_reference() {
356         using _RawUp = typename remove_reference<_Up>::type;
357         using _UpPtr = _RawUp*;
358         using _RawTp = typename remove_reference<_Tp>::type;
359         using _TpPtr = _RawTp*;
360         using _CheckLValueArg = integral_constant<bool,
361             (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value)
362         ||  is_same<_RawUp, reference_wrapper<_RawTp>>::value
363         ||  is_same<_RawUp, reference_wrapper<typename remove_const<_RawTp>::type>>::value
364         >;
365         return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value)
366             || (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value &&
367                 is_convertible<_UpPtr, _TpPtr>::value);
368     }
369
370     _LIBCPP_INLINE_VISIBILITY
371     constexpr __optional_storage_base() noexcept
372         :  __value_(nullptr) {}
373
374     template <class _UArg>
375     _LIBCPP_INLINE_VISIBILITY
376     constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg)
377         :  __value_(_VSTD::addressof(__uarg))
378     {
379       static_assert(__can_bind_reference<_UArg>(),
380         "Attempted to construct a reference element in tuple from a "
381         "possible temporary");
382     }
383
384     _LIBCPP_INLINE_VISIBILITY
385     void reset() noexcept { __value_ = nullptr; }
386
387     _LIBCPP_INLINE_VISIBILITY
388     constexpr bool has_value() const noexcept
389       { return __value_ != nullptr; }
390
391     _LIBCPP_INLINE_VISIBILITY
392     constexpr value_type& __get() const& noexcept
393       { return *__value_; }
394
395     _LIBCPP_INLINE_VISIBILITY
396     constexpr value_type&& __get() const&& noexcept
397       { return _VSTD::forward<value_type>(*__value_); }
398
399     template <class _UArg>
400     _LIBCPP_INLINE_VISIBILITY
401     void __construct(_UArg&& __val)
402     {
403         _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
404         static_assert(__can_bind_reference<_UArg>(),
405             "Attempted to construct a reference element in tuple from a "
406             "possible temporary");
407         __value_ = _VSTD::addressof(__val);
408     }
409
410     template <class _That>
411     _LIBCPP_INLINE_VISIBILITY
412     void __construct_from(_That&& __opt)
413     {
414         if (__opt.has_value())
415             __construct(_VSTD::forward<_That>(__opt).__get());
416     }
417
418     template <class _That>
419     _LIBCPP_INLINE_VISIBILITY
420     void __assign_from(_That&& __opt)
421     {
422         if (has_value() == __opt.has_value())
423         {
424             if (has_value())
425                 *__value_ = _VSTD::forward<_That>(__opt).__get();
426         }
427         else
428         {
429             if (has_value())
430                 reset();
431             else
432                 __construct(_VSTD::forward<_That>(__opt).__get());
433         }
434     }
435 };
436
437 template <class _Tp, bool = is_trivially_copyable<_Tp>::value>
438 struct __optional_storage;
439
440 template <class _Tp>
441 struct __optional_storage<_Tp, true> : __optional_storage_base<_Tp>
442 {
443     using __optional_storage_base<_Tp>::__optional_storage_base;
444 };
445
446 template <class _Tp>
447 struct __optional_storage<_Tp, false> : __optional_storage_base<_Tp>
448 {
449     using value_type = _Tp;
450     using __optional_storage_base<_Tp>::__optional_storage_base;
451
452     _LIBCPP_INLINE_VISIBILITY
453     __optional_storage() = default;
454
455     _LIBCPP_INLINE_VISIBILITY
456     __optional_storage(const __optional_storage& __opt)
457     {
458         this->__construct_from(__opt);
459     }
460
461     _LIBCPP_INLINE_VISIBILITY
462     __optional_storage(__optional_storage&& __opt)
463         noexcept(is_nothrow_move_constructible_v<value_type>)
464     {
465         this->__construct_from(_VSTD::move(__opt));
466     }
467
468     _LIBCPP_INLINE_VISIBILITY
469     __optional_storage& operator=(const __optional_storage& __opt)
470     {
471         this->__assign_from(__opt);
472         return *this;
473     }
474
475     _LIBCPP_INLINE_VISIBILITY
476     __optional_storage& operator=(__optional_storage&& __opt)
477         noexcept(is_nothrow_move_assignable_v<value_type> &&
478                  is_nothrow_move_constructible_v<value_type>)
479     {
480         this->__assign_from(_VSTD::move(__opt));
481         return *this;
482     }
483 };
484
485 template <class _Tp>
486 using __optional_sfinae_ctor_base_t = __sfinae_ctor_base<
487     is_copy_constructible<_Tp>::value,
488     is_move_constructible<_Tp>::value
489 >;
490
491 template <class _Tp>
492 using __optional_sfinae_assign_base_t = __sfinae_assign_base<
493     (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value),
494     (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value)
495 >;
496
497 template <class _Tp>
498 class optional
499     : private __optional_storage<_Tp>
500     , private __optional_sfinae_ctor_base_t<_Tp>
501     , private __optional_sfinae_assign_base_t<_Tp>
502 {
503     using __base = __optional_storage<_Tp>;
504 public:
505     using value_type = _Tp;
506
507 private:
508      // Disable the reference extension using this static assert.
509     static_assert(!is_same_v<value_type, in_place_t>,
510         "instantiation of optional with in_place_t is ill-formed");
511     static_assert(!is_same_v<__uncvref_t<value_type>, nullopt_t>,
512         "instantiation of optional with nullopt_t is ill-formed");
513     static_assert(!is_reference_v<value_type>,
514         "instantiation of optional with a reference type is ill-formed");
515     static_assert(is_destructible_v<value_type>,
516         "instantiation of optional with a non-destructible type is ill-formed");
517
518     // LWG2756: conditionally explicit conversion from _Up
519     struct _CheckOptionalArgsConstructor {
520       template <class _Up>
521       static constexpr bool __enable_implicit() {
522           return is_constructible_v<_Tp, _Up&&> &&
523                  is_convertible_v<_Up&&, _Tp>;
524       }
525
526       template <class _Up>
527       static constexpr bool __enable_explicit() {
528           return is_constructible_v<_Tp, _Up&&> &&
529                  !is_convertible_v<_Up&&, _Tp>;
530       }
531     };
532     template <class _Up>
533     using _CheckOptionalArgsCtor = conditional_t<
534         !is_same_v<in_place_t, _Up> &&
535         !is_same_v<decay_t<_Up>, optional>,
536         _CheckOptionalArgsConstructor,
537         __check_tuple_constructor_fail
538     >;
539     template <class _QualUp>
540     struct _CheckOptionalLikeConstructor {
541       template <class _Up, class _Opt = optional<_Up>>
542       using __check_constructible_from_opt = __lazy_or<
543           is_constructible<_Tp, _Opt&>,
544           is_constructible<_Tp, _Opt const&>,
545           is_constructible<_Tp, _Opt&&>,
546           is_constructible<_Tp, _Opt const&&>,
547           is_convertible<_Opt&, _Tp>,
548           is_convertible<_Opt const&, _Tp>,
549           is_convertible<_Opt&&, _Tp>,
550           is_convertible<_Opt const&&, _Tp>
551       >;
552       template <class _Up, class _Opt = optional<_Up>>
553       using __check_assignable_from_opt = __lazy_or<
554           is_assignable<_Tp&, _Opt&>,
555           is_assignable<_Tp&, _Opt const&>,
556           is_assignable<_Tp&, _Opt&&>,
557           is_assignable<_Tp&, _Opt const&&>
558       >;
559       template <class _Up, class _QUp = _QualUp>
560       static constexpr bool __enable_implicit() {
561           return is_convertible<_QUp, _Tp>::value &&
562               !__check_constructible_from_opt<_Up>::value;
563       }
564       template <class _Up, class _QUp = _QualUp>
565       static constexpr bool __enable_explicit() {
566           return !is_convertible<_QUp, _Tp>::value &&
567               !__check_constructible_from_opt<_Up>::value;
568       }
569       template <class _Up, class _QUp = _QualUp>
570       static constexpr bool __enable_assign() {
571           // Construction and assignability of _Qup to _Tp has already been
572           // checked.
573           return !__check_constructible_from_opt<_Up>::value &&
574               !__check_assignable_from_opt<_Up>::value;
575       }
576     };
577
578     template <class _Up, class _QualUp>
579     using _CheckOptionalLikeCtor = conditional_t<
580       __lazy_and<
581           __lazy_not<is_same<_Up, _Tp>>,
582           is_constructible<_Tp, _QualUp>
583       >::value,
584       _CheckOptionalLikeConstructor<_QualUp>,
585       __check_tuple_constructor_fail
586     >;
587     template <class _Up, class _QualUp>
588     using _CheckOptionalLikeAssign = conditional_t<
589       __lazy_and<
590           __lazy_not<is_same<_Up, _Tp>>,
591           is_constructible<_Tp, _QualUp>,
592           is_assignable<_Tp&, _QualUp>
593       >::value,
594       _CheckOptionalLikeConstructor<_QualUp>,
595       __check_tuple_constructor_fail
596     >;
597 public:
598
599     _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
600     _LIBCPP_INLINE_VISIBILITY optional(const optional&) = default;
601     _LIBCPP_INLINE_VISIBILITY optional(optional&&) = default;
602     _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
603
604     template <class... _Args, class = enable_if_t<
605         is_constructible_v<value_type, _Args...>>
606     >
607     _LIBCPP_INLINE_VISIBILITY
608     constexpr explicit optional(in_place_t, _Args&&... __args)
609         : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
610
611     template <class _Up, class... _Args, class = enable_if_t<
612         is_constructible_v<value_type, initializer_list<_Up>&, _Args...>>
613     >
614     _LIBCPP_INLINE_VISIBILITY
615     constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
616         : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
617
618     template <class _Up = value_type, enable_if_t<
619         _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>()
620     , int> = 0>
621     _LIBCPP_INLINE_VISIBILITY
622     constexpr optional(_Up&& __v)
623         : __base(in_place, _VSTD::forward<_Up>(__v)) {}
624
625     template <class _Up, enable_if_t<
626         _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>()
627     , int> = 0>
628     _LIBCPP_INLINE_VISIBILITY
629     constexpr explicit optional(_Up&& __v)
630         : __base(in_place, _VSTD::forward<_Up>(__v)) {}
631
632     // LWG2756: conditionally explicit conversion from const optional<_Up>&
633     template <class _Up, enable_if_t<
634         _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>()
635     , int> = 0>
636     _LIBCPP_INLINE_VISIBILITY
637     optional(const optional<_Up>& __v)
638     {
639         this->__construct_from(__v);
640     }
641     template <class _Up, enable_if_t<
642         _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>()
643     , int> = 0>
644     _LIBCPP_INLINE_VISIBILITY
645     explicit optional(const optional<_Up>& __v)
646     {
647         this->__construct_from(__v);
648     }
649
650     // LWG2756: conditionally explicit conversion from optional<_Up>&&
651     template <class _Up, enable_if_t<
652         _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>()
653     , int> = 0>
654     _LIBCPP_INLINE_VISIBILITY
655     optional(optional<_Up>&& __v)
656     {
657         this->__construct_from(_VSTD::move(__v));
658     }
659     template <class _Up, enable_if_t<
660         _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>()
661     , int> = 0>
662     _LIBCPP_INLINE_VISIBILITY
663     explicit optional(optional<_Up>&& __v)
664     {
665         this->__construct_from(_VSTD::move(__v));
666     }
667
668     _LIBCPP_INLINE_VISIBILITY
669     optional& operator=(nullopt_t) noexcept
670     {
671         reset();
672         return *this;
673     }
674
675     _LIBCPP_INLINE_VISIBILITY optional& operator=(const optional&) = default;
676     _LIBCPP_INLINE_VISIBILITY optional& operator=(optional&&) = default;
677
678     // LWG2756
679     template <class _Up = value_type,
680               class = enable_if_t
681                       <__lazy_and<
682                           integral_constant<bool,
683                               !is_same_v<decay_t<_Up>, optional> &&
684                               !(is_same_v<_Up, value_type> && is_scalar_v<value_type>)
685                           >,
686                           is_constructible<value_type, _Up>,
687                           is_assignable<value_type&, _Up>
688                       >::value>
689              >
690     _LIBCPP_INLINE_VISIBILITY
691     optional&
692     operator=(_Up&& __v)
693     {
694         if (this->has_value())
695             this->__get() = _VSTD::forward<_Up>(__v);
696         else
697             this->__construct(_VSTD::forward<_Up>(__v));
698         return *this;
699     }
700
701     // LWG2756
702     template <class _Up, enable_if_t<
703         _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>()
704     , int> = 0>
705     _LIBCPP_INLINE_VISIBILITY
706     optional&
707     operator=(const optional<_Up>& __v)
708     {
709         this->__assign_from(__v);
710         return *this;
711     }
712
713     // LWG2756
714     template <class _Up, enable_if_t<
715         _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>()
716     , int> = 0>
717     _LIBCPP_INLINE_VISIBILITY
718     optional&
719     operator=(optional<_Up>&& __v)
720     {
721         this->__assign_from(_VSTD::move(__v));
722         return *this;
723     }
724
725     template <class... _Args,
726               class = enable_if_t
727                       <
728                           is_constructible_v<value_type, _Args...>
729                       >
730              >
731     _LIBCPP_INLINE_VISIBILITY
732     void
733     emplace(_Args&&... __args)
734     {
735         reset();
736         this->__construct(_VSTD::forward<_Args>(__args)...);
737     }
738
739     template <class _Up, class... _Args,
740               class = enable_if_t
741                       <
742                           is_constructible_v<value_type, initializer_list<_Up>&, _Args...>
743                       >
744              >
745     _LIBCPP_INLINE_VISIBILITY
746     void
747     emplace(initializer_list<_Up> __il, _Args&&... __args)
748     {
749         reset();
750         this->__construct(__il, _VSTD::forward<_Args>(__args)...);
751     }
752
753     _LIBCPP_INLINE_VISIBILITY
754     void swap(optional& __opt)
755         noexcept(is_nothrow_move_constructible_v<value_type> &&
756                  is_nothrow_swappable_v<value_type>)
757     {
758         if (this->has_value() == __opt.has_value())
759         {
760             using _VSTD::swap;
761             if (this->has_value())
762                 swap(this->__get(), __opt.__get());
763         }
764         else
765         {
766             if (this->has_value())
767             {
768                 __opt.__construct(_VSTD::move(this->__get()));
769                 reset();
770             }
771             else
772             {
773                 this->__construct(_VSTD::move(__opt.__get()));
774                 __opt.reset();
775             }
776         }
777     }
778
779     _LIBCPP_INLINE_VISIBILITY
780     constexpr
781     add_pointer_t<value_type const>
782     operator->() const
783     {
784         _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
785 #ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
786         return _VSTD::addressof(this->__get());
787 #else
788         return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
789 #endif
790     }
791
792     _LIBCPP_INLINE_VISIBILITY
793     constexpr
794     add_pointer_t<value_type>
795     operator->()
796     {
797         _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
798 #ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
799         return _VSTD::addressof(this->__get());
800 #else
801         return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
802 #endif
803     }
804
805     _LIBCPP_INLINE_VISIBILITY
806     constexpr
807     const value_type&
808     operator*() const&
809     {
810         _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
811         return this->__get();
812     }
813
814     _LIBCPP_INLINE_VISIBILITY
815     constexpr
816     value_type&
817     operator*() &
818     {
819         _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
820         return this->__get();
821     }
822
823     _LIBCPP_INLINE_VISIBILITY
824     constexpr
825     value_type&&
826     operator*() &&
827     {
828         _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
829         return _VSTD::move(this->__get());
830     }
831
832     _LIBCPP_INLINE_VISIBILITY
833     constexpr
834     const value_type&&
835     operator*() const&&
836     {
837         _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
838         return _VSTD::move(this->__get());
839     }
840
841     _LIBCPP_INLINE_VISIBILITY
842     constexpr explicit operator bool() const noexcept { return has_value(); }
843
844     using __base::has_value;
845     using __base::__get;
846
847     _LIBCPP_INLINE_VISIBILITY
848     constexpr value_type const& value() const&
849     {
850         if (!this->has_value())
851             __throw_bad_optional_access();
852         return this->__get();
853     }
854
855     _LIBCPP_INLINE_VISIBILITY
856     constexpr value_type& value() &
857     {
858         if (!this->has_value())
859             __throw_bad_optional_access();
860         return this->__get();
861     }
862
863     _LIBCPP_INLINE_VISIBILITY
864     constexpr value_type&& value() &&
865     {
866         if (!this->has_value())
867             __throw_bad_optional_access();
868         return _VSTD::move(this->__get());
869     }
870
871     _LIBCPP_INLINE_VISIBILITY
872     constexpr value_type const&& value() const&&
873     {
874         if (!this->has_value())
875             __throw_bad_optional_access();
876         return _VSTD::move(this->__get());
877     }
878
879     template <class _Up>
880     _LIBCPP_INLINE_VISIBILITY
881     constexpr value_type value_or(_Up&& __v) const&
882     {
883         static_assert(is_copy_constructible_v<value_type>,
884                       "optional<T>::value_or: T must be copy constructible");
885         static_assert(is_convertible_v<_Up, value_type>,
886                       "optional<T>::value_or: U must be convertible to T");
887         return this->has_value() ? this->__get() :
888                                   static_cast<value_type>(_VSTD::forward<_Up>(__v));
889     }
890
891     template <class _Up>
892     _LIBCPP_INLINE_VISIBILITY
893     value_type value_or(_Up&& __v) &&
894     {
895         static_assert(is_move_constructible_v<value_type>,
896                       "optional<T>::value_or: T must be move constructible");
897         static_assert(is_convertible_v<_Up, value_type>,
898                       "optional<T>::value_or: U must be convertible to T");
899         return this->has_value() ? _VSTD::move(this->__get()) :
900                                   static_cast<value_type>(_VSTD::forward<_Up>(__v));
901     }
902
903     using __base::reset;
904
905 private:
906     template <class _Up>
907     _LIBCPP_INLINE_VISIBILITY
908     static _Up*
909     __operator_arrow(true_type, _Up& __x)
910     {
911         return _VSTD::addressof(__x);
912     }
913
914     template <class _Up>
915     _LIBCPP_INLINE_VISIBILITY
916     static constexpr _Up*
917     __operator_arrow(false_type, _Up& __x)
918     {
919         return &__x;
920     }
921 };
922
923 // Comparisons between optionals
924 template <class _Tp>
925 _LIBCPP_INLINE_VISIBILITY constexpr
926 enable_if_t<
927     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
928         _VSTD::declval<const _Tp&>()), bool>,
929     bool
930 >
931 operator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
932 {
933     if (static_cast<bool>(__x) != static_cast<bool>(__y))
934         return false;
935     if (!static_cast<bool>(__x))
936         return true;
937     return *__x == *__y;
938 }
939
940 template <class _Tp>
941 _LIBCPP_INLINE_VISIBILITY constexpr
942 enable_if_t<
943     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
944         _VSTD::declval<const _Tp&>()), bool>,
945     bool
946 >
947 operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y)
948 {
949     if (static_cast<bool>(__x) != static_cast<bool>(__y))
950         return true;
951     if (!static_cast<bool>(__x))
952         return false;
953     return *__x != *__y;
954 }
955
956 template <class _Tp>
957 _LIBCPP_INLINE_VISIBILITY constexpr
958 enable_if_t<
959     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
960         _VSTD::declval<const _Tp&>()), bool>,
961     bool
962 >
963 operator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
964 {
965     if (!static_cast<bool>(__y))
966         return false;
967     if (!static_cast<bool>(__x))
968         return true;
969     return *__x < *__y;
970 }
971
972 template <class _Tp>
973 _LIBCPP_INLINE_VISIBILITY constexpr
974 enable_if_t<
975     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
976         _VSTD::declval<const _Tp&>()), bool>,
977     bool
978 >
979 operator>(const optional<_Tp>& __x, const optional<_Tp>& __y)
980 {
981     if (!static_cast<bool>(__x))
982         return false;
983     if (!static_cast<bool>(__y))
984         return true;
985     return *__x > *__y;
986 }
987
988 template <class _Tp>
989 _LIBCPP_INLINE_VISIBILITY constexpr
990 enable_if_t<
991     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
992         _VSTD::declval<const _Tp&>()), bool>,
993     bool
994 >
995 operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y)
996 {
997     if (!static_cast<bool>(__x))
998         return true;
999     if (!static_cast<bool>(__y))
1000         return false;
1001     return *__x <= *__y;
1002 }
1003
1004 template <class _Tp>
1005 _LIBCPP_INLINE_VISIBILITY constexpr
1006 enable_if_t<
1007     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1008         _VSTD::declval<const _Tp&>()), bool>,
1009     bool
1010 >
1011 operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y)
1012 {
1013     if (!static_cast<bool>(__y))
1014         return true;
1015     if (!static_cast<bool>(__x))
1016         return false;
1017     return *__x >= *__y;
1018 }
1019
1020 // Comparisons with nullopt
1021 template <class _Tp>
1022 _LIBCPP_INLINE_VISIBILITY constexpr
1023 bool
1024 operator==(const optional<_Tp>& __x, nullopt_t) noexcept
1025 {
1026     return !static_cast<bool>(__x);
1027 }
1028
1029 template <class _Tp>
1030 _LIBCPP_INLINE_VISIBILITY constexpr
1031 bool
1032 operator==(nullopt_t, const optional<_Tp>& __x) noexcept
1033 {
1034     return !static_cast<bool>(__x);
1035 }
1036
1037 template <class _Tp>
1038 _LIBCPP_INLINE_VISIBILITY constexpr
1039 bool
1040 operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
1041 {
1042     return static_cast<bool>(__x);
1043 }
1044
1045 template <class _Tp>
1046 _LIBCPP_INLINE_VISIBILITY constexpr
1047 bool
1048 operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
1049 {
1050     return static_cast<bool>(__x);
1051 }
1052
1053 template <class _Tp>
1054 _LIBCPP_INLINE_VISIBILITY constexpr
1055 bool
1056 operator<(const optional<_Tp>&, nullopt_t) noexcept
1057 {
1058     return false;
1059 }
1060
1061 template <class _Tp>
1062 _LIBCPP_INLINE_VISIBILITY constexpr
1063 bool
1064 operator<(nullopt_t, const optional<_Tp>& __x) noexcept
1065 {
1066     return static_cast<bool>(__x);
1067 }
1068
1069 template <class _Tp>
1070 _LIBCPP_INLINE_VISIBILITY constexpr
1071 bool
1072 operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
1073 {
1074     return !static_cast<bool>(__x);
1075 }
1076
1077 template <class _Tp>
1078 _LIBCPP_INLINE_VISIBILITY constexpr
1079 bool
1080 operator<=(nullopt_t, const optional<_Tp>&) noexcept
1081 {
1082     return true;
1083 }
1084
1085 template <class _Tp>
1086 _LIBCPP_INLINE_VISIBILITY constexpr
1087 bool
1088 operator>(const optional<_Tp>& __x, nullopt_t) noexcept
1089 {
1090     return static_cast<bool>(__x);
1091 }
1092
1093 template <class _Tp>
1094 _LIBCPP_INLINE_VISIBILITY constexpr
1095 bool
1096 operator>(nullopt_t, const optional<_Tp>&) noexcept
1097 {
1098     return false;
1099 }
1100
1101 template <class _Tp>
1102 _LIBCPP_INLINE_VISIBILITY constexpr
1103 bool
1104 operator>=(const optional<_Tp>&, nullopt_t) noexcept
1105 {
1106     return true;
1107 }
1108
1109 template <class _Tp>
1110 _LIBCPP_INLINE_VISIBILITY constexpr
1111 bool
1112 operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
1113 {
1114     return !static_cast<bool>(__x);
1115 }
1116
1117 // Comparisons with T
1118 template <class _Tp>
1119 _LIBCPP_INLINE_VISIBILITY constexpr
1120 enable_if_t<
1121     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1122         _VSTD::declval<const _Tp&>()), bool>,
1123     bool
1124 >
1125 operator==(const optional<_Tp>& __x, const _Tp& __v)
1126 {
1127     return static_cast<bool>(__x) ? *__x == __v : false;
1128 }
1129
1130 template <class _Tp>
1131 _LIBCPP_INLINE_VISIBILITY constexpr
1132 enable_if_t<
1133     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1134         _VSTD::declval<const _Tp&>()), bool>,
1135     bool
1136 >
1137 operator==(const _Tp& __v, const optional<_Tp>& __x)
1138 {
1139     return static_cast<bool>(__x) ? __v == *__x : false;
1140 }
1141
1142 template <class _Tp>
1143 _LIBCPP_INLINE_VISIBILITY constexpr
1144 enable_if_t<
1145     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1146         _VSTD::declval<const _Tp&>()), bool>,
1147     bool
1148 >
1149 operator!=(const optional<_Tp>& __x, const _Tp& __v)
1150 {
1151     return static_cast<bool>(__x) ? *__x != __v : true;
1152 }
1153
1154 template <class _Tp>
1155 _LIBCPP_INLINE_VISIBILITY constexpr
1156 enable_if_t<
1157     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1158         _VSTD::declval<const _Tp&>()), bool>,
1159     bool
1160 >
1161 operator!=(const _Tp& __v, const optional<_Tp>& __x)
1162 {
1163     return static_cast<bool>(__x) ? __v != *__x : true;
1164 }
1165
1166 template <class _Tp>
1167 _LIBCPP_INLINE_VISIBILITY constexpr
1168 enable_if_t<
1169     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1170         _VSTD::declval<const _Tp&>()), bool>,
1171     bool
1172 >
1173 operator<(const optional<_Tp>& __x, const _Tp& __v)
1174 {
1175     return static_cast<bool>(__x) ? *__x < __v : true;
1176 }
1177
1178 template <class _Tp>
1179 _LIBCPP_INLINE_VISIBILITY constexpr
1180 enable_if_t<
1181     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1182         _VSTD::declval<const _Tp&>()), bool>,
1183     bool
1184 >
1185 operator<(const _Tp& __v, const optional<_Tp>& __x)
1186 {
1187     return static_cast<bool>(__x) ? __v < *__x : false;
1188 }
1189
1190 template <class _Tp>
1191 _LIBCPP_INLINE_VISIBILITY constexpr
1192 enable_if_t<
1193     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1194         _VSTD::declval<const _Tp&>()), bool>,
1195     bool
1196 >
1197 operator<=(const optional<_Tp>& __x, const _Tp& __v)
1198 {
1199     return static_cast<bool>(__x) ? *__x <= __v : true;
1200 }
1201
1202 template <class _Tp>
1203 _LIBCPP_INLINE_VISIBILITY constexpr
1204 enable_if_t<
1205     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1206         _VSTD::declval<const _Tp&>()), bool>,
1207     bool
1208 >
1209 operator<=(const _Tp& __v, const optional<_Tp>& __x)
1210 {
1211     return static_cast<bool>(__x) ? __v <= *__x : false;
1212 }
1213
1214 template <class _Tp>
1215 _LIBCPP_INLINE_VISIBILITY constexpr
1216 enable_if_t<
1217     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1218         _VSTD::declval<const _Tp&>()), bool>,
1219     bool
1220 >
1221 operator>(const optional<_Tp>& __x, const _Tp& __v)
1222 {
1223     return static_cast<bool>(__x) ? *__x > __v : false;
1224 }
1225
1226 template <class _Tp>
1227 _LIBCPP_INLINE_VISIBILITY constexpr
1228 enable_if_t<
1229     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1230         _VSTD::declval<const _Tp&>()), bool>,
1231     bool
1232 >
1233 operator>(const _Tp& __v, const optional<_Tp>& __x)
1234 {
1235     return static_cast<bool>(__x) ? __v > *__x : true;
1236 }
1237
1238 template <class _Tp>
1239 _LIBCPP_INLINE_VISIBILITY constexpr
1240 enable_if_t<
1241     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1242         _VSTD::declval<const _Tp&>()), bool>,
1243     bool
1244 >
1245 operator>=(const optional<_Tp>& __x, const _Tp& __v)
1246 {
1247     return static_cast<bool>(__x) ? *__x >= __v : false;
1248 }
1249
1250 template <class _Tp>
1251 _LIBCPP_INLINE_VISIBILITY constexpr
1252 enable_if_t<
1253     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1254         _VSTD::declval<const _Tp&>()), bool>,
1255     bool
1256 >
1257 operator>=(const _Tp& __v, const optional<_Tp>& __x)
1258 {
1259     return static_cast<bool>(__x) ? __v >= *__x : true;
1260 }
1261
1262
1263 template <class _Tp>
1264 inline _LIBCPP_INLINE_VISIBILITY
1265 enable_if_t<
1266     is_move_constructible_v<_Tp> && is_swappable_v<_Tp>,
1267     void
1268 >
1269 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
1270 {
1271     __x.swap(__y);
1272 }
1273
1274 template <class _Tp>
1275 _LIBCPP_INLINE_VISIBILITY constexpr
1276 optional<decay_t<_Tp>> make_optional(_Tp&& __v)
1277 {
1278     return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v));
1279 }
1280
1281 template <class _Tp, class... _Args>
1282 _LIBCPP_INLINE_VISIBILITY constexpr
1283 optional<_Tp> make_optional(_Args&&... __args)
1284 {
1285     return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...);
1286 }
1287
1288 template <class _Tp, class _Up, class... _Args>
1289 _LIBCPP_INLINE_VISIBILITY constexpr
1290 optional<_Tp> make_optional(initializer_list<_Up> __il,  _Args&&... __args)
1291 {
1292     return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...);
1293 }
1294
1295 template <class _Tp>
1296 struct _LIBCPP_TEMPLATE_VIS hash<optional<_Tp> >
1297 {
1298     typedef optional<_Tp> argument_type;
1299     typedef size_t        result_type;
1300
1301     _LIBCPP_INLINE_VISIBILITY
1302     result_type operator()(const argument_type& __opt) const _NOEXCEPT
1303     {
1304         return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0;
1305     }
1306 };
1307
1308 _LIBCPP_END_NAMESPACE_STD
1309
1310 #endif  // _LIBCPP_STD_VER > 14
1311
1312 #endif  // _LIBCPP_OPTIONAL