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