2 //===-------------------------- optional ----------------------------------===//
4 // The LLVM Compiler Infrastructure
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 #ifndef _LIBCPP_OPTIONAL
12 #define _LIBCPP_OPTIONAL
19 namespace std { namespace experimental { inline namespace fundamentals_v1 {
21 // 5.3, optional for object types
22 template <class T> class optional;
24 // 5.4, In-place construction
26 constexpr in_place_t in_place{};
28 // 5.5, No-value state indicator
29 struct nullopt_t{see below};
30 constexpr nullopt_t nullopt(unspecified);
32 // 5.6, Class bad_optional_access
33 class bad_optional_access;
35 // 5.7, Relational operators
37 constexpr bool operator==(const optional<T>&, const optional<T>&);
39 constexpr bool operator!=(const optional<T>&, const optional<T>&);
41 constexpr bool operator<(const optional<T>&, const optional<T>&);
43 constexpr bool operator>(const optional<T>&, const optional<T>&);
45 constexpr bool operator<=(const optional<T>&, const optional<T>&);
47 constexpr bool operator>=(const optional<T>&, const optional<T>&);
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;
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>&);
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&&);
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&&...);
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&&...);
111 void swap(optional&) noexcept(see below);
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&&) &&;
129 T* val; // exposition only
132 } // namespace fundamentals_v1
133 } // namespace experimental
135 // 5.11, Hash support
136 template <class T> struct hash;
137 template <class T> struct hash<experimental::optional<T>>;
143 #include <experimental/__config>
144 #include <functional>
147 _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
148 class _LIBCPP_EXCEPTION_ABI bad_optional_access
149 : public std::logic_error
152 bad_optional_access() : std::logic_error("Bad optional Access") {}
154 // Get the key function ~bad_optional_access() into the dylib
155 virtual ~bad_optional_access() _NOEXCEPT;
158 _LIBCPP_END_NAMESPACE_EXPERIMENTAL
161 #if _LIBCPP_STD_VER > 11
163 #include <initializer_list>
164 #include <type_traits>
166 #include <__functional_base>
167 #include <__undef_min_max>
170 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
171 #pragma GCC system_header
174 _LIBCPP_BEGIN_NAMESPACE_LFTS
176 struct in_place_t {};
177 constexpr in_place_t in_place{};
181 explicit constexpr nullopt_t(int) noexcept {}
184 constexpr nullopt_t nullopt{0};
186 template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
187 class __optional_storage
190 typedef _Tp value_type;
196 bool __engaged_ = false;
198 _LIBCPP_INLINE_VISIBILITY
199 ~__optional_storage()
202 __val_.~value_type();
205 _LIBCPP_INLINE_VISIBILITY
206 constexpr __optional_storage() noexcept
207 : __null_state_('\0') {}
209 _LIBCPP_INLINE_VISIBILITY
210 __optional_storage(const __optional_storage& __x)
211 : __engaged_(__x.__engaged_)
214 ::new(_VSTD::addressof(__val_)) value_type(__x.__val_);
217 _LIBCPP_INLINE_VISIBILITY
218 __optional_storage(__optional_storage&& __x)
219 noexcept(is_nothrow_move_constructible<value_type>::value)
220 : __engaged_(__x.__engaged_)
223 ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_));
226 _LIBCPP_INLINE_VISIBILITY
227 constexpr __optional_storage(const value_type& __v)
231 _LIBCPP_INLINE_VISIBILITY
232 constexpr __optional_storage(value_type&& __v)
233 : __val_(_VSTD::move(__v)),
236 template <class... _Args>
237 _LIBCPP_INLINE_VISIBILITY
239 explicit __optional_storage(in_place_t, _Args&&... __args)
240 : __val_(_VSTD::forward<_Args>(__args)...),
245 class __optional_storage<_Tp, true>
248 typedef _Tp value_type;
254 bool __engaged_ = false;
256 _LIBCPP_INLINE_VISIBILITY
257 constexpr __optional_storage() noexcept
258 : __null_state_('\0') {}
260 _LIBCPP_INLINE_VISIBILITY
261 __optional_storage(const __optional_storage& __x)
262 : __engaged_(__x.__engaged_)
265 ::new(_VSTD::addressof(__val_)) value_type(__x.__val_);
268 _LIBCPP_INLINE_VISIBILITY
269 __optional_storage(__optional_storage&& __x)
270 noexcept(is_nothrow_move_constructible<value_type>::value)
271 : __engaged_(__x.__engaged_)
274 ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_));
277 _LIBCPP_INLINE_VISIBILITY
278 constexpr __optional_storage(const value_type& __v)
282 _LIBCPP_INLINE_VISIBILITY
283 constexpr __optional_storage(value_type&& __v)
284 : __val_(_VSTD::move(__v)),
287 template <class... _Args>
288 _LIBCPP_INLINE_VISIBILITY
290 explicit __optional_storage(in_place_t, _Args&&... __args)
291 : __val_(_VSTD::forward<_Args>(__args)...),
297 : private __optional_storage<_Tp>
299 typedef __optional_storage<_Tp> __base;
301 typedef _Tp value_type;
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.");
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)
321 _LIBCPP_INLINE_VISIBILITY constexpr optional(value_type&& __v)
322 : __base(_VSTD::move(__v)) {}
324 template <class... _Args,
325 class = typename enable_if
327 is_constructible<value_type, _Args...>::value
330 _LIBCPP_INLINE_VISIBILITY
332 explicit optional(in_place_t, _Args&&... __args)
333 : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
335 template <class _Up, class... _Args,
336 class = typename enable_if
338 is_constructible<value_type, initializer_list<_Up>&, _Args...>::value
341 _LIBCPP_INLINE_VISIBILITY
343 explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
344 : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
346 _LIBCPP_INLINE_VISIBILITY
347 optional& operator=(nullopt_t) noexcept
349 if (this->__engaged_)
351 this->__val_.~value_type();
352 this->__engaged_ = false;
357 _LIBCPP_INLINE_VISIBILITY
359 operator=(const optional& __opt)
361 if (this->__engaged_ == __opt.__engaged_)
363 if (this->__engaged_)
364 this->__val_ = __opt.__val_;
368 if (this->__engaged_)
369 this->__val_.~value_type();
371 ::new(_VSTD::addressof(this->__val_)) value_type(__opt.__val_);
372 this->__engaged_ = __opt.__engaged_;
377 _LIBCPP_INLINE_VISIBILITY
379 operator=(optional&& __opt)
380 noexcept(is_nothrow_move_assignable<value_type>::value &&
381 is_nothrow_move_constructible<value_type>::value)
383 if (this->__engaged_ == __opt.__engaged_)
385 if (this->__engaged_)
386 this->__val_ = _VSTD::move(__opt.__val_);
390 if (this->__engaged_)
391 this->__val_.~value_type();
393 ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_));
394 this->__engaged_ = __opt.__engaged_;
400 class = typename enable_if
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
407 _LIBCPP_INLINE_VISIBILITY
411 if (this->__engaged_)
412 this->__val_ = _VSTD::forward<_Up>(__v);
415 ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Up>(__v));
416 this->__engaged_ = true;
421 template <class... _Args,
422 class = typename enable_if
424 is_constructible<value_type, _Args...>::value
427 _LIBCPP_INLINE_VISIBILITY
429 emplace(_Args&&... __args)
432 ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
433 this->__engaged_ = true;
436 template <class _Up, class... _Args,
437 class = typename enable_if
439 is_constructible<value_type, initializer_list<_Up>&, _Args...>::value
442 _LIBCPP_INLINE_VISIBILITY
444 emplace(initializer_list<_Up> __il, _Args&&... __args)
447 ::new(_VSTD::addressof(this->__val_)) value_type(__il, _VSTD::forward<_Args>(__args)...);
448 this->__engaged_ = true;
451 _LIBCPP_INLINE_VISIBILITY
453 swap(optional& __opt)
454 noexcept(is_nothrow_move_constructible<value_type>::value &&
455 __is_nothrow_swappable<value_type>::value)
458 if (this->__engaged_ == __opt.__engaged_)
460 if (this->__engaged_)
461 swap(this->__val_, __opt.__val_);
465 if (this->__engaged_)
467 ::new(_VSTD::addressof(__opt.__val_)) value_type(_VSTD::move(this->__val_));
468 this->__val_.~value_type();
472 ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_));
473 __opt.__val_.~value_type();
475 swap(this->__engaged_, __opt.__engaged_);
479 _LIBCPP_INLINE_VISIBILITY
484 _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
485 return __operator_arrow(__has_operator_addressof<value_type>{});
488 _LIBCPP_INLINE_VISIBILITY
492 _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
493 return _VSTD::addressof(this->__val_);
496 _LIBCPP_INLINE_VISIBILITY
501 _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
505 _LIBCPP_INLINE_VISIBILITY
509 _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
513 _LIBCPP_INLINE_VISIBILITY
514 constexpr explicit operator bool() const noexcept {return this->__engaged_;}
516 _LIBCPP_INLINE_VISIBILITY
517 constexpr value_type const& value() const
519 if (!this->__engaged_)
520 throw bad_optional_access();
524 _LIBCPP_INLINE_VISIBILITY
527 if (!this->__engaged_)
528 throw bad_optional_access();
533 _LIBCPP_INLINE_VISIBILITY
534 constexpr value_type value_or(_Up&& __v) const&
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));
545 _LIBCPP_INLINE_VISIBILITY
546 value_type value_or(_Up&& __v) &&
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));
557 _LIBCPP_INLINE_VISIBILITY
559 __operator_arrow(true_type) const
561 return _VSTD::addressof(this->__val_);
564 _LIBCPP_INLINE_VISIBILITY
567 __operator_arrow(false_type) const
569 return &this->__val_;
573 // Comparisons between optionals
575 inline _LIBCPP_INLINE_VISIBILITY
578 operator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
580 if (static_cast<bool>(__x) != static_cast<bool>(__y))
582 if (!static_cast<bool>(__x))
588 inline _LIBCPP_INLINE_VISIBILITY
591 operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y)
593 return !(__x == __y);
597 inline _LIBCPP_INLINE_VISIBILITY
600 operator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
602 if (!static_cast<bool>(__y))
604 if (!static_cast<bool>(__x))
610 inline _LIBCPP_INLINE_VISIBILITY
613 operator>(const optional<_Tp>& __x, const optional<_Tp>& __y)
619 inline _LIBCPP_INLINE_VISIBILITY
622 operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y)
628 inline _LIBCPP_INLINE_VISIBILITY
631 operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y)
637 // Comparisons with nullopt
639 inline _LIBCPP_INLINE_VISIBILITY
642 operator==(const optional<_Tp>& __x, nullopt_t) noexcept
644 return !static_cast<bool>(__x);
648 inline _LIBCPP_INLINE_VISIBILITY
651 operator==(nullopt_t, const optional<_Tp>& __x) noexcept
653 return !static_cast<bool>(__x);
657 inline _LIBCPP_INLINE_VISIBILITY
660 operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
662 return static_cast<bool>(__x);
666 inline _LIBCPP_INLINE_VISIBILITY
669 operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
671 return static_cast<bool>(__x);
675 inline _LIBCPP_INLINE_VISIBILITY
678 operator<(const optional<_Tp>&, nullopt_t) noexcept
684 inline _LIBCPP_INLINE_VISIBILITY
687 operator<(nullopt_t, const optional<_Tp>& __x) noexcept
689 return static_cast<bool>(__x);
693 inline _LIBCPP_INLINE_VISIBILITY
696 operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
698 return !static_cast<bool>(__x);
702 inline _LIBCPP_INLINE_VISIBILITY
705 operator<=(nullopt_t, const optional<_Tp>& __x) noexcept
711 inline _LIBCPP_INLINE_VISIBILITY
714 operator>(const optional<_Tp>& __x, nullopt_t) noexcept
716 return static_cast<bool>(__x);
720 inline _LIBCPP_INLINE_VISIBILITY
723 operator>(nullopt_t, const optional<_Tp>& __x) noexcept
729 inline _LIBCPP_INLINE_VISIBILITY
732 operator>=(const optional<_Tp>&, nullopt_t) noexcept
738 inline _LIBCPP_INLINE_VISIBILITY
741 operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
743 return !static_cast<bool>(__x);
746 // Comparisons with T
748 inline _LIBCPP_INLINE_VISIBILITY
751 operator==(const optional<_Tp>& __x, const _Tp& __v)
753 return static_cast<bool>(__x) ? *__x == __v : false;
757 inline _LIBCPP_INLINE_VISIBILITY
760 operator==(const _Tp& __v, const optional<_Tp>& __x)
762 return static_cast<bool>(__x) ? *__x == __v : false;
766 inline _LIBCPP_INLINE_VISIBILITY
769 operator!=(const optional<_Tp>& __x, const _Tp& __v)
771 return static_cast<bool>(__x) ? !(*__x == __v) : true;
775 inline _LIBCPP_INLINE_VISIBILITY
778 operator!=(const _Tp& __v, const optional<_Tp>& __x)
780 return static_cast<bool>(__x) ? !(*__x == __v) : true;
784 inline _LIBCPP_INLINE_VISIBILITY
787 operator<(const optional<_Tp>& __x, const _Tp& __v)
789 return static_cast<bool>(__x) ? less<_Tp>{}(*__x, __v) : true;
793 inline _LIBCPP_INLINE_VISIBILITY
796 operator<(const _Tp& __v, const optional<_Tp>& __x)
798 return static_cast<bool>(__x) ? less<_Tp>{}(__v, *__x) : false;
802 inline _LIBCPP_INLINE_VISIBILITY
805 operator<=(const optional<_Tp>& __x, const _Tp& __v)
811 inline _LIBCPP_INLINE_VISIBILITY
814 operator<=(const _Tp& __v, const optional<_Tp>& __x)
820 inline _LIBCPP_INLINE_VISIBILITY
823 operator>(const optional<_Tp>& __x, const _Tp& __v)
825 return static_cast<bool>(__x) ? __v < __x : false;
829 inline _LIBCPP_INLINE_VISIBILITY
832 operator>(const _Tp& __v, const optional<_Tp>& __x)
834 return static_cast<bool>(__x) ? __x < __v : true;
838 inline _LIBCPP_INLINE_VISIBILITY
841 operator>=(const optional<_Tp>& __x, const _Tp& __v)
847 inline _LIBCPP_INLINE_VISIBILITY
850 operator>=(const _Tp& __v, const optional<_Tp>& __x)
857 inline _LIBCPP_INLINE_VISIBILITY
859 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
865 inline _LIBCPP_INLINE_VISIBILITY
867 optional<typename decay<_Tp>::type>
868 make_optional(_Tp&& __v)
870 return optional<typename decay<_Tp>::type>(_VSTD::forward<_Tp>(__v));
873 _LIBCPP_END_NAMESPACE_LFTS
875 _LIBCPP_BEGIN_NAMESPACE_STD
878 struct _LIBCPP_TYPE_VIS_ONLY hash<std::experimental::optional<_Tp> >
880 typedef std::experimental::optional<_Tp> argument_type;
881 typedef size_t result_type;
883 _LIBCPP_INLINE_VISIBILITY
884 result_type operator()(const argument_type& __opt) const _NOEXCEPT
886 return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0;
890 _LIBCPP_END_NAMESPACE_STD
892 #endif // _LIBCPP_STD_VER > 11
894 #endif // _LIBCPP_OPTIONAL