Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: third_party/libcxx/include/optional

Issue 75213003: Add libc++ and libc++abi to third-party. (Closed) Base URL: https://src.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 #include <initializer_list>
20
21 namespace std
22 {
23
24 // optional for object types
25 template <class T>
26 class optional
27 {
28 public:
29 typedef T value_type;
30
31 // constructors
32 constexpr optional() noexcept;
33 constexpr optional(nullopt_t) noexcept;
34 optional(const optional&);
35 optional(optional&&) noexcept(is_nothrow_move_constructible<T>::value);
36 constexpr optional(const T&);
37 constexpr optional(T&&);
38 template <class... Args> constexpr explicit optional(in_place_t, Args&&...);
39 template <class U, class... Args>
40 constexpr explicit optional(in_place_t, initializer_list<U>, Args&&...);
41
42 // destructor
43 ~optional();
44
45 // assignment
46 optional& operator=(nullopt_t) noexcept;
47 optional& operator=(const optional&);
48 optional& operator=(optional&&)
49 noexcept(is_nothrow_move_assignable<T>::value &&
50 is_nothrow_move_constructible<T>::value);
51 template <class U> optional& operator=(U&&);
52 template <class... Args> void emplace(Args&&...);
53 template <class U, class... Args> void emplace(initializer_list<U>, Args&&.. .);
54
55 // swap
56 void swap(optional&)
57 noexcept(is_nothrow_move_constructible<T>::value &&
58 noexcept(swap(declval<T&>(), declval<T&>())));
59
60 // observers
61 constexpr T const* operator->() const;
62 T* operator->();
63 constexpr T const& operator*() const;
64 T& operator*();
65 constexpr explicit operator bool() const noexcept;
66 constexpr T const& value() const;
67 T& value();
68 template <class U> constexpr T value_or(U&&) const&;
69 template <class U> T value_or(U&&) &&;
70 };
71
72 // In-place construction
73 struct in_place_t{};
74 constexpr in_place_t in_place{};
75
76 // Disengaged state indicator
77 struct nullopt_t{see below};
78 constexpr nullopt_t nullopt(unspecified);
79
80 // class bad_optional_access
81 class bad_optional_access
82 : public logic_error
83 {
84 public:
85 explicit bad_optional_access(const string& what_arg);
86 explicit bad_optional_access(const char* what_arg);
87 };
88
89 // Relational operators
90 template <class T> constexpr bool operator==(const optional<T>&, const optional< T>&);
91 template <class T> constexpr bool operator< (const optional<T>&, const optional< T>&);
92
93 // Comparison with nullopt
94 template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noex cept;
95 template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noex cept;
96 template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexc ept;
97 template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexc ept;
98
99 // Comparison with T
100 template <class T> constexpr bool operator==(const optional<T>&, const T&);
101 template <class T> constexpr bool operator==(const T&, const optional<T>&);
102 template <class T> constexpr bool operator<(const optional<T>&, const T&);
103 template <class T> constexpr bool operator<(const T&, const optional<T>&);
104
105 // Specialized algorithms
106 template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below);
107 template <class T> constexpr optional<typename decay<T>::type> make_optional(T&& );
108
109 // hash support
110 template <class T> struct hash;
111 template <class T> struct hash<optional<T>>;
112
113 } // std
114
115 */
116
117 #include <__config>
118 #include <functional>
119 #include <stdexcept>
120
121 namespace std // purposefully not using versioning namespace
122 {
123
124 class _LIBCPP_EXCEPTION_ABI bad_optional_access
125 : public logic_error
126 {
127 public:
128 #if _LIBCPP_STD_VER > 11
129 _LIBCPP_INLINE_VISIBILITY explicit bad_optional_access(const string& __arg)
130 : logic_error(__arg) {}
131 _LIBCPP_INLINE_VISIBILITY explicit bad_optional_access(const char* __arg)
132 : logic_error(__arg) {}
133 _LIBCPP_INLINE_VISIBILITY bad_optional_access(const bad_optional_access&) no except = default;
134 _LIBCPP_INLINE_VISIBILITY bad_optional_access& operator=(const bad_optional_ access&) noexcept = default;
135 #else
136 private:
137 bad_optional_access(const bad_optional_access&);
138 bad_optional_access& operator=(const bad_optional_access&);
139 public:
140 #endif // _LIBCPP_STD_VER > 11
141 // Get the key function ~bad_optional_access() into the dylib even if not co mpiling for C++1y
142 virtual ~bad_optional_access() _NOEXCEPT;
143 };
144
145 } // std
146
147 #if _LIBCPP_STD_VER > 11
148
149 #include <initializer_list>
150 #include <type_traits>
151 #include <new>
152 #include <__functional_base>
153
154 #include <__undef_min_max>
155
156 #ifdef _LIBCPP_DEBUG
157 # include <__debug>
158 #else
159 # define _LIBCPP_ASSERT(x, m) ((void)0)
160 #endif
161
162 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
163 #pragma GCC system_header
164 #endif
165
166 _LIBCPP_BEGIN_NAMESPACE_STD
167
168 struct in_place_t {};
169 constexpr in_place_t in_place{};
170
171 struct nullopt_t
172 {
173 explicit constexpr nullopt_t(int) noexcept {}
174 };
175
176 constexpr nullopt_t nullopt{0};
177
178 template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
179 class __optional_storage
180 {
181 protected:
182 typedef _Tp value_type;
183 union
184 {
185 char __null_state_;
186 value_type __val_;
187 };
188 bool __engaged_ = false;
189
190 _LIBCPP_INLINE_VISIBILITY
191 ~__optional_storage()
192 {
193 if (__engaged_)
194 __val_.~value_type();
195 }
196
197 _LIBCPP_INLINE_VISIBILITY
198 constexpr __optional_storage() noexcept
199 : __null_state_('\0') {}
200
201 _LIBCPP_INLINE_VISIBILITY
202 __optional_storage(const __optional_storage& __x)
203 : __engaged_(__x.__engaged_)
204 {
205 if (__engaged_)
206 ::new(_VSTD::addressof(__val_)) value_type(__x.__val_);
207 }
208
209 _LIBCPP_INLINE_VISIBILITY
210 __optional_storage(__optional_storage&& __x)
211 noexcept(is_nothrow_move_constructible<value_type>::value)
212 : __engaged_(__x.__engaged_)
213 {
214 if (__engaged_)
215 ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val _));
216 }
217
218 _LIBCPP_INLINE_VISIBILITY
219 constexpr __optional_storage(const value_type& __v)
220 : __val_(__v),
221 __engaged_(true) {}
222
223 _LIBCPP_INLINE_VISIBILITY
224 constexpr __optional_storage(value_type&& __v)
225 : __val_(_VSTD::move(__v)),
226 __engaged_(true) {}
227
228 template <class... _Args>
229 _LIBCPP_INLINE_VISIBILITY
230 constexpr
231 explicit __optional_storage(in_place_t, _Args&&... __args)
232 : __val_(_VSTD::forward<_Args>(__args)...),
233 __engaged_(true) {}
234 };
235
236 template <class _Tp>
237 class __optional_storage<_Tp, true>
238 {
239 protected:
240 typedef _Tp value_type;
241 union
242 {
243 char __null_state_;
244 value_type __val_;
245 };
246 bool __engaged_ = false;
247
248 _LIBCPP_INLINE_VISIBILITY
249 constexpr __optional_storage() noexcept
250 : __null_state_('\0') {}
251
252 _LIBCPP_INLINE_VISIBILITY
253 __optional_storage(const __optional_storage& __x)
254 : __engaged_(__x.__engaged_)
255 {
256 if (__engaged_)
257 ::new(_VSTD::addressof(__val_)) value_type(__x.__val_);
258 }
259
260 _LIBCPP_INLINE_VISIBILITY
261 __optional_storage(__optional_storage&& __x)
262 noexcept(is_nothrow_move_constructible<value_type>::value)
263 : __engaged_(__x.__engaged_)
264 {
265 if (__engaged_)
266 ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val _));
267 }
268
269 _LIBCPP_INLINE_VISIBILITY
270 constexpr __optional_storage(const value_type& __v)
271 : __val_(__v),
272 __engaged_(true) {}
273
274 _LIBCPP_INLINE_VISIBILITY
275 constexpr __optional_storage(value_type&& __v)
276 : __val_(_VSTD::move(__v)),
277 __engaged_(true) {}
278
279 template <class... _Args>
280 _LIBCPP_INLINE_VISIBILITY
281 constexpr
282 explicit __optional_storage(in_place_t, _Args&&... __args)
283 : __val_(_VSTD::forward<_Args>(__args)...),
284 __engaged_(true) {}
285 };
286
287 template <class _Tp>
288 class optional
289 : private __optional_storage<_Tp>
290 {
291 typedef __optional_storage<_Tp> __base;
292 public:
293 typedef _Tp value_type;
294
295 static_assert(!is_reference<value_type>::value,
296 "Instantiation of optional with a reference type is ill-formed.");
297 static_assert(!is_same<typename remove_cv<value_type>::type, in_place_t>::va lue,
298 "Instantiation of optional with a in_place_t type is ill-formed.") ;
299 static_assert(!is_same<typename remove_cv<value_type>::type, nullopt_t>::val ue,
300 "Instantiation of optional with a nullopt_t type is ill-formed.");
301 static_assert(is_object<value_type>::value,
302 "Instantiation of optional with a non-object type is undefined behavior. ");
303 static_assert(is_nothrow_destructible<value_type>::value,
304 "Instantiation of optional with an object type that is not noexcept dest ructible is undefined behavior.");
305
306 _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
307 _LIBCPP_INLINE_VISIBILITY optional(const optional&) = default;
308 _LIBCPP_INLINE_VISIBILITY optional(optional&&) = default;
309 _LIBCPP_INLINE_VISIBILITY ~optional() = default;
310 _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
311 _LIBCPP_INLINE_VISIBILITY constexpr optional(const value_type& __v)
312 : __base(__v) {}
313 _LIBCPP_INLINE_VISIBILITY constexpr optional(value_type&& __v)
314 : __base(_VSTD::move(__v)) {}
315
316 template <class... _Args,
317 class = typename enable_if
318 <
319 is_constructible<value_type, _Args...>::value
320 >::type
321 >
322 _LIBCPP_INLINE_VISIBILITY
323 constexpr
324 explicit optional(in_place_t, _Args&&... __args)
325 : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
326
327 template <class _Up, class... _Args,
328 class = typename enable_if
329 <
330 is_constructible<value_type, initializer_list<_Up>&, _Args...>::value
331 >::type
332 >
333 _LIBCPP_INLINE_VISIBILITY
334 constexpr
335 explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
336 : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
337
338 _LIBCPP_INLINE_VISIBILITY
339 optional& operator=(nullopt_t) noexcept
340 {
341 if (this->__engaged_)
342 {
343 this->__val_.~value_type();
344 this->__engaged_ = false;
345 }
346 return *this;
347 }
348
349 _LIBCPP_INLINE_VISIBILITY
350 optional&
351 operator=(const optional& __opt)
352 {
353 if (this->__engaged_ == __opt.__engaged_)
354 {
355 if (this->__engaged_)
356 this->__val_ = __opt.__val_;
357 }
358 else
359 {
360 if (this->__engaged_)
361 this->__val_.~value_type();
362 else
363 ::new(_VSTD::addressof(this->__val_)) value_type(__opt.__val_);
364 this->__engaged_ = __opt.__engaged_;
365 }
366 return *this;
367 }
368
369 _LIBCPP_INLINE_VISIBILITY
370 optional&
371 operator=(optional&& __opt)
372 noexcept(is_nothrow_move_assignable<value_type>::value &&
373 is_nothrow_move_constructible<value_type>::value)
374 {
375 if (this->__engaged_ == __opt.__engaged_)
376 {
377 if (this->__engaged_)
378 this->__val_ = _VSTD::move(__opt.__val_);
379 }
380 else
381 {
382 if (this->__engaged_)
383 this->__val_.~value_type();
384 else
385 ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__o pt.__val_));
386 this->__engaged_ = __opt.__engaged_;
387 }
388 return *this;
389 }
390
391 template <class _Up,
392 class = typename enable_if
393 <
394 is_same<typename remove_reference<_Up>::type, value_ty pe>::value &&
395 is_constructible<value_type, _Up>::value &&
396 is_assignable<value_type&, _Up>::value
397 >::type
398 >
399 _LIBCPP_INLINE_VISIBILITY
400 optional&
401 operator=(_Up&& __v)
402 {
403 if (this->__engaged_)
404 this->__val_ = _VSTD::forward<_Up>(__v);
405 else
406 {
407 ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Up> (__v));
408 this->__engaged_ = true;
409 }
410 return *this;
411 }
412
413 template <class... _Args,
414 class = typename enable_if
415 <
416 is_constructible<value_type, _Args...>::value
417 >::type
418 >
419 _LIBCPP_INLINE_VISIBILITY
420 void
421 emplace(_Args&&... __args)
422 {
423 *this = nullopt;
424 ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(_ _args)...);
425 this->__engaged_ = true;
426 }
427
428 template <class _Up, class... _Args,
429 class = typename enable_if
430 <
431 is_constructible<value_type, initializer_list<_Up>&, _ Args...>::value
432 >::type
433 >
434 _LIBCPP_INLINE_VISIBILITY
435 void
436 emplace(initializer_list<_Up> __il, _Args&&... __args)
437 {
438 *this = nullopt;
439 ::new(_VSTD::addressof(this->__val_)) value_type(__il, _VSTD::forward<_A rgs>(__args)...);
440 this->__engaged_ = true;
441 }
442
443 _LIBCPP_INLINE_VISIBILITY
444 void
445 swap(optional& __opt)
446 noexcept(is_nothrow_move_constructible<value_type>::value &&
447 __is_nothrow_swappable<value_type>::value)
448 {
449 using _VSTD::swap;
450 if (this->__engaged_ == __opt.__engaged_)
451 {
452 if (this->__engaged_)
453 swap(this->__val_, __opt.__val_);
454 }
455 else
456 {
457 if (this->__engaged_)
458 {
459 ::new(_VSTD::addressof(__opt.__val_)) value_type(_VSTD::move(thi s->__val_));
460 this->__val_.~value_type();
461 }
462 else
463 {
464 ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__o pt.__val_));
465 __opt.__val_.~value_type();
466 }
467 swap(this->__engaged_, __opt.__engaged_);
468 }
469 }
470
471 _LIBCPP_INLINE_VISIBILITY
472 constexpr
473 value_type const*
474 operator->() const
475 {
476 _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disenga ged value");
477 return __operator_arrow(__has_operator_addressof<value_type>{});
478 }
479
480 _LIBCPP_INLINE_VISIBILITY
481 value_type*
482 operator->()
483 {
484 _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disenga ged value");
485 return _VSTD::addressof(this->__val_);
486 }
487
488 _LIBCPP_INLINE_VISIBILITY
489 constexpr
490 const value_type&
491 operator*() const
492 {
493 _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengag ed value");
494 return this->__val_;
495 }
496
497 _LIBCPP_INLINE_VISIBILITY
498 value_type&
499 operator*()
500 {
501 _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengag ed value");
502 return this->__val_;
503 }
504
505 _LIBCPP_INLINE_VISIBILITY
506 constexpr explicit operator bool() const noexcept {return this->__engaged_;}
507
508 _LIBCPP_INLINE_VISIBILITY
509 constexpr value_type const& value() const
510 {
511 if (!this->__engaged_)
512 throw bad_optional_access("optional<T>::value: not engaged");
513 return this->__val_;
514 }
515
516 _LIBCPP_INLINE_VISIBILITY
517 value_type& value()
518 {
519 if (!this->__engaged_)
520 throw bad_optional_access("optional<T>::value: not engaged");
521 return this->__val_;
522 }
523
524 template <class _Up>
525 _LIBCPP_INLINE_VISIBILITY
526 constexpr value_type value_or(_Up&& __v) const&
527 {
528 static_assert(is_copy_constructible<value_type>::value,
529 "optional<T>::value_or: T must be copy constructible");
530 static_assert(is_convertible<_Up, value_type>::value,
531 "optional<T>::value_or: U must be convertible to T");
532 return this->__engaged_ ? this->__val_ :
533 static_cast<value_type>(_VSTD::forward<_Up>(__ v));
534 }
535
536 template <class _Up>
537 _LIBCPP_INLINE_VISIBILITY
538 value_type value_or(_Up&& __v) &&
539 {
540 static_assert(is_move_constructible<value_type>::value,
541 "optional<T>::value_or: T must be move constructible");
542 static_assert(is_convertible<_Up, value_type>::value,
543 "optional<T>::value_or: U must be convertible to T");
544 return this->__engaged_ ? _VSTD::move(this->__val_) :
545 static_cast<value_type>(_VSTD::forward<_Up>(__ v));
546 }
547
548 private:
549 _LIBCPP_INLINE_VISIBILITY
550 value_type const*
551 __operator_arrow(true_type) const
552 {
553 return _VSTD::addressof(this->__val_);
554 }
555
556 _LIBCPP_INLINE_VISIBILITY
557 constexpr
558 value_type const*
559 __operator_arrow(false_type) const
560 {
561 return &this->__val_;
562 }
563 };
564
565 template <class _Tp>
566 inline _LIBCPP_INLINE_VISIBILITY
567 constexpr
568 bool
569 operator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
570 {
571 if (static_cast<bool>(__x) != static_cast<bool>(__y))
572 return false;
573 if (!static_cast<bool>(__x))
574 return true;
575 return *__x == *__y;
576 }
577
578 template <class _Tp>
579 inline _LIBCPP_INLINE_VISIBILITY
580 constexpr
581 bool
582 operator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
583 {
584 if (!static_cast<bool>(__y))
585 return false;
586 if (!static_cast<bool>(__x))
587 return true;
588 return less<_Tp>{}(*__x, *__y);
589 }
590
591 template <class _Tp>
592 inline _LIBCPP_INLINE_VISIBILITY
593 constexpr
594 bool
595 operator==(const optional<_Tp>& __x, nullopt_t) noexcept
596 {
597 return !static_cast<bool>(__x);
598 }
599
600 template <class _Tp>
601 inline _LIBCPP_INLINE_VISIBILITY
602 constexpr
603 bool
604 operator==(nullopt_t, const optional<_Tp>& __x) noexcept
605 {
606 return !static_cast<bool>(__x);
607 }
608
609 template <class _Tp>
610 inline _LIBCPP_INLINE_VISIBILITY
611 constexpr
612 bool
613 operator<(const optional<_Tp>&, nullopt_t) noexcept
614 {
615 return false;
616 }
617
618 template <class _Tp>
619 inline _LIBCPP_INLINE_VISIBILITY
620 constexpr
621 bool
622 operator<(nullopt_t, const optional<_Tp>& __x) noexcept
623 {
624 return static_cast<bool>(__x);
625 }
626
627 template <class _Tp>
628 inline _LIBCPP_INLINE_VISIBILITY
629 constexpr
630 bool
631 operator==(const optional<_Tp>& __x, const _Tp& __v)
632 {
633 return static_cast<bool>(__x) ? *__x == __v : false;
634 }
635
636 template <class _Tp>
637 inline _LIBCPP_INLINE_VISIBILITY
638 constexpr
639 bool
640 operator==(const _Tp& __v, const optional<_Tp>& __x)
641 {
642 return static_cast<bool>(__x) ? *__x == __v : false;
643 }
644
645 template <class _Tp>
646 inline _LIBCPP_INLINE_VISIBILITY
647 constexpr
648 bool
649 operator<(const optional<_Tp>& __x, const _Tp& __v)
650 {
651 return static_cast<bool>(__x) ? less<_Tp>{}(*__x, __v) : true;
652 }
653
654 template <class _Tp>
655 inline _LIBCPP_INLINE_VISIBILITY
656 constexpr
657 bool
658 operator<(const _Tp& __v, const optional<_Tp>& __x)
659 {
660 return static_cast<bool>(__x) ? less<_Tp>{}(__v, *__x) : false;
661 }
662
663 template <class _Tp>
664 inline _LIBCPP_INLINE_VISIBILITY
665 void
666 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
667 {
668 __x.swap(__y);
669 }
670
671 template <class _Tp>
672 inline _LIBCPP_INLINE_VISIBILITY
673 constexpr
674 optional<typename decay<_Tp>::type>
675 make_optional(_Tp&& __v)
676 {
677 return optional<typename decay<_Tp>::type>(_VSTD::forward<_Tp>(__v));
678 }
679
680 template <class _Tp>
681 struct _LIBCPP_TYPE_VIS_ONLY hash<optional<_Tp> >
682 {
683 typedef optional<_Tp> argument_type;
684 typedef size_t result_type;
685
686 _LIBCPP_INLINE_VISIBILITY
687 result_type operator()(const argument_type& __opt) const _NOEXCEPT
688 {
689 return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0;
690 }
691 };
692
693 _LIBCPP_END_NAMESPACE_STD
694
695 #endif // _LIBCPP_STD_VER > 11
696
697 #endif // _LIBCPP_ARRAY
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698