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_EXPERIMENTAL_OPTIONAL
12 #define _LIBCPP_EXPERIMENTAL_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((void*)_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((void*)_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((void*)_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((void*)_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((void*)_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((void*)_VSTD::addressof(this->__val_))
394 value_type(_VSTD::move(__opt.__val_));
395 this->__engaged_ = __opt.__engaged_;
401 class = typename enable_if
403 is_same<typename remove_reference<_Up>::type, value_type>::value &&
404 is_constructible<value_type, _Up>::value &&
405 is_assignable<value_type&, _Up>::value
408 _LIBCPP_INLINE_VISIBILITY
412 if (this->__engaged_)
413 this->__val_ = _VSTD::forward<_Up>(__v);
416 ::new((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Up>(__v));
417 this->__engaged_ = true;
422 template <class... _Args,
423 class = typename enable_if
425 is_constructible<value_type, _Args...>::value
428 _LIBCPP_INLINE_VISIBILITY
430 emplace(_Args&&... __args)
433 ::new((void*)_VSTD::addressof(this->__val_))
434 value_type(_VSTD::forward<_Args>(__args)...);
435 this->__engaged_ = true;
438 template <class _Up, class... _Args,
439 class = typename enable_if
441 is_constructible<value_type, initializer_list<_Up>&, _Args...>::value
444 _LIBCPP_INLINE_VISIBILITY
446 emplace(initializer_list<_Up> __il, _Args&&... __args)
449 ::new((void*)_VSTD::addressof(this->__val_))
450 value_type(__il, _VSTD::forward<_Args>(__args)...);
451 this->__engaged_ = true;
454 _LIBCPP_INLINE_VISIBILITY
456 swap(optional& __opt)
457 noexcept(is_nothrow_move_constructible<value_type>::value &&
458 __is_nothrow_swappable<value_type>::value)
461 if (this->__engaged_ == __opt.__engaged_)
463 if (this->__engaged_)
464 swap(this->__val_, __opt.__val_);
468 if (this->__engaged_)
470 ::new((void*)_VSTD::addressof(__opt.__val_))
471 value_type(_VSTD::move(this->__val_));
472 this->__val_.~value_type();
476 ::new((void*)_VSTD::addressof(this->__val_))
477 value_type(_VSTD::move(__opt.__val_));
478 __opt.__val_.~value_type();
480 swap(this->__engaged_, __opt.__engaged_);
484 _LIBCPP_INLINE_VISIBILITY
489 _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
490 #ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
491 return __builtin_addressof(this->__val_);
493 return __operator_arrow(__has_operator_addressof<value_type>{});
497 _LIBCPP_INLINE_VISIBILITY
501 _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
502 return _VSTD::addressof(this->__val_);
505 _LIBCPP_INLINE_VISIBILITY
510 _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
514 _LIBCPP_INLINE_VISIBILITY
518 _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
522 _LIBCPP_INLINE_VISIBILITY
523 constexpr explicit operator bool() const noexcept {return this->__engaged_;}
525 _LIBCPP_NORETURN _LIBCPP_INLINE_VISIBILITY
526 constexpr void __throw_bad_optional_access() const
528 #ifndef _LIBCPP_NO_EXCEPTIONS
529 throw bad_optional_access();
535 _LIBCPP_INLINE_VISIBILITY
536 constexpr value_type const& value() const
538 if (!this->__engaged_)
539 __throw_bad_optional_access();
543 _LIBCPP_INLINE_VISIBILITY
546 if (!this->__engaged_)
547 __throw_bad_optional_access();
552 _LIBCPP_INLINE_VISIBILITY
553 constexpr value_type value_or(_Up&& __v) const&
555 static_assert(is_copy_constructible<value_type>::value,
556 "optional<T>::value_or: T must be copy constructible");
557 static_assert(is_convertible<_Up, value_type>::value,
558 "optional<T>::value_or: U must be convertible to T");
559 return this->__engaged_ ? this->__val_ :
560 static_cast<value_type>(_VSTD::forward<_Up>(__v));
564 _LIBCPP_INLINE_VISIBILITY
565 value_type value_or(_Up&& __v) &&
567 static_assert(is_move_constructible<value_type>::value,
568 "optional<T>::value_or: T must be move constructible");
569 static_assert(is_convertible<_Up, value_type>::value,
570 "optional<T>::value_or: U must be convertible to T");
571 return this->__engaged_ ? _VSTD::move(this->__val_) :
572 static_cast<value_type>(_VSTD::forward<_Up>(__v));
576 _LIBCPP_INLINE_VISIBILITY
578 __operator_arrow(true_type) const
580 return _VSTD::addressof(this->__val_);
583 _LIBCPP_INLINE_VISIBILITY
586 __operator_arrow(false_type) const
588 return &this->__val_;
592 // Comparisons between optionals
594 inline _LIBCPP_INLINE_VISIBILITY
597 operator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
599 if (static_cast<bool>(__x) != static_cast<bool>(__y))
601 if (!static_cast<bool>(__x))
607 inline _LIBCPP_INLINE_VISIBILITY
610 operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y)
612 return !(__x == __y);
616 inline _LIBCPP_INLINE_VISIBILITY
619 operator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
621 if (!static_cast<bool>(__y))
623 if (!static_cast<bool>(__x))
629 inline _LIBCPP_INLINE_VISIBILITY
632 operator>(const optional<_Tp>& __x, const optional<_Tp>& __y)
638 inline _LIBCPP_INLINE_VISIBILITY
641 operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y)
647 inline _LIBCPP_INLINE_VISIBILITY
650 operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y)
656 // Comparisons with nullopt
658 inline _LIBCPP_INLINE_VISIBILITY
661 operator==(const optional<_Tp>& __x, nullopt_t) noexcept
663 return !static_cast<bool>(__x);
667 inline _LIBCPP_INLINE_VISIBILITY
670 operator==(nullopt_t, const optional<_Tp>& __x) noexcept
672 return !static_cast<bool>(__x);
676 inline _LIBCPP_INLINE_VISIBILITY
679 operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
681 return static_cast<bool>(__x);
685 inline _LIBCPP_INLINE_VISIBILITY
688 operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
690 return static_cast<bool>(__x);
694 inline _LIBCPP_INLINE_VISIBILITY
697 operator<(const optional<_Tp>&, nullopt_t) noexcept
703 inline _LIBCPP_INLINE_VISIBILITY
706 operator<(nullopt_t, const optional<_Tp>& __x) noexcept
708 return static_cast<bool>(__x);
712 inline _LIBCPP_INLINE_VISIBILITY
715 operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
717 return !static_cast<bool>(__x);
721 inline _LIBCPP_INLINE_VISIBILITY
724 operator<=(nullopt_t, const optional<_Tp>&) noexcept
730 inline _LIBCPP_INLINE_VISIBILITY
733 operator>(const optional<_Tp>& __x, nullopt_t) noexcept
735 return static_cast<bool>(__x);
739 inline _LIBCPP_INLINE_VISIBILITY
742 operator>(nullopt_t, const optional<_Tp>&) noexcept
748 inline _LIBCPP_INLINE_VISIBILITY
751 operator>=(const optional<_Tp>&, nullopt_t) noexcept
757 inline _LIBCPP_INLINE_VISIBILITY
760 operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
762 return !static_cast<bool>(__x);
765 // Comparisons with T
767 inline _LIBCPP_INLINE_VISIBILITY
770 operator==(const optional<_Tp>& __x, const _Tp& __v)
772 return static_cast<bool>(__x) ? *__x == __v : false;
776 inline _LIBCPP_INLINE_VISIBILITY
779 operator==(const _Tp& __v, const optional<_Tp>& __x)
781 return static_cast<bool>(__x) ? *__x == __v : false;
785 inline _LIBCPP_INLINE_VISIBILITY
788 operator!=(const optional<_Tp>& __x, const _Tp& __v)
790 return static_cast<bool>(__x) ? !(*__x == __v) : true;
794 inline _LIBCPP_INLINE_VISIBILITY
797 operator!=(const _Tp& __v, const optional<_Tp>& __x)
799 return static_cast<bool>(__x) ? !(*__x == __v) : true;
803 inline _LIBCPP_INLINE_VISIBILITY
806 operator<(const optional<_Tp>& __x, const _Tp& __v)
808 return static_cast<bool>(__x) ? less<_Tp>{}(*__x, __v) : true;
812 inline _LIBCPP_INLINE_VISIBILITY
815 operator<(const _Tp& __v, const optional<_Tp>& __x)
817 return static_cast<bool>(__x) ? less<_Tp>{}(__v, *__x) : false;
821 inline _LIBCPP_INLINE_VISIBILITY
824 operator<=(const optional<_Tp>& __x, const _Tp& __v)
830 inline _LIBCPP_INLINE_VISIBILITY
833 operator<=(const _Tp& __v, const optional<_Tp>& __x)
839 inline _LIBCPP_INLINE_VISIBILITY
842 operator>(const optional<_Tp>& __x, const _Tp& __v)
844 return static_cast<bool>(__x) ? __v < __x : false;
848 inline _LIBCPP_INLINE_VISIBILITY
851 operator>(const _Tp& __v, const optional<_Tp>& __x)
853 return static_cast<bool>(__x) ? __x < __v : true;
857 inline _LIBCPP_INLINE_VISIBILITY
860 operator>=(const optional<_Tp>& __x, const _Tp& __v)
866 inline _LIBCPP_INLINE_VISIBILITY
869 operator>=(const _Tp& __v, const optional<_Tp>& __x)
876 inline _LIBCPP_INLINE_VISIBILITY
878 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
884 inline _LIBCPP_INLINE_VISIBILITY
886 optional<typename decay<_Tp>::type>
887 make_optional(_Tp&& __v)
889 return optional<typename decay<_Tp>::type>(_VSTD::forward<_Tp>(__v));
892 _LIBCPP_END_NAMESPACE_LFTS
894 _LIBCPP_BEGIN_NAMESPACE_STD
897 struct _LIBCPP_TEMPLATE_VIS hash<std::experimental::optional<_Tp> >
899 typedef std::experimental::optional<_Tp> argument_type;
900 typedef size_t result_type;
902 _LIBCPP_INLINE_VISIBILITY
903 result_type operator()(const argument_type& __opt) const _NOEXCEPT
905 return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0;
909 _LIBCPP_END_NAMESPACE_STD
911 #endif // _LIBCPP_STD_VER > 11
913 #endif // _LIBCPP_EXPERIMENTAL_OPTIONAL