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