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 #include <initializer_list>
21 namespace std { namespace experimental {
23 // optional for object types
31 constexpr optional() noexcept;
32 constexpr optional(nullopt_t) noexcept;
33 optional(const optional&);
34 optional(optional&&) noexcept(is_nothrow_move_constructible<T>::value);
35 constexpr optional(const T&);
36 constexpr optional(T&&);
37 template <class... Args> constexpr explicit optional(in_place_t, Args&&...);
38 template <class U, class... Args>
39 constexpr explicit optional(in_place_t, initializer_list<U>, Args&&...);
45 optional& operator=(nullopt_t) noexcept;
46 optional& operator=(const optional&);
47 optional& operator=(optional&&)
48 noexcept(is_nothrow_move_assignable<T>::value &&
49 is_nothrow_move_constructible<T>::value);
50 template <class U> optional& operator=(U&&);
51 template <class... Args> void emplace(Args&&...);
52 template <class U, class... Args> void emplace(initializer_list<U>, Args&&...);
56 noexcept(is_nothrow_move_constructible<T>::value &&
57 noexcept(swap(declval<T&>(), declval<T&>())));
60 constexpr T const* operator->() const;
62 constexpr T const& operator*() const;
64 constexpr explicit operator bool() const noexcept;
65 constexpr T const& value() const;
67 template <class U> constexpr T value_or(U&&) const&;
68 template <class U> T value_or(U&&) &&;
71 // In-place construction
73 constexpr in_place_t in_place{};
75 // Disengaged state indicator
76 struct nullopt_t{see below};
77 constexpr nullopt_t nullopt(unspecified);
79 // class bad_optional_access
80 class bad_optional_access
84 explicit bad_optional_access(const string& what_arg);
85 explicit bad_optional_access(const char* what_arg);
88 // Relational operators
89 template <class T> constexpr bool operator==(const optional<T>&, const optional<T>&);
90 template <class T> constexpr bool operator< (const optional<T>&, const optional<T>&);
92 // Comparison with nullopt
93 template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
94 template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept;
95 template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept;
96 template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept;
99 template <class T> constexpr bool operator==(const optional<T>&, const T&);
100 template <class T> constexpr bool operator==(const T&, const optional<T>&);
101 template <class T> constexpr bool operator<(const optional<T>&, const T&);
102 template <class T> constexpr bool operator<(const T&, const optional<T>&);
104 // Specialized algorithms
105 template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below);
106 template <class T> constexpr optional<typename decay<T>::type> make_optional(T&&);
109 template <class T> struct hash;
110 template <class T> struct hash<optional<T>>;
112 }} // std::experimental
117 #include <functional>
120 namespace std { namespace experimental {
122 class _LIBCPP_EXCEPTION_ABI bad_optional_access
126 #if _LIBCPP_STD_VER > 11
127 _LIBCPP_INLINE_VISIBILITY explicit bad_optional_access(const string& __arg)
128 : logic_error(__arg) {}
129 _LIBCPP_INLINE_VISIBILITY explicit bad_optional_access(const char* __arg)
130 : logic_error(__arg) {}
131 _LIBCPP_INLINE_VISIBILITY bad_optional_access(const bad_optional_access&) noexcept = default;
132 _LIBCPP_INLINE_VISIBILITY bad_optional_access& operator=(const bad_optional_access&) noexcept = default;
135 bad_optional_access(const bad_optional_access&);
136 bad_optional_access& operator=(const bad_optional_access&);
138 #endif // _LIBCPP_STD_VER > 11
139 // Get the key function ~bad_optional_access() into the dylib even if not compiling for C++1y
140 virtual ~bad_optional_access() _NOEXCEPT;
143 }} // std::experimental
145 #if _LIBCPP_STD_VER > 11
147 #include <initializer_list>
148 #include <type_traits>
150 #include <__functional_base>
152 #include <__undef_min_max>
156 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
157 #pragma GCC system_header
160 namespace std { namespace experimental { inline namespace __library_fundamentals_v1 {
162 struct in_place_t {};
163 constexpr in_place_t in_place{};
167 explicit constexpr nullopt_t(int) noexcept {}
170 constexpr nullopt_t nullopt{0};
172 template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
173 class __optional_storage
176 typedef _Tp value_type;
182 bool __engaged_ = false;
184 _LIBCPP_INLINE_VISIBILITY
185 ~__optional_storage()
188 __val_.~value_type();
191 _LIBCPP_INLINE_VISIBILITY
192 constexpr __optional_storage() noexcept
193 : __null_state_('\0') {}
195 _LIBCPP_INLINE_VISIBILITY
196 __optional_storage(const __optional_storage& __x)
197 : __engaged_(__x.__engaged_)
200 ::new(_VSTD::addressof(__val_)) value_type(__x.__val_);
203 _LIBCPP_INLINE_VISIBILITY
204 __optional_storage(__optional_storage&& __x)
205 noexcept(is_nothrow_move_constructible<value_type>::value)
206 : __engaged_(__x.__engaged_)
209 ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_));
212 _LIBCPP_INLINE_VISIBILITY
213 constexpr __optional_storage(const value_type& __v)
217 _LIBCPP_INLINE_VISIBILITY
218 constexpr __optional_storage(value_type&& __v)
219 : __val_(_VSTD::move(__v)),
222 template <class... _Args>
223 _LIBCPP_INLINE_VISIBILITY
225 explicit __optional_storage(in_place_t, _Args&&... __args)
226 : __val_(_VSTD::forward<_Args>(__args)...),
231 class __optional_storage<_Tp, true>
234 typedef _Tp value_type;
240 bool __engaged_ = false;
242 _LIBCPP_INLINE_VISIBILITY
243 constexpr __optional_storage() noexcept
244 : __null_state_('\0') {}
246 _LIBCPP_INLINE_VISIBILITY
247 __optional_storage(const __optional_storage& __x)
248 : __engaged_(__x.__engaged_)
251 ::new(_VSTD::addressof(__val_)) value_type(__x.__val_);
254 _LIBCPP_INLINE_VISIBILITY
255 __optional_storage(__optional_storage&& __x)
256 noexcept(is_nothrow_move_constructible<value_type>::value)
257 : __engaged_(__x.__engaged_)
260 ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_));
263 _LIBCPP_INLINE_VISIBILITY
264 constexpr __optional_storage(const value_type& __v)
268 _LIBCPP_INLINE_VISIBILITY
269 constexpr __optional_storage(value_type&& __v)
270 : __val_(_VSTD::move(__v)),
273 template <class... _Args>
274 _LIBCPP_INLINE_VISIBILITY
276 explicit __optional_storage(in_place_t, _Args&&... __args)
277 : __val_(_VSTD::forward<_Args>(__args)...),
283 : private __optional_storage<_Tp>
285 typedef __optional_storage<_Tp> __base;
287 typedef _Tp value_type;
289 static_assert(!is_reference<value_type>::value,
290 "Instantiation of optional with a reference type is ill-formed.");
291 static_assert(!is_same<typename remove_cv<value_type>::type, in_place_t>::value,
292 "Instantiation of optional with a in_place_t type is ill-formed.");
293 static_assert(!is_same<typename remove_cv<value_type>::type, nullopt_t>::value,
294 "Instantiation of optional with a nullopt_t type is ill-formed.");
295 static_assert(is_object<value_type>::value,
296 "Instantiation of optional with a non-object type is undefined behavior.");
297 static_assert(is_nothrow_destructible<value_type>::value,
298 "Instantiation of optional with an object type that is not noexcept destructible is undefined behavior.");
300 _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
301 _LIBCPP_INLINE_VISIBILITY optional(const optional&) = default;
302 _LIBCPP_INLINE_VISIBILITY optional(optional&&) = default;
303 _LIBCPP_INLINE_VISIBILITY ~optional() = default;
304 _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
305 _LIBCPP_INLINE_VISIBILITY constexpr optional(const value_type& __v)
307 _LIBCPP_INLINE_VISIBILITY constexpr optional(value_type&& __v)
308 : __base(_VSTD::move(__v)) {}
310 template <class... _Args,
311 class = typename enable_if
313 is_constructible<value_type, _Args...>::value
316 _LIBCPP_INLINE_VISIBILITY
318 explicit optional(in_place_t, _Args&&... __args)
319 : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
321 template <class _Up, class... _Args,
322 class = typename enable_if
324 is_constructible<value_type, initializer_list<_Up>&, _Args...>::value
327 _LIBCPP_INLINE_VISIBILITY
329 explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
330 : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
332 _LIBCPP_INLINE_VISIBILITY
333 optional& operator=(nullopt_t) noexcept
335 if (this->__engaged_)
337 this->__val_.~value_type();
338 this->__engaged_ = false;
343 _LIBCPP_INLINE_VISIBILITY
345 operator=(const optional& __opt)
347 if (this->__engaged_ == __opt.__engaged_)
349 if (this->__engaged_)
350 this->__val_ = __opt.__val_;
354 if (this->__engaged_)
355 this->__val_.~value_type();
357 ::new(_VSTD::addressof(this->__val_)) value_type(__opt.__val_);
358 this->__engaged_ = __opt.__engaged_;
363 _LIBCPP_INLINE_VISIBILITY
365 operator=(optional&& __opt)
366 noexcept(is_nothrow_move_assignable<value_type>::value &&
367 is_nothrow_move_constructible<value_type>::value)
369 if (this->__engaged_ == __opt.__engaged_)
371 if (this->__engaged_)
372 this->__val_ = _VSTD::move(__opt.__val_);
376 if (this->__engaged_)
377 this->__val_.~value_type();
379 ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_));
380 this->__engaged_ = __opt.__engaged_;
386 class = typename enable_if
388 is_same<typename remove_reference<_Up>::type, value_type>::value &&
389 is_constructible<value_type, _Up>::value &&
390 is_assignable<value_type&, _Up>::value
393 _LIBCPP_INLINE_VISIBILITY
397 if (this->__engaged_)
398 this->__val_ = _VSTD::forward<_Up>(__v);
401 ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Up>(__v));
402 this->__engaged_ = true;
407 template <class... _Args,
408 class = typename enable_if
410 is_constructible<value_type, _Args...>::value
413 _LIBCPP_INLINE_VISIBILITY
415 emplace(_Args&&... __args)
418 ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
419 this->__engaged_ = true;
422 template <class _Up, class... _Args,
423 class = typename enable_if
425 is_constructible<value_type, initializer_list<_Up>&, _Args...>::value
428 _LIBCPP_INLINE_VISIBILITY
430 emplace(initializer_list<_Up> __il, _Args&&... __args)
433 ::new(_VSTD::addressof(this->__val_)) value_type(__il, _VSTD::forward<_Args>(__args)...);
434 this->__engaged_ = true;
437 _LIBCPP_INLINE_VISIBILITY
439 swap(optional& __opt)
440 noexcept(is_nothrow_move_constructible<value_type>::value &&
441 __is_nothrow_swappable<value_type>::value)
444 if (this->__engaged_ == __opt.__engaged_)
446 if (this->__engaged_)
447 swap(this->__val_, __opt.__val_);
451 if (this->__engaged_)
453 ::new(_VSTD::addressof(__opt.__val_)) value_type(_VSTD::move(this->__val_));
454 this->__val_.~value_type();
458 ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_));
459 __opt.__val_.~value_type();
461 swap(this->__engaged_, __opt.__engaged_);
465 _LIBCPP_INLINE_VISIBILITY
470 _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
471 return __operator_arrow(__has_operator_addressof<value_type>{});
474 _LIBCPP_INLINE_VISIBILITY
478 _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
479 return _VSTD::addressof(this->__val_);
482 _LIBCPP_INLINE_VISIBILITY
487 _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
491 _LIBCPP_INLINE_VISIBILITY
495 _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
499 _LIBCPP_INLINE_VISIBILITY
500 constexpr explicit operator bool() const noexcept {return this->__engaged_;}
502 _LIBCPP_INLINE_VISIBILITY
503 constexpr value_type const& value() const
505 if (!this->__engaged_)
506 throw bad_optional_access("optional<T>::value: not engaged");
510 _LIBCPP_INLINE_VISIBILITY
513 if (!this->__engaged_)
514 throw bad_optional_access("optional<T>::value: not engaged");
519 _LIBCPP_INLINE_VISIBILITY
520 constexpr value_type value_or(_Up&& __v) const&
522 static_assert(is_copy_constructible<value_type>::value,
523 "optional<T>::value_or: T must be copy constructible");
524 static_assert(is_convertible<_Up, value_type>::value,
525 "optional<T>::value_or: U must be convertible to T");
526 return this->__engaged_ ? this->__val_ :
527 static_cast<value_type>(_VSTD::forward<_Up>(__v));
531 _LIBCPP_INLINE_VISIBILITY
532 value_type value_or(_Up&& __v) &&
534 static_assert(is_move_constructible<value_type>::value,
535 "optional<T>::value_or: T must be move constructible");
536 static_assert(is_convertible<_Up, value_type>::value,
537 "optional<T>::value_or: U must be convertible to T");
538 return this->__engaged_ ? _VSTD::move(this->__val_) :
539 static_cast<value_type>(_VSTD::forward<_Up>(__v));
543 _LIBCPP_INLINE_VISIBILITY
545 __operator_arrow(true_type) const
547 return _VSTD::addressof(this->__val_);
550 _LIBCPP_INLINE_VISIBILITY
553 __operator_arrow(false_type) const
555 return &this->__val_;
560 inline _LIBCPP_INLINE_VISIBILITY
563 operator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
565 if (static_cast<bool>(__x) != static_cast<bool>(__y))
567 if (!static_cast<bool>(__x))
573 inline _LIBCPP_INLINE_VISIBILITY
576 operator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
578 if (!static_cast<bool>(__y))
580 if (!static_cast<bool>(__x))
582 return less<_Tp>{}(*__x, *__y);
586 inline _LIBCPP_INLINE_VISIBILITY
589 operator==(const optional<_Tp>& __x, nullopt_t) noexcept
591 return !static_cast<bool>(__x);
595 inline _LIBCPP_INLINE_VISIBILITY
598 operator==(nullopt_t, const optional<_Tp>& __x) noexcept
600 return !static_cast<bool>(__x);
604 inline _LIBCPP_INLINE_VISIBILITY
607 operator<(const optional<_Tp>&, nullopt_t) noexcept
613 inline _LIBCPP_INLINE_VISIBILITY
616 operator<(nullopt_t, const optional<_Tp>& __x) noexcept
618 return static_cast<bool>(__x);
622 inline _LIBCPP_INLINE_VISIBILITY
625 operator==(const optional<_Tp>& __x, const _Tp& __v)
627 return static_cast<bool>(__x) ? *__x == __v : false;
631 inline _LIBCPP_INLINE_VISIBILITY
634 operator==(const _Tp& __v, const optional<_Tp>& __x)
636 return static_cast<bool>(__x) ? *__x == __v : false;
640 inline _LIBCPP_INLINE_VISIBILITY
643 operator<(const optional<_Tp>& __x, const _Tp& __v)
645 return static_cast<bool>(__x) ? less<_Tp>{}(*__x, __v) : true;
649 inline _LIBCPP_INLINE_VISIBILITY
652 operator<(const _Tp& __v, const optional<_Tp>& __x)
654 return static_cast<bool>(__x) ? less<_Tp>{}(__v, *__x) : false;
658 inline _LIBCPP_INLINE_VISIBILITY
660 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
666 inline _LIBCPP_INLINE_VISIBILITY
668 optional<typename decay<_Tp>::type>
669 make_optional(_Tp&& __v)
671 return optional<typename decay<_Tp>::type>(_VSTD::forward<_Tp>(__v));
674 }}} // namespace std::experimental::__library_fundamentals_v1
676 _LIBCPP_BEGIN_NAMESPACE_STD
679 struct _LIBCPP_TYPE_VIS_ONLY hash<std::experimental::optional<_Tp> >
681 typedef std::experimental::optional<_Tp> argument_type;
682 typedef size_t result_type;
684 _LIBCPP_INLINE_VISIBILITY
685 result_type operator()(const argument_type& __opt) const _NOEXCEPT
687 return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0;
691 _LIBCPP_END_NAMESPACE_STD
693 #endif // _LIBCPP_STD_VER > 11
695 #endif // _LIBCPP_ARRAY