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