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