root / lab4 / .minix-src / include / c++ / experimental / optional
History | View | Annotate | Download (24 KB)
1 |
// -*- C++ -*- |
---|---|
2 |
//===-------------------------- optional ----------------------------------===// |
3 |
// |
4 |
// The LLVM Compiler Infrastructure |
5 |
// |
6 |
// This file is dual licensed under the MIT and the University of Illinois Open |
7 |
// Source Licenses. See LICENSE.TXT for details. |
8 |
// |
9 |
//===----------------------------------------------------------------------===// |
10 |
|
11 |
#ifndef _LIBCPP_OPTIONAL |
12 |
#define _LIBCPP_OPTIONAL |
13 |
|
14 |
/* |
15 |
optional synopsis |
16 |
|
17 |
// C++1y |
18 |
|
19 |
namespace std { namespace experimental { inline namespace fundamentals_v1 { |
20 |
|
21 |
// 5.3, optional for object types |
22 |
template <class T> class optional; |
23 |
|
24 |
// 5.4, In-place construction |
25 |
struct in_place_t{}; |
26 |
constexpr in_place_t in_place{}; |
27 |
|
28 |
// 5.5, No-value state indicator |
29 |
struct nullopt_t{see below}; |
30 |
constexpr nullopt_t nullopt(unspecified); |
31 |
|
32 |
// 5.6, Class bad_optional_access |
33 |
class bad_optional_access; |
34 |
|
35 |
// 5.7, Relational operators |
36 |
template <class T> |
37 |
constexpr bool operator==(const optional<T>&, const optional<T>&); |
38 |
template <class T> |
39 |
constexpr bool operator!=(const optional<T>&, const optional<T>&); |
40 |
template <class T> |
41 |
constexpr bool operator<(const optional<T>&, const optional<T>&); |
42 |
template <class T> |
43 |
constexpr bool operator>(const optional<T>&, const optional<T>&); |
44 |
template <class T> |
45 |
constexpr bool operator<=(const optional<T>&, const optional<T>&); |
46 |
template <class T> |
47 |
constexpr bool operator>=(const optional<T>&, const optional<T>&); |
48 |
|
49 |
// 5.8, Comparison with nullopt |
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 |
template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept; |
57 |
template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept; |
58 |
template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept; |
59 |
template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept; |
60 |
template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept; |
61 |
template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept; |
62 |
|
63 |
// 5.9, Comparison with T |
64 |
template <class T> constexpr bool operator==(const optional<T>&, const T&); |
65 |
template <class T> constexpr bool operator==(const T&, const optional<T>&); |
66 |
template <class T> constexpr bool operator!=(const optional<T>&, const T&); |
67 |
template <class T> constexpr bool operator!=(const T&, const optional<T>&); |
68 |
template <class T> constexpr bool operator<(const optional<T>&, const T&); |
69 |
template <class T> constexpr bool operator<(const T&, const optional<T>&); |
70 |
template <class T> constexpr bool operator<=(const optional<T>&, const T&); |
71 |
template <class T> constexpr bool operator<=(const T&, const optional<T>&); |
72 |
template <class T> constexpr bool operator>(const optional<T>&, const T&); |
73 |
template <class T> constexpr bool operator>(const T&, const optional<T>&); |
74 |
template <class T> constexpr bool operator>=(const optional<T>&, const T&); |
75 |
template <class T> constexpr bool operator>=(const T&, const optional<T>&); |
76 |
|
77 |
// 5.10, Specialized algorithms |
78 |
template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below); |
79 |
template <class T> constexpr optional<see below> make_optional(T&&); |
80 |
|
81 |
template <class T> |
82 |
class optional |
83 |
{ |
84 |
public: |
85 |
typedef T value_type; |
86 |
|
87 |
// 5.3.1, Constructors |
88 |
constexpr optional() noexcept; |
89 |
constexpr optional(nullopt_t) noexcept; |
90 |
optional(const optional&); |
91 |
optional(optional&&) noexcept(see below); |
92 |
constexpr optional(const T&); |
93 |
constexpr optional(T&&); |
94 |
template <class... Args> constexpr explicit optional(in_place_t, Args&&...); |
95 |
template <class U, class... Args> |
96 |
constexpr explicit optional(in_place_t, initializer_list<U>, Args&&...); |
97 |
|
98 |
// 5.3.2, Destructor |
99 |
~optional(); |
100 |
|
101 |
// 5.3.3, Assignment |
102 |
optional& operator=(nullopt_t) noexcept; |
103 |
optional& operator=(const optional&); |
104 |
optional& operator=(optional&&) noexcept(see below); |
105 |
template <class U> optional& operator=(U&&); |
106 |
template <class... Args> void emplace(Args&&...); |
107 |
template <class U, class... Args> |
108 |
void emplace(initializer_list<U>, Args&&...); |
109 |
|
110 |
// 5.3.4, Swap |
111 |
void swap(optional&) noexcept(see below); |
112 |
|
113 |
// 5.3.5, Observers |
114 |
constexpr T const* operator ->() const; |
115 |
constexpr T* operator ->(); |
116 |
constexpr T const& operator *() const &; |
117 |
constexpr T& operator *() &; |
118 |
constexpr T&& operator *() &&; |
119 |
constexpr const T&& operator *() const &&; |
120 |
constexpr explicit operator bool() const noexcept; |
121 |
constexpr T const& value() const &; |
122 |
constexpr T& value() &; |
123 |
constexpr T&& value() &&; |
124 |
constexpr const T&& value() const &&; |
125 |
template <class U> constexpr T value_or(U&&) const &; |
126 |
template <class U> constexpr T value_or(U&&) &&; |
127 |
|
128 |
private: |
129 |
T* val; // exposition only |
130 |
}; |
131 |
|
132 |
} // namespace fundamentals_v1 |
133 |
} // namespace experimental |
134 |
|
135 |
// 5.11, Hash support |
136 |
template <class T> struct hash; |
137 |
template <class T> struct hash<experimental::optional<T>>; |
138 |
|
139 |
} // namespace std |
140 |
|
141 |
*/ |
142 |
|
143 |
#include <experimental/__config> |
144 |
#include <functional> |
145 |
#include <stdexcept> |
146 |
|
147 |
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL |
148 |
class _LIBCPP_EXCEPTION_ABI bad_optional_access |
149 |
: public std::logic_error |
150 |
{ |
151 |
public: |
152 |
bad_optional_access() : std::logic_error("Bad optional Access") {} |
153 |
|
154 |
// Get the key function ~bad_optional_access() into the dylib |
155 |
virtual ~bad_optional_access() _NOEXCEPT; |
156 |
}; |
157 |
|
158 |
_LIBCPP_END_NAMESPACE_EXPERIMENTAL |
159 |
|
160 |
|
161 |
#if _LIBCPP_STD_VER > 11 |
162 |
|
163 |
#include <initializer_list> |
164 |
#include <type_traits> |
165 |
#include <new> |
166 |
#include <__functional_base> |
167 |
#include <__undef_min_max> |
168 |
#include <__debug> |
169 |
|
170 |
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
171 |
#pragma GCC system_header |
172 |
#endif |
173 |
|
174 |
_LIBCPP_BEGIN_NAMESPACE_LFTS |
175 |
|
176 |
struct in_place_t {}; |
177 |
constexpr in_place_t in_place{}; |
178 |
|
179 |
struct nullopt_t |
180 |
{ |
181 |
explicit constexpr nullopt_t(int) noexcept {} |
182 |
}; |
183 |
|
184 |
constexpr nullopt_t nullopt{0}; |
185 |
|
186 |
template <class _Tp, bool = is_trivially_destructible<_Tp>::value> |
187 |
class __optional_storage |
188 |
{ |
189 |
protected: |
190 |
typedef _Tp value_type; |
191 |
union |
192 |
{ |
193 |
char __null_state_; |
194 |
value_type __val_; |
195 |
}; |
196 |
bool __engaged_ = false; |
197 |
|
198 |
_LIBCPP_INLINE_VISIBILITY |
199 |
~__optional_storage() |
200 |
{ |
201 |
if (__engaged_) |
202 |
__val_.~value_type(); |
203 |
} |
204 |
|
205 |
_LIBCPP_INLINE_VISIBILITY |
206 |
constexpr __optional_storage() noexcept |
207 |
: __null_state_('\0') {} |
208 |
|
209 |
_LIBCPP_INLINE_VISIBILITY |
210 |
__optional_storage(const __optional_storage& __x) |
211 |
: __engaged_(__x.__engaged_) |
212 |
{ |
213 |
if (__engaged_) |
214 |
::new(_VSTD::addressof(__val_)) value_type(__x.__val_); |
215 |
} |
216 |
|
217 |
_LIBCPP_INLINE_VISIBILITY |
218 |
__optional_storage(__optional_storage&& __x) |
219 |
noexcept(is_nothrow_move_constructible<value_type>::value) |
220 |
: __engaged_(__x.__engaged_) |
221 |
{ |
222 |
if (__engaged_) |
223 |
::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_)); |
224 |
} |
225 |
|
226 |
_LIBCPP_INLINE_VISIBILITY |
227 |
constexpr __optional_storage(const value_type& __v) |
228 |
: __val_(__v), |
229 |
__engaged_(true) {} |
230 |
|
231 |
_LIBCPP_INLINE_VISIBILITY |
232 |
constexpr __optional_storage(value_type&& __v) |
233 |
: __val_(_VSTD::move(__v)), |
234 |
__engaged_(true) {} |
235 |
|
236 |
template <class... _Args> |
237 |
_LIBCPP_INLINE_VISIBILITY |
238 |
constexpr |
239 |
explicit __optional_storage(in_place_t, _Args&&... __args) |
240 |
: __val_(_VSTD::forward<_Args>(__args)...), |
241 |
__engaged_(true) {} |
242 |
}; |
243 |
|
244 |
template <class _Tp> |
245 |
class __optional_storage<_Tp, true> |
246 |
{ |
247 |
protected: |
248 |
typedef _Tp value_type; |
249 |
union |
250 |
{ |
251 |
char __null_state_; |
252 |
value_type __val_; |
253 |
}; |
254 |
bool __engaged_ = false; |
255 |
|
256 |
_LIBCPP_INLINE_VISIBILITY |
257 |
constexpr __optional_storage() noexcept |
258 |
: __null_state_('\0') {} |
259 |
|
260 |
_LIBCPP_INLINE_VISIBILITY |
261 |
__optional_storage(const __optional_storage& __x) |
262 |
: __engaged_(__x.__engaged_) |
263 |
{ |
264 |
if (__engaged_) |
265 |
::new(_VSTD::addressof(__val_)) value_type(__x.__val_); |
266 |
} |
267 |
|
268 |
_LIBCPP_INLINE_VISIBILITY |
269 |
__optional_storage(__optional_storage&& __x) |
270 |
noexcept(is_nothrow_move_constructible<value_type>::value) |
271 |
: __engaged_(__x.__engaged_) |
272 |
{ |
273 |
if (__engaged_) |
274 |
::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_)); |
275 |
} |
276 |
|
277 |
_LIBCPP_INLINE_VISIBILITY |
278 |
constexpr __optional_storage(const value_type& __v) |
279 |
: __val_(__v), |
280 |
__engaged_(true) {} |
281 |
|
282 |
_LIBCPP_INLINE_VISIBILITY |
283 |
constexpr __optional_storage(value_type&& __v) |
284 |
: __val_(_VSTD::move(__v)), |
285 |
__engaged_(true) {} |
286 |
|
287 |
template <class... _Args> |
288 |
_LIBCPP_INLINE_VISIBILITY |
289 |
constexpr |
290 |
explicit __optional_storage(in_place_t, _Args&&... __args) |
291 |
: __val_(_VSTD::forward<_Args>(__args)...), |
292 |
__engaged_(true) {} |
293 |
}; |
294 |
|
295 |
template <class _Tp> |
296 |
class optional |
297 |
: private __optional_storage<_Tp> |
298 |
{ |
299 |
typedef __optional_storage<_Tp> __base; |
300 |
public: |
301 |
typedef _Tp value_type; |
302 |
|
303 |
static_assert(!is_reference<value_type>::value, |
304 |
"Instantiation of optional with a reference type is ill-formed."); |
305 |
static_assert(!is_same<typename remove_cv<value_type>::type, in_place_t>::value, |
306 |
"Instantiation of optional with a in_place_t type is ill-formed."); |
307 |
static_assert(!is_same<typename remove_cv<value_type>::type, nullopt_t>::value, |
308 |
"Instantiation of optional with a nullopt_t type is ill-formed."); |
309 |
static_assert(is_object<value_type>::value, |
310 |
"Instantiation of optional with a non-object type is undefined behavior."); |
311 |
static_assert(is_nothrow_destructible<value_type>::value, |
312 |
"Instantiation of optional with an object type that is not noexcept destructible is undefined behavior."); |
313 |
|
314 |
_LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {} |
315 |
_LIBCPP_INLINE_VISIBILITY optional(const optional&) = default; |
316 |
_LIBCPP_INLINE_VISIBILITY optional(optional&&) = default; |
317 |
_LIBCPP_INLINE_VISIBILITY ~optional() = default; |
318 |
_LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {} |
319 |
_LIBCPP_INLINE_VISIBILITY constexpr optional(const value_type& __v) |
320 |
: __base(__v) {} |
321 |
_LIBCPP_INLINE_VISIBILITY constexpr optional(value_type&& __v) |
322 |
: __base(_VSTD::move(__v)) {} |
323 |
|
324 |
template <class... _Args, |
325 |
class = typename enable_if |
326 |
< |
327 |
is_constructible<value_type, _Args...>::value |
328 |
>::type |
329 |
> |
330 |
_LIBCPP_INLINE_VISIBILITY |
331 |
constexpr |
332 |
explicit optional(in_place_t, _Args&&... __args) |
333 |
: __base(in_place, _VSTD::forward<_Args>(__args)...) {} |
334 |
|
335 |
template <class _Up, class... _Args, |
336 |
class = typename enable_if |
337 |
< |
338 |
is_constructible<value_type, initializer_list<_Up>&, _Args...>::value |
339 |
>::type |
340 |
> |
341 |
_LIBCPP_INLINE_VISIBILITY |
342 |
constexpr |
343 |
explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args) |
344 |
: __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {} |
345 |
|
346 |
_LIBCPP_INLINE_VISIBILITY |
347 |
optional& operator=(nullopt_t) noexcept |
348 |
{ |
349 |
if (this->__engaged_) |
350 |
{ |
351 |
this->__val_.~value_type(); |
352 |
this->__engaged_ = false; |
353 |
} |
354 |
return *this; |
355 |
} |
356 |
|
357 |
_LIBCPP_INLINE_VISIBILITY |
358 |
optional& |
359 |
operator=(const optional& __opt) |
360 |
{ |
361 |
if (this->__engaged_ == __opt.__engaged_) |
362 |
{ |
363 |
if (this->__engaged_) |
364 |
this->__val_ = __opt.__val_; |
365 |
} |
366 |
else |
367 |
{ |
368 |
if (this->__engaged_) |
369 |
this->__val_.~value_type(); |
370 |
else |
371 |
::new(_VSTD::addressof(this->__val_)) value_type(__opt.__val_); |
372 |
this->__engaged_ = __opt.__engaged_; |
373 |
} |
374 |
return *this; |
375 |
} |
376 |
|
377 |
_LIBCPP_INLINE_VISIBILITY |
378 |
optional& |
379 |
operator=(optional&& __opt) |
380 |
noexcept(is_nothrow_move_assignable<value_type>::value && |
381 |
is_nothrow_move_constructible<value_type>::value) |
382 |
{ |
383 |
if (this->__engaged_ == __opt.__engaged_) |
384 |
{ |
385 |
if (this->__engaged_) |
386 |
this->__val_ = _VSTD::move(__opt.__val_); |
387 |
} |
388 |
else |
389 |
{ |
390 |
if (this->__engaged_) |
391 |
this->__val_.~value_type(); |
392 |
else |
393 |
::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_)); |
394 |
this->__engaged_ = __opt.__engaged_; |
395 |
} |
396 |
return *this; |
397 |
} |
398 |
|
399 |
template <class _Up, |
400 |
class = typename enable_if |
401 |
< |
402 |
is_same<typename remove_reference<_Up>::type, value_type>::value && |
403 |
is_constructible<value_type, _Up>::value && |
404 |
is_assignable<value_type&, _Up>::value |
405 |
>::type |
406 |
> |
407 |
_LIBCPP_INLINE_VISIBILITY |
408 |
optional& |
409 |
operator=(_Up&& __v) |
410 |
{ |
411 |
if (this->__engaged_) |
412 |
this->__val_ = _VSTD::forward<_Up>(__v); |
413 |
else |
414 |
{ |
415 |
::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Up>(__v)); |
416 |
this->__engaged_ = true; |
417 |
} |
418 |
return *this; |
419 |
} |
420 |
|
421 |
template <class... _Args, |
422 |
class = typename enable_if |
423 |
< |
424 |
is_constructible<value_type, _Args...>::value |
425 |
>::type |
426 |
> |
427 |
_LIBCPP_INLINE_VISIBILITY |
428 |
void |
429 |
emplace(_Args&&... __args) |
430 |
{ |
431 |
*this = nullopt; |
432 |
::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...); |
433 |
this->__engaged_ = true; |
434 |
} |
435 |
|
436 |
template <class _Up, class... _Args, |
437 |
class = typename enable_if |
438 |
< |
439 |
is_constructible<value_type, initializer_list<_Up>&, _Args...>::value |
440 |
>::type |
441 |
> |
442 |
_LIBCPP_INLINE_VISIBILITY |
443 |
void |
444 |
emplace(initializer_list<_Up> __il, _Args&&... __args) |
445 |
{ |
446 |
*this = nullopt; |
447 |
::new(_VSTD::addressof(this->__val_)) value_type(__il, _VSTD::forward<_Args>(__args)...); |
448 |
this->__engaged_ = true; |
449 |
} |
450 |
|
451 |
_LIBCPP_INLINE_VISIBILITY |
452 |
void |
453 |
swap(optional& __opt) |
454 |
noexcept(is_nothrow_move_constructible<value_type>::value && |
455 |
__is_nothrow_swappable<value_type>::value) |
456 |
{ |
457 |
using _VSTD::swap; |
458 |
if (this->__engaged_ == __opt.__engaged_) |
459 |
{ |
460 |
if (this->__engaged_) |
461 |
swap(this->__val_, __opt.__val_); |
462 |
} |
463 |
else |
464 |
{ |
465 |
if (this->__engaged_) |
466 |
{ |
467 |
::new(_VSTD::addressof(__opt.__val_)) value_type(_VSTD::move(this->__val_)); |
468 |
this->__val_.~value_type(); |
469 |
} |
470 |
else |
471 |
{ |
472 |
::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_)); |
473 |
__opt.__val_.~value_type(); |
474 |
} |
475 |
swap(this->__engaged_, __opt.__engaged_); |
476 |
} |
477 |
} |
478 |
|
479 |
_LIBCPP_INLINE_VISIBILITY |
480 |
constexpr |
481 |
value_type const* |
482 |
operator->() const |
483 |
{ |
484 |
_LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value"); |
485 |
return __operator_arrow(__has_operator_addressof<value_type>{}); |
486 |
} |
487 |
|
488 |
_LIBCPP_INLINE_VISIBILITY |
489 |
value_type* |
490 |
operator->() |
491 |
{ |
492 |
_LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value"); |
493 |
return _VSTD::addressof(this->__val_); |
494 |
} |
495 |
|
496 |
_LIBCPP_INLINE_VISIBILITY |
497 |
constexpr |
498 |
const value_type& |
499 |
operator*() const |
500 |
{ |
501 |
_LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value"); |
502 |
return this->__val_; |
503 |
} |
504 |
|
505 |
_LIBCPP_INLINE_VISIBILITY |
506 |
value_type& |
507 |
operator*() |
508 |
{ |
509 |
_LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value"); |
510 |
return this->__val_; |
511 |
} |
512 |
|
513 |
_LIBCPP_INLINE_VISIBILITY |
514 |
constexpr explicit operator bool() const noexcept {return this->__engaged_;} |
515 |
|
516 |
_LIBCPP_INLINE_VISIBILITY |
517 |
constexpr value_type const& value() const |
518 |
{ |
519 |
if (!this->__engaged_) |
520 |
throw bad_optional_access(); |
521 |
return this->__val_; |
522 |
} |
523 |
|
524 |
_LIBCPP_INLINE_VISIBILITY |
525 |
value_type& value() |
526 |
{ |
527 |
if (!this->__engaged_) |
528 |
throw bad_optional_access(); |
529 |
return this->__val_; |
530 |
} |
531 |
|
532 |
template <class _Up> |
533 |
_LIBCPP_INLINE_VISIBILITY |
534 |
constexpr value_type value_or(_Up&& __v) const& |
535 |
{ |
536 |
static_assert(is_copy_constructible<value_type>::value, |
537 |
"optional<T>::value_or: T must be copy constructible"); |
538 |
static_assert(is_convertible<_Up, value_type>::value, |
539 |
"optional<T>::value_or: U must be convertible to T"); |
540 |
return this->__engaged_ ? this->__val_ : |
541 |
static_cast<value_type>(_VSTD::forward<_Up>(__v)); |
542 |
} |
543 |
|
544 |
template <class _Up> |
545 |
_LIBCPP_INLINE_VISIBILITY |
546 |
value_type value_or(_Up&& __v) && |
547 |
{ |
548 |
static_assert(is_move_constructible<value_type>::value, |
549 |
"optional<T>::value_or: T must be move constructible"); |
550 |
static_assert(is_convertible<_Up, value_type>::value, |
551 |
"optional<T>::value_or: U must be convertible to T"); |
552 |
return this->__engaged_ ? _VSTD::move(this->__val_) : |
553 |
static_cast<value_type>(_VSTD::forward<_Up>(__v)); |
554 |
} |
555 |
|
556 |
private: |
557 |
_LIBCPP_INLINE_VISIBILITY |
558 |
value_type const* |
559 |
__operator_arrow(true_type) const |
560 |
{ |
561 |
return _VSTD::addressof(this->__val_); |
562 |
} |
563 |
|
564 |
_LIBCPP_INLINE_VISIBILITY |
565 |
constexpr |
566 |
value_type const* |
567 |
__operator_arrow(false_type) const |
568 |
{ |
569 |
return &this->__val_; |
570 |
} |
571 |
}; |
572 |
|
573 |
// Comparisons between optionals |
574 |
template <class _Tp> |
575 |
inline _LIBCPP_INLINE_VISIBILITY |
576 |
constexpr |
577 |
bool |
578 |
operator==(const optional<_Tp>& __x, const optional<_Tp>& __y) |
579 |
{ |
580 |
if (static_cast<bool>(__x) != static_cast<bool>(__y)) |
581 |
return false; |
582 |
if (!static_cast<bool>(__x)) |
583 |
return true; |
584 |
return *__x == *__y; |
585 |
} |
586 |
|
587 |
template <class _Tp> |
588 |
inline _LIBCPP_INLINE_VISIBILITY |
589 |
constexpr |
590 |
bool |
591 |
operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y) |
592 |
{ |
593 |
return !(__x == __y); |
594 |
} |
595 |
|
596 |
template <class _Tp> |
597 |
inline _LIBCPP_INLINE_VISIBILITY |
598 |
constexpr |
599 |
bool |
600 |
operator<(const optional<_Tp>& __x, const optional<_Tp>& __y) |
601 |
{ |
602 |
if (!static_cast<bool>(__y)) |
603 |
return false; |
604 |
if (!static_cast<bool>(__x)) |
605 |
return true; |
606 |
return *__x < *__y; |
607 |
} |
608 |
|
609 |
template <class _Tp> |
610 |
inline _LIBCPP_INLINE_VISIBILITY |
611 |
constexpr |
612 |
bool |
613 |
operator>(const optional<_Tp>& __x, const optional<_Tp>& __y) |
614 |
{ |
615 |
return __y < __x; |
616 |
} |
617 |
|
618 |
template <class _Tp> |
619 |
inline _LIBCPP_INLINE_VISIBILITY |
620 |
constexpr |
621 |
bool |
622 |
operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y) |
623 |
{ |
624 |
return !(__y < __x); |
625 |
} |
626 |
|
627 |
template <class _Tp> |
628 |
inline _LIBCPP_INLINE_VISIBILITY |
629 |
constexpr |
630 |
bool |
631 |
operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y) |
632 |
{ |
633 |
return !(__x < __y); |
634 |
} |
635 |
|
636 |
|
637 |
// Comparisons with nullopt |
638 |
template <class _Tp> |
639 |
inline _LIBCPP_INLINE_VISIBILITY |
640 |
constexpr |
641 |
bool |
642 |
operator==(const optional<_Tp>& __x, nullopt_t) noexcept |
643 |
{ |
644 |
return !static_cast<bool>(__x); |
645 |
} |
646 |
|
647 |
template <class _Tp> |
648 |
inline _LIBCPP_INLINE_VISIBILITY |
649 |
constexpr |
650 |
bool |
651 |
operator==(nullopt_t, const optional<_Tp>& __x) noexcept |
652 |
{ |
653 |
return !static_cast<bool>(__x); |
654 |
} |
655 |
|
656 |
template <class _Tp> |
657 |
inline _LIBCPP_INLINE_VISIBILITY |
658 |
constexpr |
659 |
bool |
660 |
operator!=(const optional<_Tp>& __x, nullopt_t) noexcept |
661 |
{ |
662 |
return static_cast<bool>(__x); |
663 |
} |
664 |
|
665 |
template <class _Tp> |
666 |
inline _LIBCPP_INLINE_VISIBILITY |
667 |
constexpr |
668 |
bool |
669 |
operator!=(nullopt_t, const optional<_Tp>& __x) noexcept |
670 |
{ |
671 |
return static_cast<bool>(__x); |
672 |
} |
673 |
|
674 |
template <class _Tp> |
675 |
inline _LIBCPP_INLINE_VISIBILITY |
676 |
constexpr |
677 |
bool |
678 |
operator<(const optional<_Tp>&, nullopt_t) noexcept |
679 |
{ |
680 |
return false; |
681 |
} |
682 |
|
683 |
template <class _Tp> |
684 |
inline _LIBCPP_INLINE_VISIBILITY |
685 |
constexpr |
686 |
bool |
687 |
operator<(nullopt_t, const optional<_Tp>& __x) noexcept |
688 |
{ |
689 |
return static_cast<bool>(__x); |
690 |
} |
691 |
|
692 |
template <class _Tp> |
693 |
inline _LIBCPP_INLINE_VISIBILITY |
694 |
constexpr |
695 |
bool |
696 |
operator<=(const optional<_Tp>& __x, nullopt_t) noexcept |
697 |
{ |
698 |
return !static_cast<bool>(__x); |
699 |
} |
700 |
|
701 |
template <class _Tp> |
702 |
inline _LIBCPP_INLINE_VISIBILITY |
703 |
constexpr |
704 |
bool |
705 |
operator<=(nullopt_t, const optional<_Tp>& __x) noexcept |
706 |
{ |
707 |
return true; |
708 |
} |
709 |
|
710 |
template <class _Tp> |
711 |
inline _LIBCPP_INLINE_VISIBILITY |
712 |
constexpr |
713 |
bool |
714 |
operator>(const optional<_Tp>& __x, nullopt_t) noexcept |
715 |
{ |
716 |
return static_cast<bool>(__x); |
717 |
} |
718 |
|
719 |
template <class _Tp> |
720 |
inline _LIBCPP_INLINE_VISIBILITY |
721 |
constexpr |
722 |
bool |
723 |
operator>(nullopt_t, const optional<_Tp>& __x) noexcept |
724 |
{ |
725 |
return false; |
726 |
} |
727 |
|
728 |
template <class _Tp> |
729 |
inline _LIBCPP_INLINE_VISIBILITY |
730 |
constexpr |
731 |
bool |
732 |
operator>=(const optional<_Tp>&, nullopt_t) noexcept |
733 |
{ |
734 |
return true; |
735 |
} |
736 |
|
737 |
template <class _Tp> |
738 |
inline _LIBCPP_INLINE_VISIBILITY |
739 |
constexpr |
740 |
bool |
741 |
operator>=(nullopt_t, const optional<_Tp>& __x) noexcept |
742 |
{ |
743 |
return !static_cast<bool>(__x); |
744 |
} |
745 |
|
746 |
// Comparisons with T |
747 |
template <class _Tp> |
748 |
inline _LIBCPP_INLINE_VISIBILITY |
749 |
constexpr |
750 |
bool |
751 |
operator==(const optional<_Tp>& __x, const _Tp& __v) |
752 |
{ |
753 |
return static_cast<bool>(__x) ? *__x == __v : false; |
754 |
} |
755 |
|
756 |
template <class _Tp> |
757 |
inline _LIBCPP_INLINE_VISIBILITY |
758 |
constexpr |
759 |
bool |
760 |
operator==(const _Tp& __v, const optional<_Tp>& __x) |
761 |
{ |
762 |
return static_cast<bool>(__x) ? *__x == __v : false; |
763 |
} |
764 |
|
765 |
template <class _Tp> |
766 |
inline _LIBCPP_INLINE_VISIBILITY |
767 |
constexpr |
768 |
bool |
769 |
operator!=(const optional<_Tp>& __x, const _Tp& __v) |
770 |
{ |
771 |
return static_cast<bool>(__x) ? !(*__x == __v) : true; |
772 |
} |
773 |
|
774 |
template <class _Tp> |
775 |
inline _LIBCPP_INLINE_VISIBILITY |
776 |
constexpr |
777 |
bool |
778 |
operator!=(const _Tp& __v, const optional<_Tp>& __x) |
779 |
{ |
780 |
return static_cast<bool>(__x) ? !(*__x == __v) : true; |
781 |
} |
782 |
|
783 |
template <class _Tp> |
784 |
inline _LIBCPP_INLINE_VISIBILITY |
785 |
constexpr |
786 |
bool |
787 |
operator<(const optional<_Tp>& __x, const _Tp& __v) |
788 |
{ |
789 |
return static_cast<bool>(__x) ? less<_Tp>{}(*__x, __v) : true; |
790 |
} |
791 |
|
792 |
template <class _Tp> |
793 |
inline _LIBCPP_INLINE_VISIBILITY |
794 |
constexpr |
795 |
bool |
796 |
operator<(const _Tp& __v, const optional<_Tp>& __x) |
797 |
{ |
798 |
return static_cast<bool>(__x) ? less<_Tp>{}(__v, *__x) : false; |
799 |
} |
800 |
|
801 |
template <class _Tp> |
802 |
inline _LIBCPP_INLINE_VISIBILITY |
803 |
constexpr |
804 |
bool |
805 |
operator<=(const optional<_Tp>& __x, const _Tp& __v) |
806 |
{ |
807 |
return !(__x > __v); |
808 |
} |
809 |
|
810 |
template <class _Tp> |
811 |
inline _LIBCPP_INLINE_VISIBILITY |
812 |
constexpr |
813 |
bool |
814 |
operator<=(const _Tp& __v, const optional<_Tp>& __x) |
815 |
{ |
816 |
return !(__v > __x); |
817 |
} |
818 |
|
819 |
template <class _Tp> |
820 |
inline _LIBCPP_INLINE_VISIBILITY |
821 |
constexpr |
822 |
bool |
823 |
operator>(const optional<_Tp>& __x, const _Tp& __v) |
824 |
{ |
825 |
return static_cast<bool>(__x) ? __v < __x : false; |
826 |
} |
827 |
|
828 |
template <class _Tp> |
829 |
inline _LIBCPP_INLINE_VISIBILITY |
830 |
constexpr |
831 |
bool |
832 |
operator>(const _Tp& __v, const optional<_Tp>& __x) |
833 |
{ |
834 |
return static_cast<bool>(__x) ? __x < __v : true; |
835 |
} |
836 |
|
837 |
template <class _Tp> |
838 |
inline _LIBCPP_INLINE_VISIBILITY |
839 |
constexpr |
840 |
bool |
841 |
operator>=(const optional<_Tp>& __x, const _Tp& __v) |
842 |
{ |
843 |
return !(__x < __v); |
844 |
} |
845 |
|
846 |
template <class _Tp> |
847 |
inline _LIBCPP_INLINE_VISIBILITY |
848 |
constexpr |
849 |
bool |
850 |
operator>=(const _Tp& __v, const optional<_Tp>& __x) |
851 |
{ |
852 |
return !(__v < __x); |
853 |
} |
854 |
|
855 |
|
856 |
template <class _Tp> |
857 |
inline _LIBCPP_INLINE_VISIBILITY |
858 |
void |
859 |
swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) |
860 |
{ |
861 |
__x.swap(__y); |
862 |
} |
863 |
|
864 |
template <class _Tp> |
865 |
inline _LIBCPP_INLINE_VISIBILITY |
866 |
constexpr |
867 |
optional<typename decay<_Tp>::type> |
868 |
make_optional(_Tp&& __v) |
869 |
{ |
870 |
return optional<typename decay<_Tp>::type>(_VSTD::forward<_Tp>(__v)); |
871 |
} |
872 |
|
873 |
_LIBCPP_END_NAMESPACE_LFTS |
874 |
|
875 |
_LIBCPP_BEGIN_NAMESPACE_STD |
876 |
|
877 |
template <class _Tp> |
878 |
struct _LIBCPP_TYPE_VIS_ONLY hash<std::experimental::optional<_Tp> > |
879 |
{ |
880 |
typedef std::experimental::optional<_Tp> argument_type; |
881 |
typedef size_t result_type; |
882 |
|
883 |
_LIBCPP_INLINE_VISIBILITY |
884 |
result_type operator()(const argument_type& __opt) const _NOEXCEPT |
885 |
{ |
886 |
return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0; |
887 |
} |
888 |
}; |
889 |
|
890 |
_LIBCPP_END_NAMESPACE_STD |
891 |
|
892 |
#endif // _LIBCPP_STD_VER > 11 |
893 |
|
894 |
#endif // _LIBCPP_OPTIONAL |