1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_OPTIONAL
11#define _LIBCPP_OPTIONAL
12
13/*
14 optional synopsis
15
16// C++1z
17
18namespace std {
19 // 23.6.3, optional for object types
20 template <class T> class optional;
21
22 // 23.6.4, no-value state indicator
23 struct nullopt_t{see below };
24 inline constexpr nullopt_t nullopt(unspecified );
25
26 // 23.6.5, class bad_optional_access
27 class bad_optional_access;
28
29 // 23.6.6, relational operators
30 template <class T, class U>
31 constexpr bool operator==(const optional<T>&, const optional<U>&);
32 template <class T, class U>
33 constexpr bool operator!=(const optional<T>&, const optional<U>&);
34 template <class T, class U>
35 constexpr bool operator<(const optional<T>&, const optional<U>&);
36 template <class T, class U>
37 constexpr bool operator>(const optional<T>&, const optional<U>&);
38 template <class T, class U>
39 constexpr bool operator<=(const optional<T>&, const optional<U>&);
40 template <class T, class U>
41 constexpr bool operator>=(const optional<T>&, const optional<U>&);
42
43 // 23.6.7 comparison with nullopt
44 template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
45 template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept;
46 template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept;
47 template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept;
48 template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept;
49 template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept;
50 template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept;
51 template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept;
52 template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept;
53 template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept;
54 template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept;
55 template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept;
56
57 // 23.6.8, comparison with T
58 template <class T, class U> constexpr bool operator==(const optional<T>&, const U&);
59 template <class T, class U> constexpr bool operator==(const T&, const optional<U>&);
60 template <class T, class U> constexpr bool operator!=(const optional<T>&, const U&);
61 template <class T, class U> constexpr bool operator!=(const T&, const optional<U>&);
62 template <class T, class U> constexpr bool operator<(const optional<T>&, const U&);
63 template <class T, class U> constexpr bool operator<(const T&, const optional<U>&);
64 template <class T, class U> constexpr bool operator<=(const optional<T>&, const U&);
65 template <class T, class U> constexpr bool operator<=(const T&, const optional<U>&);
66 template <class T, class U> constexpr bool operator>(const optional<T>&, const U&);
67 template <class T, class U> constexpr bool operator>(const T&, const optional<U>&);
68 template <class T, class U> constexpr bool operator>=(const optional<T>&, const U&);
69 template <class T, class U> constexpr bool operator>=(const T&, const optional<U>&);
70
71 // 23.6.9, specialized algorithms
72 template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below ); // constexpr in C++20
73 template <class T> constexpr optional<see below > make_optional(T&&);
74 template <class T, class... Args>
75 constexpr optional<T> make_optional(Args&&... args);
76 template <class T, class U, class... Args>
77 constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args);
78
79 // 23.6.10, hash support
80 template <class T> struct hash;
81 template <class T> struct hash<optional<T>>;
82
83 template <class T> class optional {
84 public:
85 using value_type = T;
86
87 // 23.6.3.1, constructors
88 constexpr optional() noexcept;
89 constexpr optional(nullopt_t) noexcept;
90 optional(const optional &);
91 optional(optional &&) noexcept(see below);
92 template <class... Args> constexpr explicit optional(in_place_t, Args &&...);
93 template <class U, class... Args>
94 constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...);
95 template <class U = T>
96 constexpr explicit(see-below) optional(U &&);
97 template <class U>
98 explicit(see-below) optional(const optional<U> &); // constexpr in C++20
99 template <class U>
100 explicit(see-below) optional(optional<U> &&); // constexpr in C++20
101
102 // 23.6.3.2, destructor
103 ~optional(); // constexpr in C++20
104
105 // 23.6.3.3, assignment
106 optional &operator=(nullopt_t) noexcept; // constexpr in C++20
107 optional &operator=(const optional &); // constexpr in C++20
108 optional &operator=(optional &&) noexcept(see below); // constexpr in C++20
109 template <class U = T> optional &operator=(U &&); // constexpr in C++20
110 template <class U> optional &operator=(const optional<U> &); // constexpr in C++20
111 template <class U> optional &operator=(optional<U> &&); // constexpr in C++20
112 template <class... Args> T& emplace(Args &&...); // constexpr in C++20
113 template <class U, class... Args>
114 T& emplace(initializer_list<U>, Args &&...); // constexpr in C++20
115
116 // 23.6.3.4, swap
117 void swap(optional &) noexcept(see below ); // constexpr in C++20
118
119 // 23.6.3.5, observers
120 constexpr T const *operator->() const;
121 constexpr T *operator->();
122 constexpr T const &operator*() const &;
123 constexpr T &operator*() &;
124 constexpr T &&operator*() &&;
125 constexpr const T &&operator*() const &&;
126 constexpr explicit operator bool() const noexcept;
127 constexpr bool has_value() const noexcept;
128 constexpr T const &value() const &;
129 constexpr T &value() &;
130 constexpr T &&value() &&;
131 constexpr const T &&value() const &&;
132 template <class U> constexpr T value_or(U &&) const &;
133 template <class U> constexpr T value_or(U &&) &&;
134
135 // [optional.monadic], monadic operations
136 template<class F> constexpr auto and_then(F&& f) &; // since C++23
137 template<class F> constexpr auto and_then(F&& f) &&; // since C++23
138 template<class F> constexpr auto and_then(F&& f) const&; // since C++23
139 template<class F> constexpr auto and_then(F&& f) const&&; // since C++23
140 template<class F> constexpr auto transform(F&& f) &; // since C++23
141 template<class F> constexpr auto transform(F&& f) &&; // since C++23
142 template<class F> constexpr auto transform(F&& f) const&; // since C++23
143 template<class F> constexpr auto transform(F&& f) const&&; // since C++23
144 template<class F> constexpr optional or_else(F&& f) &&; // since C++23
145 template<class F> constexpr optional or_else(F&& f) const&; // since C++23
146
147 // 23.6.3.6, modifiers
148 void reset() noexcept; // constexpr in C++20
149
150 private:
151 T *val; // exposition only
152 };
153
154template<class T>
155 optional(T) -> optional<T>;
156
157} // namespace std
158
159*/
160
161#include <__assert> // all public C++ headers provide the assertion handler
162#include <__availability>
163#include <__concepts/invocable.h>
164#include <__config>
165#include <__functional/hash.h>
166#include <__functional/invoke.h>
167#include <__functional/unary_function.h>
168#include <__memory/construct_at.h>
169#include <__tuple>
170#include <__utility/forward.h>
171#include <__utility/in_place.h>
172#include <__utility/move.h>
173#include <__utility/swap.h>
174#include <initializer_list>
175#include <new>
176#include <stdexcept>
177#include <type_traits>
178#include <version>
179
180#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
181# include <atomic>
182# include <chrono>
183# include <climits>
184# include <concepts>
185# include <ctime>
186# include <iterator>
187# include <memory>
188# include <ratio>
189# include <tuple>
190# include <typeinfo>
191# include <utility>
192# include <variant>
193#endif
194
195// standard-mandated includes
196#include <compare>
197
198#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
199# pragma GCC system_header
200#endif
201
202namespace std // purposefully not using versioning namespace
203{
204
205class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
206 : public exception
207{
208public:
209 // Get the key function ~bad_optional_access() into the dylib
210 virtual ~bad_optional_access() _NOEXCEPT;
211 virtual const char* what() const _NOEXCEPT;
212};
213
214} // namespace std
215
216#if _LIBCPP_STD_VER > 14
217
218_LIBCPP_BEGIN_NAMESPACE_STD
219
220_LIBCPP_NORETURN
221inline _LIBCPP_INLINE_VISIBILITY
222_LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
223void __throw_bad_optional_access() {
224#ifndef _LIBCPP_NO_EXCEPTIONS
225 throw bad_optional_access();
226#else
227 _VSTD::abort();
228#endif
229}
230
231struct nullopt_t
232{
233 struct __secret_tag { _LIBCPP_INLINE_VISIBILITY explicit __secret_tag() = default; };
234 _LIBCPP_INLINE_VISIBILITY constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {}
235};
236
237inline constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}};
238
239struct __optional_construct_from_invoke_tag {};
240
241template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
242struct __optional_destruct_base;
243
244template <class _Tp>
245struct __optional_destruct_base<_Tp, false>
246{
247 typedef _Tp value_type;
248 static_assert(is_object_v<value_type>,
249 "instantiation of optional with a non-object type is undefined behavior");
250 union
251 {
252 char __null_state_;
253 value_type __val_;
254 };
255 bool __engaged_;
256
257 _LIBCPP_INLINE_VISIBILITY
258 _LIBCPP_CONSTEXPR_AFTER_CXX17 ~__optional_destruct_base()
259 {
260 if (__engaged_)
261 __val_.~value_type();
262 }
263
264 _LIBCPP_INLINE_VISIBILITY
265 constexpr __optional_destruct_base() noexcept
266 : __null_state_(),
267 __engaged_(false) {}
268
269 template <class... _Args>
270 _LIBCPP_INLINE_VISIBILITY
271 constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
272 : __val_(_VSTD::forward<_Args>(__args)...),
273 __engaged_(true) {}
274
275#if _LIBCPP_STD_VER > 20
276 template <class _Fp, class... _Args>
277 _LIBCPP_HIDE_FROM_ABI
278 constexpr __optional_destruct_base(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
279 : __val_(_VSTD::invoke(_VSTD::forward<_Fp>(__f), _VSTD::forward<_Args>(__args)...)), __engaged_(true) {}
280#endif
281
282 _LIBCPP_INLINE_VISIBILITY
283 _LIBCPP_CONSTEXPR_AFTER_CXX17 void reset() noexcept
284 {
285 if (__engaged_)
286 {
287 __val_.~value_type();
288 __engaged_ = false;
289 }
290 }
291};
292
293template <class _Tp>
294struct __optional_destruct_base<_Tp, true>
295{
296 typedef _Tp value_type;
297 static_assert(is_object_v<value_type>,
298 "instantiation of optional with a non-object type is undefined behavior");
299 union
300 {
301 char __null_state_;
302 value_type __val_;
303 };
304 bool __engaged_;
305
306 _LIBCPP_INLINE_VISIBILITY
307 constexpr __optional_destruct_base() noexcept
308 : __null_state_(),
309 __engaged_(false) {}
310
311 template <class... _Args>
312 _LIBCPP_INLINE_VISIBILITY
313 constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
314 : __val_(_VSTD::forward<_Args>(__args)...),
315 __engaged_(true) {}
316
317#if _LIBCPP_STD_VER > 20
318 template <class _Fp, class... _Args>
319 _LIBCPP_HIDE_FROM_ABI
320 constexpr __optional_destruct_base(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
321 : __val_(_VSTD::invoke(_VSTD::forward<_Fp>(__f), _VSTD::forward<_Args>(__args)...)), __engaged_(true) {}
322#endif
323
324 _LIBCPP_INLINE_VISIBILITY
325 _LIBCPP_CONSTEXPR_AFTER_CXX17 void reset() noexcept
326 {
327 if (__engaged_)
328 {
329 __engaged_ = false;
330 }
331 }
332};
333
334template <class _Tp, bool = is_reference<_Tp>::value>
335struct __optional_storage_base : __optional_destruct_base<_Tp>
336{
337 using __base = __optional_destruct_base<_Tp>;
338 using value_type = _Tp;
339 using __base::__base;
340
341 _LIBCPP_INLINE_VISIBILITY
342 constexpr bool has_value() const noexcept
343 {
344 return this->__engaged_;
345 }
346
347 _LIBCPP_INLINE_VISIBILITY
348 constexpr value_type& __get() & noexcept
349 {
350 return this->__val_;
351 }
352 _LIBCPP_INLINE_VISIBILITY
353 constexpr const value_type& __get() const& noexcept
354 {
355 return this->__val_;
356 }
357 _LIBCPP_INLINE_VISIBILITY
358 constexpr value_type&& __get() && noexcept
359 {
360 return _VSTD::move(this->__val_);
361 }
362 _LIBCPP_INLINE_VISIBILITY
363 constexpr const value_type&& __get() const&& noexcept
364 {
365 return _VSTD::move(this->__val_);
366 }
367
368 template <class... _Args>
369 _LIBCPP_INLINE_VISIBILITY
370 _LIBCPP_CONSTEXPR_AFTER_CXX17 void __construct(_Args&&... __args)
371 {
372 _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
373#if _LIBCPP_STD_VER > 17
374 _VSTD::construct_at(_VSTD::addressof(this->__val_), _VSTD::forward<_Args>(__args)...);
375#else
376 ::new ((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
377#endif
378 this->__engaged_ = true;
379 }
380
381 template <class _That>
382 _LIBCPP_INLINE_VISIBILITY
383 _LIBCPP_CONSTEXPR_AFTER_CXX17 void __construct_from(_That&& __opt)
384 {
385 if (__opt.has_value())
386 __construct(_VSTD::forward<_That>(__opt).__get());
387 }
388
389 template <class _That>
390 _LIBCPP_INLINE_VISIBILITY
391 _LIBCPP_CONSTEXPR_AFTER_CXX17 void __assign_from(_That&& __opt)
392 {
393 if (this->__engaged_ == __opt.has_value())
394 {
395 if (this->__engaged_)
396 this->__val_ = _VSTD::forward<_That>(__opt).__get();
397 }
398 else
399 {
400 if (this->__engaged_)
401 this->reset();
402 else
403 __construct(_VSTD::forward<_That>(__opt).__get());
404 }
405 }
406};
407
408// optional<T&> is currently required to be ill-formed. However, it may
409// be allowed in the future. For this reason, it has already been implemented
410// to ensure we can make the change in an ABI-compatible manner.
411template <class _Tp>
412struct __optional_storage_base<_Tp, true>
413{
414 using value_type = _Tp;
415 using __raw_type = remove_reference_t<_Tp>;
416 __raw_type* __value_;
417
418 template <class _Up>
419 static constexpr bool __can_bind_reference() {
420 using _RawUp = typename remove_reference<_Up>::type;
421 using _UpPtr = _RawUp*;
422 using _RawTp = typename remove_reference<_Tp>::type;
423 using _TpPtr = _RawTp*;
424 using _CheckLValueArg = integral_constant<bool,
425 (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value)
426 || is_same<_RawUp, reference_wrapper<_RawTp>>::value
427 || is_same<_RawUp, reference_wrapper<typename remove_const<_RawTp>::type>>::value
428 >;
429 return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value)
430 || (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value &&
431 is_convertible<_UpPtr, _TpPtr>::value);
432 }
433
434 _LIBCPP_INLINE_VISIBILITY
435 constexpr __optional_storage_base() noexcept
436 : __value_(nullptr) {}
437
438 template <class _UArg>
439 _LIBCPP_INLINE_VISIBILITY
440 constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg)
441 : __value_(_VSTD::addressof(__uarg))
442 {
443 static_assert(__can_bind_reference<_UArg>(),
444 "Attempted to construct a reference element in tuple from a "
445 "possible temporary");
446 }
447
448 _LIBCPP_INLINE_VISIBILITY
449 _LIBCPP_CONSTEXPR_AFTER_CXX17 void reset() noexcept { __value_ = nullptr; }
450
451 _LIBCPP_INLINE_VISIBILITY
452 constexpr bool has_value() const noexcept
453 { return __value_ != nullptr; }
454
455 _LIBCPP_INLINE_VISIBILITY
456 constexpr value_type& __get() const& noexcept
457 { return *__value_; }
458
459 _LIBCPP_INLINE_VISIBILITY
460 constexpr value_type&& __get() const&& noexcept
461 { return _VSTD::forward<value_type>(*__value_); }
462
463 template <class _UArg>
464 _LIBCPP_INLINE_VISIBILITY
465 _LIBCPP_CONSTEXPR_AFTER_CXX17 void __construct(_UArg&& __val)
466 {
467 _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
468 static_assert(__can_bind_reference<_UArg>(),
469 "Attempted to construct a reference element in tuple from a "
470 "possible temporary");
471 __value_ = _VSTD::addressof(__val);
472 }
473
474 template <class _That>
475 _LIBCPP_INLINE_VISIBILITY
476 _LIBCPP_CONSTEXPR_AFTER_CXX17 void __construct_from(_That&& __opt)
477 {
478 if (__opt.has_value())
479 __construct(_VSTD::forward<_That>(__opt).__get());
480 }
481
482 template <class _That>
483 _LIBCPP_INLINE_VISIBILITY
484 _LIBCPP_CONSTEXPR_AFTER_CXX17 void __assign_from(_That&& __opt)
485 {
486 if (has_value() == __opt.has_value())
487 {
488 if (has_value())
489 *__value_ = _VSTD::forward<_That>(__opt).__get();
490 }
491 else
492 {
493 if (has_value())
494 reset();
495 else
496 __construct(_VSTD::forward<_That>(__opt).__get());
497 }
498 }
499};
500
501template <class _Tp, bool = is_trivially_copy_constructible<_Tp>::value>
502struct __optional_copy_base : __optional_storage_base<_Tp>
503{
504 using __optional_storage_base<_Tp>::__optional_storage_base;
505};
506
507template <class _Tp>
508struct __optional_copy_base<_Tp, false> : __optional_storage_base<_Tp>
509{
510 using __optional_storage_base<_Tp>::__optional_storage_base;
511
512 _LIBCPP_INLINE_VISIBILITY
513 __optional_copy_base() = default;
514
515 _LIBCPP_INLINE_VISIBILITY
516 _LIBCPP_CONSTEXPR_AFTER_CXX17 __optional_copy_base(const __optional_copy_base& __opt)
517 {
518 this->__construct_from(__opt);
519 }
520
521 _LIBCPP_INLINE_VISIBILITY
522 __optional_copy_base(__optional_copy_base&&) = default;
523 _LIBCPP_INLINE_VISIBILITY
524 __optional_copy_base& operator=(const __optional_copy_base&) = default;
525 _LIBCPP_INLINE_VISIBILITY
526 __optional_copy_base& operator=(__optional_copy_base&&) = default;
527};
528
529template <class _Tp, bool = is_trivially_move_constructible<_Tp>::value>
530struct __optional_move_base : __optional_copy_base<_Tp>
531{
532 using __optional_copy_base<_Tp>::__optional_copy_base;
533};
534
535template <class _Tp>
536struct __optional_move_base<_Tp, false> : __optional_copy_base<_Tp>
537{
538 using value_type = _Tp;
539 using __optional_copy_base<_Tp>::__optional_copy_base;
540
541 _LIBCPP_INLINE_VISIBILITY
542 __optional_move_base() = default;
543 _LIBCPP_INLINE_VISIBILITY
544 __optional_move_base(const __optional_move_base&) = default;
545
546 _LIBCPP_INLINE_VISIBILITY
547 _LIBCPP_CONSTEXPR_AFTER_CXX17 __optional_move_base(__optional_move_base&& __opt)
548 noexcept(is_nothrow_move_constructible_v<value_type>)
549 {
550 this->__construct_from(_VSTD::move(__opt));
551 }
552
553 _LIBCPP_INLINE_VISIBILITY
554 __optional_move_base& operator=(const __optional_move_base&) = default;
555 _LIBCPP_INLINE_VISIBILITY
556 __optional_move_base& operator=(__optional_move_base&&) = default;
557};
558
559template <class _Tp, bool =
560 is_trivially_destructible<_Tp>::value &&
561 is_trivially_copy_constructible<_Tp>::value &&
562 is_trivially_copy_assignable<_Tp>::value>
563struct __optional_copy_assign_base : __optional_move_base<_Tp>
564{
565 using __optional_move_base<_Tp>::__optional_move_base;
566};
567
568template <class _Tp>
569struct __optional_copy_assign_base<_Tp, false> : __optional_move_base<_Tp>
570{
571 using __optional_move_base<_Tp>::__optional_move_base;
572
573 _LIBCPP_INLINE_VISIBILITY
574 __optional_copy_assign_base() = default;
575 _LIBCPP_INLINE_VISIBILITY
576 __optional_copy_assign_base(const __optional_copy_assign_base&) = default;
577 _LIBCPP_INLINE_VISIBILITY
578 __optional_copy_assign_base(__optional_copy_assign_base&&) = default;
579
580 _LIBCPP_INLINE_VISIBILITY
581 _LIBCPP_CONSTEXPR_AFTER_CXX17 __optional_copy_assign_base& operator=(const __optional_copy_assign_base& __opt)
582 {
583 this->__assign_from(__opt);
584 return *this;
585 }
586
587 _LIBCPP_INLINE_VISIBILITY
588 __optional_copy_assign_base& operator=(__optional_copy_assign_base&&) = default;
589};
590
591template <class _Tp, bool =
592 is_trivially_destructible<_Tp>::value &&
593 is_trivially_move_constructible<_Tp>::value &&
594 is_trivially_move_assignable<_Tp>::value>
595struct __optional_move_assign_base : __optional_copy_assign_base<_Tp>
596{
597 using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
598};
599
600template <class _Tp>
601struct __optional_move_assign_base<_Tp, false> : __optional_copy_assign_base<_Tp>
602{
603 using value_type = _Tp;
604 using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
605
606 _LIBCPP_INLINE_VISIBILITY
607 __optional_move_assign_base() = default;
608 _LIBCPP_INLINE_VISIBILITY
609 __optional_move_assign_base(const __optional_move_assign_base& __opt) = default;
610 _LIBCPP_INLINE_VISIBILITY
611 __optional_move_assign_base(__optional_move_assign_base&&) = default;
612 _LIBCPP_INLINE_VISIBILITY
613 __optional_move_assign_base& operator=(const __optional_move_assign_base&) = default;
614
615 _LIBCPP_INLINE_VISIBILITY
616 _LIBCPP_CONSTEXPR_AFTER_CXX17 __optional_move_assign_base& operator=(__optional_move_assign_base&& __opt)
617 noexcept(is_nothrow_move_assignable_v<value_type> &&
618 is_nothrow_move_constructible_v<value_type>)
619 {
620 this->__assign_from(_VSTD::move(__opt));
621 return *this;
622 }
623};
624
625template <class _Tp>
626using __optional_sfinae_ctor_base_t = __sfinae_ctor_base<
627 is_copy_constructible<_Tp>::value,
628 is_move_constructible<_Tp>::value
629>;
630
631template <class _Tp>
632using __optional_sfinae_assign_base_t = __sfinae_assign_base<
633 (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value),
634 (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value)
635>;
636
637template<class _Tp>
638class optional;
639template <class _Tp>
640struct __is_std_optional : false_type {};
641template <class _Tp> struct __is_std_optional<optional<_Tp>> : true_type {};
642
643template <class _Tp>
644class optional
645 : private __optional_move_assign_base<_Tp>
646 , private __optional_sfinae_ctor_base_t<_Tp>
647 , private __optional_sfinae_assign_base_t<_Tp>
648{
649 using __base = __optional_move_assign_base<_Tp>;
650public:
651 using value_type = _Tp;
652
653private:
654 // Disable the reference extension using this static assert.
655 static_assert(!is_same_v<__uncvref_t<value_type>, in_place_t>,
656 "instantiation of optional with in_place_t is ill-formed");
657 static_assert(!is_same_v<__uncvref_t<value_type>, nullopt_t>,
658 "instantiation of optional with nullopt_t is ill-formed");
659 static_assert(!is_reference_v<value_type>,
660 "instantiation of optional with a reference type is ill-formed");
661 static_assert(is_destructible_v<value_type>,
662 "instantiation of optional with a non-destructible type is ill-formed");
663 static_assert(!is_array_v<value_type>,
664 "instantiation of optional with an array type is ill-formed");
665
666 // LWG2756: conditionally explicit conversion from _Up
667 struct _CheckOptionalArgsConstructor {
668 template <class _Up>
669 static constexpr bool __enable_implicit() {
670 return is_constructible_v<_Tp, _Up&&> &&
671 is_convertible_v<_Up&&, _Tp>;
672 }
673
674 template <class _Up>
675 static constexpr bool __enable_explicit() {
676 return is_constructible_v<_Tp, _Up&&> &&
677 !is_convertible_v<_Up&&, _Tp>;
678 }
679 };
680 template <class _Up>
681 using _CheckOptionalArgsCtor = _If<
682 _IsNotSame<__uncvref_t<_Up>, in_place_t>::value &&
683 _IsNotSame<__uncvref_t<_Up>, optional>::value,
684 _CheckOptionalArgsConstructor,
685 __check_tuple_constructor_fail
686 >;
687 template <class _QualUp>
688 struct _CheckOptionalLikeConstructor {
689 template <class _Up, class _Opt = optional<_Up>>
690 using __check_constructible_from_opt = _Or<
691 is_constructible<_Tp, _Opt&>,
692 is_constructible<_Tp, _Opt const&>,
693 is_constructible<_Tp, _Opt&&>,
694 is_constructible<_Tp, _Opt const&&>,
695 is_convertible<_Opt&, _Tp>,
696 is_convertible<_Opt const&, _Tp>,
697 is_convertible<_Opt&&, _Tp>,
698 is_convertible<_Opt const&&, _Tp>
699 >;
700 template <class _Up, class _Opt = optional<_Up>>
701 using __check_assignable_from_opt = _Or<
702 is_assignable<_Tp&, _Opt&>,
703 is_assignable<_Tp&, _Opt const&>,
704 is_assignable<_Tp&, _Opt&&>,
705 is_assignable<_Tp&, _Opt const&&>
706 >;
707 template <class _Up, class _QUp = _QualUp>
708 static constexpr bool __enable_implicit() {
709 return is_convertible<_QUp, _Tp>::value &&
710 !__check_constructible_from_opt<_Up>::value;
711 }
712 template <class _Up, class _QUp = _QualUp>
713 static constexpr bool __enable_explicit() {
714 return !is_convertible<_QUp, _Tp>::value &&
715 !__check_constructible_from_opt<_Up>::value;
716 }
717 template <class _Up, class _QUp = _QualUp>
718 static constexpr bool __enable_assign() {
719 // Construction and assignability of _QUp to _Tp has already been
720 // checked.
721 return !__check_constructible_from_opt<_Up>::value &&
722 !__check_assignable_from_opt<_Up>::value;
723 }
724 };
725
726 template <class _Up, class _QualUp>
727 using _CheckOptionalLikeCtor = _If<
728 _And<
729 _IsNotSame<_Up, _Tp>,
730 is_constructible<_Tp, _QualUp>
731 >::value,
732 _CheckOptionalLikeConstructor<_QualUp>,
733 __check_tuple_constructor_fail
734 >;
735 template <class _Up, class _QualUp>
736 using _CheckOptionalLikeAssign = _If<
737 _And<
738 _IsNotSame<_Up, _Tp>,
739 is_constructible<_Tp, _QualUp>,
740 is_assignable<_Tp&, _QualUp>
741 >::value,
742 _CheckOptionalLikeConstructor<_QualUp>,
743 __check_tuple_constructor_fail
744 >;
745
746public:
747
748 _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
749 _LIBCPP_INLINE_VISIBILITY constexpr optional(const optional&) = default;
750 _LIBCPP_INLINE_VISIBILITY constexpr optional(optional&&) = default;
751 _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
752
753 template <class _InPlaceT, class... _Args, class = enable_if_t<
754 _And<
755 _IsSame<_InPlaceT, in_place_t>,
756 is_constructible<value_type, _Args...>
757 >::value
758 >
759 >
760 _LIBCPP_INLINE_VISIBILITY
761 constexpr explicit optional(_InPlaceT, _Args&&... __args)
762 : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
763
764 template <class _Up, class... _Args, class = enable_if_t<
765 is_constructible_v<value_type, initializer_list<_Up>&, _Args...>>
766 >
767 _LIBCPP_INLINE_VISIBILITY
768 constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
769 : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
770
771 template <class _Up = value_type, enable_if_t<
772 _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>()
773 , int> = 0>
774 _LIBCPP_INLINE_VISIBILITY
775 constexpr optional(_Up&& __v)
776 : __base(in_place, _VSTD::forward<_Up>(__v)) {}
777
778 template <class _Up, enable_if_t<
779 _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>()
780 , int> = 0>
781 _LIBCPP_INLINE_VISIBILITY
782 constexpr explicit optional(_Up&& __v)
783 : __base(in_place, _VSTD::forward<_Up>(__v)) {}
784
785 // LWG2756: conditionally explicit conversion from const optional<_Up>&
786 template <class _Up, enable_if_t<
787 _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>()
788 , int> = 0>
789 _LIBCPP_INLINE_VISIBILITY
790 _LIBCPP_CONSTEXPR_AFTER_CXX17 optional(const optional<_Up>& __v)
791 {
792 this->__construct_from(__v);
793 }
794 template <class _Up, enable_if_t<
795 _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>()
796 , int> = 0>
797 _LIBCPP_INLINE_VISIBILITY
798 _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit optional(const optional<_Up>& __v)
799 {
800 this->__construct_from(__v);
801 }
802
803 // LWG2756: conditionally explicit conversion from optional<_Up>&&
804 template <class _Up, enable_if_t<
805 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>()
806 , int> = 0>
807 _LIBCPP_INLINE_VISIBILITY
808 _LIBCPP_CONSTEXPR_AFTER_CXX17 optional(optional<_Up>&& __v)
809 {
810 this->__construct_from(_VSTD::move(__v));
811 }
812 template <class _Up, enable_if_t<
813 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>()
814 , int> = 0>
815 _LIBCPP_INLINE_VISIBILITY
816 _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit optional(optional<_Up>&& __v)
817 {
818 this->__construct_from(_VSTD::move(__v));
819 }
820
821#if _LIBCPP_STD_VER > 20
822 template<class _Fp, class... _Args>
823 _LIBCPP_HIDE_FROM_ABI
824 constexpr explicit optional(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
825 : __base(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Fp>(__f), _VSTD::forward<_Args>(__args)...) {
826 }
827#endif
828
829 _LIBCPP_INLINE_VISIBILITY
830 _LIBCPP_CONSTEXPR_AFTER_CXX17 optional& operator=(nullopt_t) noexcept
831 {
832 reset();
833 return *this;
834 }
835
836 _LIBCPP_INLINE_VISIBILITY optional& operator=(const optional&) = default;
837 _LIBCPP_INLINE_VISIBILITY optional& operator=(optional&&) = default;
838
839 // LWG2756
840 template <class _Up = value_type,
841 class = enable_if_t<
842 _And<
843 _IsNotSame<__uncvref_t<_Up>, optional>,
844 _Or<
845 _IsNotSame<__uncvref_t<_Up>, value_type>,
846 _Not<is_scalar<value_type>>
847 >,
848 is_constructible<value_type, _Up>,
849 is_assignable<value_type&, _Up>
850 >::value>
851 >
852 _LIBCPP_INLINE_VISIBILITY
853 _LIBCPP_CONSTEXPR_AFTER_CXX17 optional&
854 operator=(_Up&& __v)
855 {
856 if (this->has_value())
857 this->__get() = _VSTD::forward<_Up>(__v);
858 else
859 this->__construct(_VSTD::forward<_Up>(__v));
860 return *this;
861 }
862
863 // LWG2756
864 template <class _Up, enable_if_t<
865 _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>()
866 , int> = 0>
867 _LIBCPP_INLINE_VISIBILITY
868 _LIBCPP_CONSTEXPR_AFTER_CXX17 optional&
869 operator=(const optional<_Up>& __v)
870 {
871 this->__assign_from(__v);
872 return *this;
873 }
874
875 // LWG2756
876 template <class _Up, enable_if_t<
877 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>()
878 , int> = 0>
879 _LIBCPP_INLINE_VISIBILITY
880 _LIBCPP_CONSTEXPR_AFTER_CXX17 optional&
881 operator=(optional<_Up>&& __v)
882 {
883 this->__assign_from(_VSTD::move(__v));
884 return *this;
885 }
886
887 template <class... _Args,
888 class = enable_if_t
889 <
890 is_constructible_v<value_type, _Args...>
891 >
892 >
893 _LIBCPP_INLINE_VISIBILITY
894 _LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp &
895 emplace(_Args&&... __args)
896 {
897 reset();
898 this->__construct(_VSTD::forward<_Args>(__args)...);
899 return this->__get();
900 }
901
902 template <class _Up, class... _Args,
903 class = enable_if_t
904 <
905 is_constructible_v<value_type, initializer_list<_Up>&, _Args...>
906 >
907 >
908 _LIBCPP_INLINE_VISIBILITY
909 _LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp &
910 emplace(initializer_list<_Up> __il, _Args&&... __args)
911 {
912 reset();
913 this->__construct(__il, _VSTD::forward<_Args>(__args)...);
914 return this->__get();
915 }
916
917 _LIBCPP_INLINE_VISIBILITY
918 _LIBCPP_CONSTEXPR_AFTER_CXX17 void swap(optional& __opt)
919 noexcept(is_nothrow_move_constructible_v<value_type> &&
920 is_nothrow_swappable_v<value_type>)
921 {
922 if (this->has_value() == __opt.has_value())
923 {
924 using _VSTD::swap;
925 if (this->has_value())
926 swap(this->__get(), __opt.__get());
927 }
928 else
929 {
930 if (this->has_value())
931 {
932 __opt.__construct(_VSTD::move(this->__get()));
933 reset();
934 }
935 else
936 {
937 this->__construct(_VSTD::move(__opt.__get()));
938 __opt.reset();
939 }
940 }
941 }
942
943 _LIBCPP_INLINE_VISIBILITY
944 constexpr
945 add_pointer_t<value_type const>
946 operator->() const
947 {
948 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called on a disengaged value");
949 return _VSTD::addressof(this->__get());
950 }
951
952 _LIBCPP_INLINE_VISIBILITY
953 constexpr
954 add_pointer_t<value_type>
955 operator->()
956 {
957 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called on a disengaged value");
958 return _VSTD::addressof(this->__get());
959 }
960
961 _LIBCPP_INLINE_VISIBILITY
962 constexpr
963 const value_type&
964 operator*() const& noexcept
965 {
966 _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
967 return this->__get();
968 }
969
970 _LIBCPP_INLINE_VISIBILITY
971 constexpr
972 value_type&
973 operator*() & noexcept
974 {
975 _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
976 return this->__get();
977 }
978
979 _LIBCPP_INLINE_VISIBILITY
980 constexpr
981 value_type&&
982 operator*() && noexcept
983 {
984 _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
985 return _VSTD::move(this->__get());
986 }
987
988 _LIBCPP_INLINE_VISIBILITY
989 constexpr
990 const value_type&&
991 operator*() const&& noexcept
992 {
993 _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
994 return _VSTD::move(this->__get());
995 }
996
997 _LIBCPP_INLINE_VISIBILITY
998 constexpr explicit operator bool() const noexcept { return has_value(); }
999
1000 using __base::has_value;
1001 using __base::__get;
1002
1003 _LIBCPP_INLINE_VISIBILITY
1004 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1005 constexpr value_type const& value() const&
1006 {
1007 if (!this->has_value())
1008 __throw_bad_optional_access();
1009 return this->__get();
1010 }
1011
1012 _LIBCPP_INLINE_VISIBILITY
1013 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1014 constexpr value_type& value() &
1015 {
1016 if (!this->has_value())
1017 __throw_bad_optional_access();
1018 return this->__get();
1019 }
1020
1021 _LIBCPP_INLINE_VISIBILITY
1022 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1023 constexpr value_type&& value() &&
1024 {
1025 if (!this->has_value())
1026 __throw_bad_optional_access();
1027 return _VSTD::move(this->__get());
1028 }
1029
1030 _LIBCPP_INLINE_VISIBILITY
1031 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1032 constexpr value_type const&& value() const&&
1033 {
1034 if (!this->has_value())
1035 __throw_bad_optional_access();
1036 return _VSTD::move(this->__get());
1037 }
1038
1039 template <class _Up>
1040 _LIBCPP_INLINE_VISIBILITY
1041 constexpr value_type value_or(_Up&& __v) const&
1042 {
1043 static_assert(is_copy_constructible_v<value_type>,
1044 "optional<T>::value_or: T must be copy constructible");
1045 static_assert(is_convertible_v<_Up, value_type>,
1046 "optional<T>::value_or: U must be convertible to T");
1047 return this->has_value() ? this->__get() :
1048 static_cast<value_type>(_VSTD::forward<_Up>(__v));
1049 }
1050
1051 template <class _Up>
1052 _LIBCPP_INLINE_VISIBILITY
1053 constexpr value_type value_or(_Up&& __v) &&
1054 {
1055 static_assert(is_move_constructible_v<value_type>,
1056 "optional<T>::value_or: T must be move constructible");
1057 static_assert(is_convertible_v<_Up, value_type>,
1058 "optional<T>::value_or: U must be convertible to T");
1059 return this->has_value() ? _VSTD::move(this->__get()) :
1060 static_cast<value_type>(_VSTD::forward<_Up>(__v));
1061 }
1062
1063#if _LIBCPP_STD_VER > 20
1064 template<class _Func>
1065 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1066 constexpr auto and_then(_Func&& __f) & {
1067 using _Up = invoke_result_t<_Func, value_type&>;
1068 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
1069 "Result of f(value()) must be a specialization of std::optional");
1070 if (*this)
1071 return _VSTD::invoke(_VSTD::forward<_Func>(__f), value());
1072 return remove_cvref_t<_Up>();
1073 }
1074
1075 template<class _Func>
1076 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1077 constexpr auto and_then(_Func&& __f) const& {
1078 using _Up = invoke_result_t<_Func, const value_type&>;
1079 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
1080 "Result of f(value()) must be a specialization of std::optional");
1081 if (*this)
1082 return _VSTD::invoke(_VSTD::forward<_Func>(__f), value());
1083 return remove_cvref_t<_Up>();
1084 }
1085
1086 template<class _Func>
1087 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1088 constexpr auto and_then(_Func&& __f) && {
1089 using _Up = invoke_result_t<_Func, value_type&&>;
1090 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
1091 "Result of f(std::move(value())) must be a specialization of std::optional");
1092 if (*this)
1093 return _VSTD::invoke(_VSTD::forward<_Func>(__f), _VSTD::move(value()));
1094 return remove_cvref_t<_Up>();
1095 }
1096
1097 template<class _Func>
1098 _LIBCPP_HIDE_FROM_ABI
1099 constexpr auto and_then(_Func&& __f) const&& {
1100 using _Up = invoke_result_t<_Func, const value_type&&>;
1101 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
1102 "Result of f(std::move(value())) must be a specialization of std::optional");
1103 if (*this)
1104 return _VSTD::invoke(_VSTD::forward<_Func>(__f), _VSTD::move(value()));
1105 return remove_cvref_t<_Up>();
1106 }
1107
1108 template<class _Func>
1109 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1110 constexpr auto transform(_Func&& __f) & {
1111 using _Up = remove_cv_t<invoke_result_t<_Func, value_type&>>;
1112 static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array");
1113 static_assert(!is_same_v<_Up, in_place_t>,
1114 "Result of f(value()) should not be std::in_place_t");
1115 static_assert(!is_same_v<_Up, nullopt_t>,
1116 "Result of f(value()) should not be std::nullopt_t");
1117 static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type");
1118 if (*this)
1119 return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), value());
1120 return optional<_Up>();
1121 }
1122
1123 template<class _Func>
1124 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1125 constexpr auto transform(_Func&& __f) const& {
1126 using _Up = remove_cv_t<invoke_result_t<_Func, const value_type&>>;
1127 static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array");
1128 static_assert(!is_same_v<_Up, in_place_t>,
1129 "Result of f(value()) should not be std::in_place_t");
1130 static_assert(!is_same_v<_Up, nullopt_t>,
1131 "Result of f(value()) should not be std::nullopt_t");
1132 static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type");
1133 if (*this)
1134 return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), value());
1135 return optional<_Up>();
1136 }
1137
1138 template<class _Func>
1139 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1140 constexpr auto transform(_Func&& __f) && {
1141 using _Up = remove_cv_t<invoke_result_t<_Func, value_type&&>>;
1142 static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array");
1143 static_assert(!is_same_v<_Up, in_place_t>,
1144 "Result of f(std::move(value())) should not be std::in_place_t");
1145 static_assert(!is_same_v<_Up, nullopt_t>,
1146 "Result of f(std::move(value())) should not be std::nullopt_t");
1147 static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type");
1148 if (*this)
1149 return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), _VSTD::move(value()));
1150 return optional<_Up>();
1151 }
1152
1153 template<class _Func>
1154 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1155 constexpr auto transform(_Func&& __f) const&& {
1156 using _Up = remove_cvref_t<invoke_result_t<_Func, const value_type&&>>;
1157 static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array");
1158 static_assert(!is_same_v<_Up, in_place_t>,
1159 "Result of f(std::move(value())) should not be std::in_place_t");
1160 static_assert(!is_same_v<_Up, nullopt_t>,
1161 "Result of f(std::move(value())) should not be std::nullopt_t");
1162 static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type");
1163 if (*this)
1164 return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), _VSTD::move(value()));
1165 return optional<_Up>();
1166 }
1167
1168 template<invocable _Func>
1169 _LIBCPP_HIDE_FROM_ABI
1170 constexpr optional or_else(_Func&& __f) const& requires is_copy_constructible_v<value_type> {
1171 static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>,
1172 "Result of f() should be the same type as this optional");
1173 if (*this)
1174 return *this;
1175 return _VSTD::forward<_Func>(__f)();
1176 }
1177
1178 template<invocable _Func>
1179 _LIBCPP_HIDE_FROM_ABI
1180 constexpr optional or_else(_Func&& __f) && requires is_move_constructible_v<value_type> {
1181 static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>,
1182 "Result of f() should be the same type as this optional");
1183 if (*this)
1184 return _VSTD::move(*this);
1185 return _VSTD::forward<_Func>(__f)();
1186 }
1187#endif // _LIBCPP_STD_VER > 20
1188
1189 using __base::reset;
1190};
1191
1192#if _LIBCPP_STD_VER >= 17
1193template<class _Tp>
1194 optional(_Tp) -> optional<_Tp>;
1195#endif
1196
1197// Comparisons between optionals
1198template <class _Tp, class _Up>
1199_LIBCPP_INLINE_VISIBILITY constexpr
1200enable_if_t<
1201 is_convertible_v<decltype(declval<const _Tp&>() ==
1202 declval<const _Up&>()), bool>,
1203 bool
1204>
1205operator==(const optional<_Tp>& __x, const optional<_Up>& __y)
1206{
1207 if (static_cast<bool>(__x) != static_cast<bool>(__y))
1208 return false;
1209 if (!static_cast<bool>(__x))
1210 return true;
1211 return *__x == *__y;
1212}
1213
1214template <class _Tp, class _Up>
1215_LIBCPP_INLINE_VISIBILITY constexpr
1216enable_if_t<
1217 is_convertible_v<decltype(declval<const _Tp&>() !=
1218 declval<const _Up&>()), bool>,
1219 bool
1220>
1221operator!=(const optional<_Tp>& __x, const optional<_Up>& __y)
1222{
1223 if (static_cast<bool>(__x) != static_cast<bool>(__y))
1224 return true;
1225 if (!static_cast<bool>(__x))
1226 return false;
1227 return *__x != *__y;
1228}
1229
1230template <class _Tp, class _Up>
1231_LIBCPP_INLINE_VISIBILITY constexpr
1232enable_if_t<
1233 is_convertible_v<decltype(declval<const _Tp&>() <
1234 declval<const _Up&>()), bool>,
1235 bool
1236>
1237operator<(const optional<_Tp>& __x, const optional<_Up>& __y)
1238{
1239 if (!static_cast<bool>(__y))
1240 return false;
1241 if (!static_cast<bool>(__x))
1242 return true;
1243 return *__x < *__y;
1244}
1245
1246template <class _Tp, class _Up>
1247_LIBCPP_INLINE_VISIBILITY constexpr
1248enable_if_t<
1249 is_convertible_v<decltype(declval<const _Tp&>() >
1250 declval<const _Up&>()), bool>,
1251 bool
1252>
1253operator>(const optional<_Tp>& __x, const optional<_Up>& __y)
1254{
1255 if (!static_cast<bool>(__x))
1256 return false;
1257 if (!static_cast<bool>(__y))
1258 return true;
1259 return *__x > *__y;
1260}
1261
1262template <class _Tp, class _Up>
1263_LIBCPP_INLINE_VISIBILITY constexpr
1264enable_if_t<
1265 is_convertible_v<decltype(declval<const _Tp&>() <=
1266 declval<const _Up&>()), bool>,
1267 bool
1268>
1269operator<=(const optional<_Tp>& __x, const optional<_Up>& __y)
1270{
1271 if (!static_cast<bool>(__x))
1272 return true;
1273 if (!static_cast<bool>(__y))
1274 return false;
1275 return *__x <= *__y;
1276}
1277
1278template <class _Tp, class _Up>
1279_LIBCPP_INLINE_VISIBILITY constexpr
1280enable_if_t<
1281 is_convertible_v<decltype(declval<const _Tp&>() >=
1282 declval<const _Up&>()), bool>,
1283 bool
1284>
1285operator>=(const optional<_Tp>& __x, const optional<_Up>& __y)
1286{
1287 if (!static_cast<bool>(__y))
1288 return true;
1289 if (!static_cast<bool>(__x))
1290 return false;
1291 return *__x >= *__y;
1292}
1293
1294// Comparisons with nullopt
1295template <class _Tp>
1296_LIBCPP_INLINE_VISIBILITY constexpr
1297bool
1298operator==(const optional<_Tp>& __x, nullopt_t) noexcept
1299{
1300 return !static_cast<bool>(__x);
1301}
1302
1303template <class _Tp>
1304_LIBCPP_INLINE_VISIBILITY constexpr
1305bool
1306operator==(nullopt_t, const optional<_Tp>& __x) noexcept
1307{
1308 return !static_cast<bool>(__x);
1309}
1310
1311template <class _Tp>
1312_LIBCPP_INLINE_VISIBILITY constexpr
1313bool
1314operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
1315{
1316 return static_cast<bool>(__x);
1317}
1318
1319template <class _Tp>
1320_LIBCPP_INLINE_VISIBILITY constexpr
1321bool
1322operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
1323{
1324 return static_cast<bool>(__x);
1325}
1326
1327template <class _Tp>
1328_LIBCPP_INLINE_VISIBILITY constexpr
1329bool
1330operator<(const optional<_Tp>&, nullopt_t) noexcept
1331{
1332 return false;
1333}
1334
1335template <class _Tp>
1336_LIBCPP_INLINE_VISIBILITY constexpr
1337bool
1338operator<(nullopt_t, const optional<_Tp>& __x) noexcept
1339{
1340 return static_cast<bool>(__x);
1341}
1342
1343template <class _Tp>
1344_LIBCPP_INLINE_VISIBILITY constexpr
1345bool
1346operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
1347{
1348 return !static_cast<bool>(__x);
1349}
1350
1351template <class _Tp>
1352_LIBCPP_INLINE_VISIBILITY constexpr
1353bool
1354operator<=(nullopt_t, const optional<_Tp>&) noexcept
1355{
1356 return true;
1357}
1358
1359template <class _Tp>
1360_LIBCPP_INLINE_VISIBILITY constexpr
1361bool
1362operator>(const optional<_Tp>& __x, nullopt_t) noexcept
1363{
1364 return static_cast<bool>(__x);
1365}
1366
1367template <class _Tp>
1368_LIBCPP_INLINE_VISIBILITY constexpr
1369bool
1370operator>(nullopt_t, const optional<_Tp>&) noexcept
1371{
1372 return false;
1373}
1374
1375template <class _Tp>
1376_LIBCPP_INLINE_VISIBILITY constexpr
1377bool
1378operator>=(const optional<_Tp>&, nullopt_t) noexcept
1379{
1380 return true;
1381}
1382
1383template <class _Tp>
1384_LIBCPP_INLINE_VISIBILITY constexpr
1385bool
1386operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
1387{
1388 return !static_cast<bool>(__x);
1389}
1390
1391// Comparisons with T
1392template <class _Tp, class _Up>
1393_LIBCPP_INLINE_VISIBILITY constexpr
1394enable_if_t<
1395 is_convertible_v<decltype(declval<const _Tp&>() ==
1396 declval<const _Up&>()), bool>,
1397 bool
1398>
1399operator==(const optional<_Tp>& __x, const _Up& __v)
1400{
1401 return static_cast<bool>(__x) ? *__x == __v : false;
1402}
1403
1404template <class _Tp, class _Up>
1405_LIBCPP_INLINE_VISIBILITY constexpr
1406enable_if_t<
1407 is_convertible_v<decltype(declval<const _Tp&>() ==
1408 declval<const _Up&>()), bool>,
1409 bool
1410>
1411operator==(const _Tp& __v, const optional<_Up>& __x)
1412{
1413 return static_cast<bool>(__x) ? __v == *__x : false;
1414}
1415
1416template <class _Tp, class _Up>
1417_LIBCPP_INLINE_VISIBILITY constexpr
1418enable_if_t<
1419 is_convertible_v<decltype(declval<const _Tp&>() !=
1420 declval<const _Up&>()), bool>,
1421 bool
1422>
1423operator!=(const optional<_Tp>& __x, const _Up& __v)
1424{
1425 return static_cast<bool>(__x) ? *__x != __v : true;
1426}
1427
1428template <class _Tp, class _Up>
1429_LIBCPP_INLINE_VISIBILITY constexpr
1430enable_if_t<
1431 is_convertible_v<decltype(declval<const _Tp&>() !=
1432 declval<const _Up&>()), bool>,
1433 bool
1434>
1435operator!=(const _Tp& __v, const optional<_Up>& __x)
1436{
1437 return static_cast<bool>(__x) ? __v != *__x : true;
1438}
1439
1440template <class _Tp, class _Up>
1441_LIBCPP_INLINE_VISIBILITY constexpr
1442enable_if_t<
1443 is_convertible_v<decltype(declval<const _Tp&>() <
1444 declval<const _Up&>()), bool>,
1445 bool
1446>
1447operator<(const optional<_Tp>& __x, const _Up& __v)
1448{
1449 return static_cast<bool>(__x) ? *__x < __v : true;
1450}
1451
1452template <class _Tp, class _Up>
1453_LIBCPP_INLINE_VISIBILITY constexpr
1454enable_if_t<
1455 is_convertible_v<decltype(declval<const _Tp&>() <
1456 declval<const _Up&>()), bool>,
1457 bool
1458>
1459operator<(const _Tp& __v, const optional<_Up>& __x)
1460{
1461 return static_cast<bool>(__x) ? __v < *__x : false;
1462}
1463
1464template <class _Tp, class _Up>
1465_LIBCPP_INLINE_VISIBILITY constexpr
1466enable_if_t<
1467 is_convertible_v<decltype(declval<const _Tp&>() <=
1468 declval<const _Up&>()), bool>,
1469 bool
1470>
1471operator<=(const optional<_Tp>& __x, const _Up& __v)
1472{
1473 return static_cast<bool>(__x) ? *__x <= __v : true;
1474}
1475
1476template <class _Tp, class _Up>
1477_LIBCPP_INLINE_VISIBILITY constexpr
1478enable_if_t<
1479 is_convertible_v<decltype(declval<const _Tp&>() <=
1480 declval<const _Up&>()), bool>,
1481 bool
1482>
1483operator<=(const _Tp& __v, const optional<_Up>& __x)
1484{
1485 return static_cast<bool>(__x) ? __v <= *__x : false;
1486}
1487
1488template <class _Tp, class _Up>
1489_LIBCPP_INLINE_VISIBILITY constexpr
1490enable_if_t<
1491 is_convertible_v<decltype(declval<const _Tp&>() >
1492 declval<const _Up&>()), bool>,
1493 bool
1494>
1495operator>(const optional<_Tp>& __x, const _Up& __v)
1496{
1497 return static_cast<bool>(__x) ? *__x > __v : false;
1498}
1499
1500template <class _Tp, class _Up>
1501_LIBCPP_INLINE_VISIBILITY constexpr
1502enable_if_t<
1503 is_convertible_v<decltype(declval<const _Tp&>() >
1504 declval<const _Up&>()), bool>,
1505 bool
1506>
1507operator>(const _Tp& __v, const optional<_Up>& __x)
1508{
1509 return static_cast<bool>(__x) ? __v > *__x : true;
1510}
1511
1512template <class _Tp, class _Up>
1513_LIBCPP_INLINE_VISIBILITY constexpr
1514enable_if_t<
1515 is_convertible_v<decltype(declval<const _Tp&>() >=
1516 declval<const _Up&>()), bool>,
1517 bool
1518>
1519operator>=(const optional<_Tp>& __x, const _Up& __v)
1520{
1521 return static_cast<bool>(__x) ? *__x >= __v : false;
1522}
1523
1524template <class _Tp, class _Up>
1525_LIBCPP_INLINE_VISIBILITY constexpr
1526enable_if_t<
1527 is_convertible_v<decltype(declval<const _Tp&>() >=
1528 declval<const _Up&>()), bool>,
1529 bool
1530>
1531operator>=(const _Tp& __v, const optional<_Up>& __x)
1532{
1533 return static_cast<bool>(__x) ? __v >= *__x : true;
1534}
1535
1536
1537template <class _Tp>
1538inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1539enable_if_t<
1540 is_move_constructible_v<_Tp> && is_swappable_v<_Tp>,
1541 void
1542>
1543swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
1544{
1545 __x.swap(__y);
1546}
1547
1548template <class _Tp>
1549_LIBCPP_INLINE_VISIBILITY constexpr
1550optional<decay_t<_Tp>> make_optional(_Tp&& __v)
1551{
1552 return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v));
1553}
1554
1555template <class _Tp, class... _Args>
1556_LIBCPP_INLINE_VISIBILITY constexpr
1557optional<_Tp> make_optional(_Args&&... __args)
1558{
1559 return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...);
1560}
1561
1562template <class _Tp, class _Up, class... _Args>
1563_LIBCPP_INLINE_VISIBILITY constexpr
1564optional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args)
1565{
1566 return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...);
1567}
1568
1569template <class _Tp>
1570struct _LIBCPP_TEMPLATE_VIS hash<
1571 __enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>>
1572>
1573{
1574#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
1575 _LIBCPP_DEPRECATED_IN_CXX17 typedef optional<_Tp> argument_type;
1576 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
1577#endif
1578
1579 _LIBCPP_INLINE_VISIBILITY
1580 size_t operator()(const optional<_Tp>& __opt) const
1581 {
1582 return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0;
1583 }
1584};
1585
1586_LIBCPP_END_NAMESPACE_STD
1587
1588#endif // _LIBCPP_STD_VER > 14
1589
1590#endif // _LIBCPP_OPTIONAL
1591

source code of flutter_engine/third_party/libcxx/include/optional