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>
146 #if _LIBCPP_STD_VER > 11
147 #include <initializer_list>
148 #include <type_traits>
150 #include <__functional_base>
154 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
155 #pragma GCC system_header
159 #include <__undef_macros>
162 _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
163 class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
164 : public std::logic_error
167 bad_optional_access() : std::logic_error("Bad optional Access") {}
169 // Get the key function ~bad_optional_access() into the dylib
170 virtual ~bad_optional_access() _NOEXCEPT;
173 _LIBCPP_END_NAMESPACE_EXPERIMENTAL
176 #if _LIBCPP_STD_VER > 11
178 _LIBCPP_BEGIN_NAMESPACE_LFTS
180 struct in_place_t {};
181 constexpr in_place_t in_place{};
185 explicit constexpr nullopt_t(int) noexcept {}
188 constexpr nullopt_t nullopt{0};
190 template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
191 class __optional_storage
194 typedef _Tp value_type;
200 bool __engaged_ = false;
202 _LIBCPP_INLINE_VISIBILITY
203 ~__optional_storage()
206 __val_.~value_type();
209 _LIBCPP_INLINE_VISIBILITY
210 constexpr __optional_storage() noexcept
211 : __null_state_('\0') {}
213 _LIBCPP_INLINE_VISIBILITY
214 __optional_storage(const __optional_storage& __x)
215 : __engaged_(__x.__engaged_)
218 ::new((void*)_VSTD::addressof(__val_)) value_type(__x.__val_);
221 _LIBCPP_INLINE_VISIBILITY
222 __optional_storage(__optional_storage&& __x)
223 noexcept(is_nothrow_move_constructible<value_type>::value)
224 : __engaged_(__x.__engaged_)
227 ::new((void*)_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_));
230 _LIBCPP_INLINE_VISIBILITY
231 constexpr __optional_storage(const value_type& __v)
235 _LIBCPP_INLINE_VISIBILITY
236 constexpr __optional_storage(value_type&& __v)
237 : __val_(_VSTD::move(__v)),
240 template <class... _Args>
241 _LIBCPP_INLINE_VISIBILITY
243 explicit __optional_storage(in_place_t, _Args&&... __args)
244 : __val_(_VSTD::forward<_Args>(__args)...),
249 class __optional_storage<_Tp, true>
252 typedef _Tp value_type;
258 bool __engaged_ = false;
260 _LIBCPP_INLINE_VISIBILITY
261 constexpr __optional_storage() noexcept
262 : __null_state_('\0') {}
264 _LIBCPP_INLINE_VISIBILITY
265 __optional_storage(const __optional_storage& __x)
266 : __engaged_(__x.__engaged_)
269 ::new((void*)_VSTD::addressof(__val_)) value_type(__x.__val_);
272 _LIBCPP_INLINE_VISIBILITY
273 __optional_storage(__optional_storage&& __x)
274 noexcept(is_nothrow_move_constructible<value_type>::value)
275 : __engaged_(__x.__engaged_)
278 ::new((void*)_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_));
281 _LIBCPP_INLINE_VISIBILITY
282 constexpr __optional_storage(const value_type& __v)
286 _LIBCPP_INLINE_VISIBILITY
287 constexpr __optional_storage(value_type&& __v)
288 : __val_(_VSTD::move(__v)),
291 template <class... _Args>
292 _LIBCPP_INLINE_VISIBILITY
294 explicit __optional_storage(in_place_t, _Args&&... __args)
295 : __val_(_VSTD::forward<_Args>(__args)...),
301 : private __optional_storage<_Tp>
303 typedef __optional_storage<_Tp> __base;
305 typedef _Tp value_type;
307 static_assert(!is_reference<value_type>::value,
308 "Instantiation of optional with a reference type is ill-formed.");
309 static_assert(!is_same<typename remove_cv<value_type>::type, in_place_t>::value,
310 "Instantiation of optional with a in_place_t type is ill-formed.");
311 static_assert(!is_same<typename remove_cv<value_type>::type, nullopt_t>::value,
312 "Instantiation of optional with a nullopt_t type is ill-formed.");
313 static_assert(is_object<value_type>::value,
314 "Instantiation of optional with a non-object type is undefined behavior.");
315 static_assert(is_nothrow_destructible<value_type>::value,
316 "Instantiation of optional with an object type that is not noexcept destructible is undefined behavior.");
318 _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
319 _LIBCPP_INLINE_VISIBILITY optional(const optional&) = default;
320 _LIBCPP_INLINE_VISIBILITY optional(optional&&) = default;
321 _LIBCPP_INLINE_VISIBILITY ~optional() = default;
322 _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
323 _LIBCPP_INLINE_VISIBILITY constexpr optional(const value_type& __v)
325 _LIBCPP_INLINE_VISIBILITY constexpr optional(value_type&& __v)
326 : __base(_VSTD::move(__v)) {}
328 template <class... _Args,
329 class = typename enable_if
331 is_constructible<value_type, _Args...>::value
334 _LIBCPP_INLINE_VISIBILITY
336 explicit optional(in_place_t, _Args&&... __args)
337 : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
339 template <class _Up, class... _Args,
340 class = typename enable_if
342 is_constructible<value_type, initializer_list<_Up>&, _Args...>::value
345 _LIBCPP_INLINE_VISIBILITY
347 explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
348 : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
350 _LIBCPP_INLINE_VISIBILITY
351 optional& operator=(nullopt_t) noexcept
353 if (this->__engaged_)
355 this->__val_.~value_type();
356 this->__engaged_ = false;
361 _LIBCPP_INLINE_VISIBILITY
363 operator=(const optional& __opt)
365 if (this->__engaged_ == __opt.__engaged_)
367 if (this->__engaged_)
368 this->__val_ = __opt.__val_;
372 if (this->__engaged_)
373 this->__val_.~value_type();
375 ::new((void*)_VSTD::addressof(this->__val_)) value_type(__opt.__val_);
376 this->__engaged_ = __opt.__engaged_;
381 _LIBCPP_INLINE_VISIBILITY
383 operator=(optional&& __opt)
384 noexcept(is_nothrow_move_assignable<value_type>::value &&
385 is_nothrow_move_constructible<value_type>::value)
387 if (this->__engaged_ == __opt.__engaged_)
389 if (this->__engaged_)
390 this->__val_ = _VSTD::move(__opt.__val_);
394 if (this->__engaged_)
395 this->__val_.~value_type();
397 ::new((void*)_VSTD::addressof(this->__val_))
398 value_type(_VSTD::move(__opt.__val_));
399 this->__engaged_ = __opt.__engaged_;
405 class = typename enable_if
407 is_same<typename remove_reference<_Up>::type, value_type>::value &&
408 is_constructible<value_type, _Up>::value &&
409 is_assignable<value_type&, _Up>::value
412 _LIBCPP_INLINE_VISIBILITY
416 if (this->__engaged_)
417 this->__val_ = _VSTD::forward<_Up>(__v);
420 ::new((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Up>(__v));
421 this->__engaged_ = true;
426 template <class... _Args,
427 class = typename enable_if
429 is_constructible<value_type, _Args...>::value
432 _LIBCPP_INLINE_VISIBILITY
434 emplace(_Args&&... __args)
437 ::new((void*)_VSTD::addressof(this->__val_))
438 value_type(_VSTD::forward<_Args>(__args)...);
439 this->__engaged_ = true;
442 template <class _Up, class... _Args,
443 class = typename enable_if
445 is_constructible<value_type, initializer_list<_Up>&, _Args...>::value
448 _LIBCPP_INLINE_VISIBILITY
450 emplace(initializer_list<_Up> __il, _Args&&... __args)
453 ::new((void*)_VSTD::addressof(this->__val_))
454 value_type(__il, _VSTD::forward<_Args>(__args)...);
455 this->__engaged_ = true;
458 _LIBCPP_INLINE_VISIBILITY
460 swap(optional& __opt)
461 noexcept(is_nothrow_move_constructible<value_type>::value &&
462 __is_nothrow_swappable<value_type>::value)
465 if (this->__engaged_ == __opt.__engaged_)
467 if (this->__engaged_)
468 swap(this->__val_, __opt.__val_);
472 if (this->__engaged_)
474 ::new((void*)_VSTD::addressof(__opt.__val_))
475 value_type(_VSTD::move(this->__val_));
476 this->__val_.~value_type();
480 ::new((void*)_VSTD::addressof(this->__val_))
481 value_type(_VSTD::move(__opt.__val_));
482 __opt.__val_.~value_type();
484 swap(this->__engaged_, __opt.__engaged_);
488 _LIBCPP_INLINE_VISIBILITY
493 _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
494 #ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
495 return __builtin_addressof(this->__val_);
497 return __operator_arrow(__has_operator_addressof<value_type>{});
501 _LIBCPP_INLINE_VISIBILITY
505 _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
506 return _VSTD::addressof(this->__val_);
509 _LIBCPP_INLINE_VISIBILITY
514 _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
518 _LIBCPP_INLINE_VISIBILITY
522 _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
526 _LIBCPP_INLINE_VISIBILITY
527 constexpr explicit operator bool() const noexcept {return this->__engaged_;}
529 _LIBCPP_NORETURN _LIBCPP_INLINE_VISIBILITY
530 #ifndef _LIBCPP_NO_EXCEPTIONS
531 _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
533 constexpr void __throw_bad_optional_access() const
535 #ifndef _LIBCPP_NO_EXCEPTIONS
536 throw bad_optional_access();
542 _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
543 constexpr value_type const& value() const
545 if (!this->__engaged_)
546 __throw_bad_optional_access();
550 _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
553 if (!this->__engaged_)
554 __throw_bad_optional_access();
559 _LIBCPP_INLINE_VISIBILITY
560 constexpr value_type value_or(_Up&& __v) const&
562 static_assert(is_copy_constructible<value_type>::value,
563 "optional<T>::value_or: T must be copy constructible");
564 static_assert(is_convertible<_Up, value_type>::value,
565 "optional<T>::value_or: U must be convertible to T");
566 return this->__engaged_ ? this->__val_ :
567 static_cast<value_type>(_VSTD::forward<_Up>(__v));
571 _LIBCPP_INLINE_VISIBILITY
572 value_type value_or(_Up&& __v) &&
574 static_assert(is_move_constructible<value_type>::value,
575 "optional<T>::value_or: T must be move constructible");
576 static_assert(is_convertible<_Up, value_type>::value,
577 "optional<T>::value_or: U must be convertible to T");
578 return this->__engaged_ ? _VSTD::move(this->__val_) :
579 static_cast<value_type>(_VSTD::forward<_Up>(__v));
583 _LIBCPP_INLINE_VISIBILITY
585 __operator_arrow(true_type) const
587 return _VSTD::addressof(this->__val_);
590 _LIBCPP_INLINE_VISIBILITY
593 __operator_arrow(false_type) const
595 return &this->__val_;
599 // Comparisons between optionals
601 inline _LIBCPP_INLINE_VISIBILITY
604 operator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
606 if (static_cast<bool>(__x) != static_cast<bool>(__y))
608 if (!static_cast<bool>(__x))
614 inline _LIBCPP_INLINE_VISIBILITY
617 operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y)
619 return !(__x == __y);
623 inline _LIBCPP_INLINE_VISIBILITY
626 operator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
628 if (!static_cast<bool>(__y))
630 if (!static_cast<bool>(__x))
636 inline _LIBCPP_INLINE_VISIBILITY
639 operator>(const optional<_Tp>& __x, const optional<_Tp>& __y)
645 inline _LIBCPP_INLINE_VISIBILITY
648 operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y)
654 inline _LIBCPP_INLINE_VISIBILITY
657 operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y)
663 // Comparisons with nullopt
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>& __x, nullopt_t) noexcept
688 return static_cast<bool>(__x);
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>&, nullopt_t) noexcept
710 inline _LIBCPP_INLINE_VISIBILITY
713 operator<(nullopt_t, const optional<_Tp>& __x) noexcept
715 return static_cast<bool>(__x);
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>&) noexcept
737 inline _LIBCPP_INLINE_VISIBILITY
740 operator>(const optional<_Tp>& __x, nullopt_t) noexcept
742 return static_cast<bool>(__x);
746 inline _LIBCPP_INLINE_VISIBILITY
749 operator>(nullopt_t, const optional<_Tp>&) noexcept
755 inline _LIBCPP_INLINE_VISIBILITY
758 operator>=(const optional<_Tp>&, nullopt_t) noexcept
764 inline _LIBCPP_INLINE_VISIBILITY
767 operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
769 return !static_cast<bool>(__x);
772 // Comparisons with T
774 inline _LIBCPP_INLINE_VISIBILITY
777 operator==(const optional<_Tp>& __x, const _Tp& __v)
779 return static_cast<bool>(__x) ? *__x == __v : false;
783 inline _LIBCPP_INLINE_VISIBILITY
786 operator==(const _Tp& __v, const optional<_Tp>& __x)
788 return static_cast<bool>(__x) ? *__x == __v : false;
792 inline _LIBCPP_INLINE_VISIBILITY
795 operator!=(const optional<_Tp>& __x, const _Tp& __v)
797 return static_cast<bool>(__x) ? !(*__x == __v) : true;
801 inline _LIBCPP_INLINE_VISIBILITY
804 operator!=(const _Tp& __v, const optional<_Tp>& __x)
806 return static_cast<bool>(__x) ? !(*__x == __v) : true;
810 inline _LIBCPP_INLINE_VISIBILITY
813 operator<(const optional<_Tp>& __x, const _Tp& __v)
815 return static_cast<bool>(__x) ? less<_Tp>{}(*__x, __v) : true;
819 inline _LIBCPP_INLINE_VISIBILITY
822 operator<(const _Tp& __v, const optional<_Tp>& __x)
824 return static_cast<bool>(__x) ? less<_Tp>{}(__v, *__x) : false;
828 inline _LIBCPP_INLINE_VISIBILITY
831 operator<=(const optional<_Tp>& __x, const _Tp& __v)
837 inline _LIBCPP_INLINE_VISIBILITY
840 operator<=(const _Tp& __v, const optional<_Tp>& __x)
846 inline _LIBCPP_INLINE_VISIBILITY
849 operator>(const optional<_Tp>& __x, const _Tp& __v)
851 return static_cast<bool>(__x) ? __v < __x : false;
855 inline _LIBCPP_INLINE_VISIBILITY
858 operator>(const _Tp& __v, const optional<_Tp>& __x)
860 return static_cast<bool>(__x) ? __x < __v : true;
864 inline _LIBCPP_INLINE_VISIBILITY
867 operator>=(const optional<_Tp>& __x, const _Tp& __v)
873 inline _LIBCPP_INLINE_VISIBILITY
876 operator>=(const _Tp& __v, const optional<_Tp>& __x)
883 inline _LIBCPP_INLINE_VISIBILITY
885 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
891 inline _LIBCPP_INLINE_VISIBILITY
893 optional<typename decay<_Tp>::type>
894 make_optional(_Tp&& __v)
896 return optional<typename decay<_Tp>::type>(_VSTD::forward<_Tp>(__v));
899 _LIBCPP_END_NAMESPACE_LFTS
901 _LIBCPP_BEGIN_NAMESPACE_STD
904 struct _LIBCPP_TEMPLATE_VIS hash<std::experimental::optional<_Tp> >
906 typedef std::experimental::optional<_Tp> argument_type;
907 typedef size_t result_type;
909 _LIBCPP_INLINE_VISIBILITY
910 result_type operator()(const argument_type& __opt) const _NOEXCEPT
912 return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0;
916 _LIBCPP_END_NAMESPACE_STD
918 #endif // _LIBCPP_STD_VER > 11
922 #endif // _LIBCPP_EXPERIMENTAL_OPTIONAL