root / lab4 / .minix-src / include / c++ / experimental / optional
History | View | Annotate | Download (24 KB)
1 | 13 | up20180614 | // -*- 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 |