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 #ifndef _LIBCPP_NO_EXCEPTIONS
521 throw bad_optional_access();
523 assert(!"bad optional access");
528 _LIBCPP_INLINE_VISIBILITY
531 if (!this->__engaged_)
532 #ifndef _LIBCPP_NO_EXCEPTIONS
533 throw bad_optional_access();
535 assert(!"bad optional access");
541 _LIBCPP_INLINE_VISIBILITY
542 constexpr value_type value_or(_Up&& __v) const&
544 static_assert(is_copy_constructible<value_type>::value,
545 "optional<T>::value_or: T must be copy constructible");
546 static_assert(is_convertible<_Up, value_type>::value,
547 "optional<T>::value_or: U must be convertible to T");
548 return this->__engaged_ ? this->__val_ :
549 static_cast<value_type>(_VSTD::forward<_Up>(__v));
553 _LIBCPP_INLINE_VISIBILITY
554 value_type value_or(_Up&& __v) &&
556 static_assert(is_move_constructible<value_type>::value,
557 "optional<T>::value_or: T must be move constructible");
558 static_assert(is_convertible<_Up, value_type>::value,
559 "optional<T>::value_or: U must be convertible to T");
560 return this->__engaged_ ? _VSTD::move(this->__val_) :
561 static_cast<value_type>(_VSTD::forward<_Up>(__v));
565 _LIBCPP_INLINE_VISIBILITY
567 __operator_arrow(true_type) const
569 return _VSTD::addressof(this->__val_);
572 _LIBCPP_INLINE_VISIBILITY
575 __operator_arrow(false_type) const
577 return &this->__val_;
581 // Comparisons between optionals
583 inline _LIBCPP_INLINE_VISIBILITY
586 operator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
588 if (static_cast<bool>(__x) != static_cast<bool>(__y))
590 if (!static_cast<bool>(__x))
596 inline _LIBCPP_INLINE_VISIBILITY
599 operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y)
601 return !(__x == __y);
605 inline _LIBCPP_INLINE_VISIBILITY
608 operator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
610 if (!static_cast<bool>(__y))
612 if (!static_cast<bool>(__x))
618 inline _LIBCPP_INLINE_VISIBILITY
621 operator>(const optional<_Tp>& __x, const optional<_Tp>& __y)
627 inline _LIBCPP_INLINE_VISIBILITY
630 operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y)
636 inline _LIBCPP_INLINE_VISIBILITY
639 operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y)
645 // Comparisons with nullopt
647 inline _LIBCPP_INLINE_VISIBILITY
650 operator==(const optional<_Tp>& __x, nullopt_t) noexcept
652 return !static_cast<bool>(__x);
656 inline _LIBCPP_INLINE_VISIBILITY
659 operator==(nullopt_t, const optional<_Tp>& __x) noexcept
661 return !static_cast<bool>(__x);
665 inline _LIBCPP_INLINE_VISIBILITY
668 operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
670 return static_cast<bool>(__x);
674 inline _LIBCPP_INLINE_VISIBILITY
677 operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
679 return static_cast<bool>(__x);
683 inline _LIBCPP_INLINE_VISIBILITY
686 operator<(const optional<_Tp>&, nullopt_t) noexcept
692 inline _LIBCPP_INLINE_VISIBILITY
695 operator<(nullopt_t, const optional<_Tp>& __x) noexcept
697 return static_cast<bool>(__x);
701 inline _LIBCPP_INLINE_VISIBILITY
704 operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
706 return !static_cast<bool>(__x);
710 inline _LIBCPP_INLINE_VISIBILITY
713 operator<=(nullopt_t, const optional<_Tp>& __x) noexcept
719 inline _LIBCPP_INLINE_VISIBILITY
722 operator>(const optional<_Tp>& __x, nullopt_t) noexcept
724 return static_cast<bool>(__x);
728 inline _LIBCPP_INLINE_VISIBILITY
731 operator>(nullopt_t, const optional<_Tp>& __x) noexcept
737 inline _LIBCPP_INLINE_VISIBILITY
740 operator>=(const optional<_Tp>&, nullopt_t) noexcept
746 inline _LIBCPP_INLINE_VISIBILITY
749 operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
751 return !static_cast<bool>(__x);
754 // Comparisons with T
756 inline _LIBCPP_INLINE_VISIBILITY
759 operator==(const optional<_Tp>& __x, const _Tp& __v)
761 return static_cast<bool>(__x) ? *__x == __v : false;
765 inline _LIBCPP_INLINE_VISIBILITY
768 operator==(const _Tp& __v, const optional<_Tp>& __x)
770 return static_cast<bool>(__x) ? *__x == __v : false;
774 inline _LIBCPP_INLINE_VISIBILITY
777 operator!=(const optional<_Tp>& __x, const _Tp& __v)
779 return static_cast<bool>(__x) ? !(*__x == __v) : true;
783 inline _LIBCPP_INLINE_VISIBILITY
786 operator!=(const _Tp& __v, const optional<_Tp>& __x)
788 return static_cast<bool>(__x) ? !(*__x == __v) : true;
792 inline _LIBCPP_INLINE_VISIBILITY
795 operator<(const optional<_Tp>& __x, const _Tp& __v)
797 return static_cast<bool>(__x) ? less<_Tp>{}(*__x, __v) : true;
801 inline _LIBCPP_INLINE_VISIBILITY
804 operator<(const _Tp& __v, const optional<_Tp>& __x)
806 return static_cast<bool>(__x) ? less<_Tp>{}(__v, *__x) : false;
810 inline _LIBCPP_INLINE_VISIBILITY
813 operator<=(const optional<_Tp>& __x, const _Tp& __v)
819 inline _LIBCPP_INLINE_VISIBILITY
822 operator<=(const _Tp& __v, const optional<_Tp>& __x)
828 inline _LIBCPP_INLINE_VISIBILITY
831 operator>(const optional<_Tp>& __x, const _Tp& __v)
833 return static_cast<bool>(__x) ? __v < __x : false;
837 inline _LIBCPP_INLINE_VISIBILITY
840 operator>(const _Tp& __v, const optional<_Tp>& __x)
842 return static_cast<bool>(__x) ? __x < __v : true;
846 inline _LIBCPP_INLINE_VISIBILITY
849 operator>=(const optional<_Tp>& __x, const _Tp& __v)
855 inline _LIBCPP_INLINE_VISIBILITY
858 operator>=(const _Tp& __v, const optional<_Tp>& __x)
865 inline _LIBCPP_INLINE_VISIBILITY
867 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
873 inline _LIBCPP_INLINE_VISIBILITY
875 optional<typename decay<_Tp>::type>
876 make_optional(_Tp&& __v)
878 return optional<typename decay<_Tp>::type>(_VSTD::forward<_Tp>(__v));
881 _LIBCPP_END_NAMESPACE_LFTS
883 _LIBCPP_BEGIN_NAMESPACE_STD
886 struct _LIBCPP_TYPE_VIS_ONLY hash<std::experimental::optional<_Tp> >
888 typedef std::experimental::optional<_Tp> argument_type;
889 typedef size_t result_type;
891 _LIBCPP_INLINE_VISIBILITY
892 result_type operator()(const argument_type& __opt) const _NOEXCEPT
894 return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0;
898 _LIBCPP_END_NAMESPACE_STD
900 #endif // _LIBCPP_STD_VER > 11
902 #endif // _LIBCPP_OPTIONAL