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>
157 # define _LIBCPP_ASSERT(x, m) ((void)0)
160 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
161 #pragma GCC system_header
164 namespace std { namespace experimental { inline namespace __library_fundamentals_v1 {
166 struct in_place_t {};
167 constexpr in_place_t in_place{};
171 explicit constexpr nullopt_t(int) noexcept {}
174 constexpr nullopt_t nullopt{0};
176 template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
177 class __optional_storage
180 typedef _Tp value_type;
186 bool __engaged_ = false;
188 _LIBCPP_INLINE_VISIBILITY
189 ~__optional_storage()
192 __val_.~value_type();
195 _LIBCPP_INLINE_VISIBILITY
196 constexpr __optional_storage() noexcept
197 : __null_state_('\0') {}
199 _LIBCPP_INLINE_VISIBILITY
200 __optional_storage(const __optional_storage& __x)
201 : __engaged_(__x.__engaged_)
204 ::new(_VSTD::addressof(__val_)) value_type(__x.__val_);
207 _LIBCPP_INLINE_VISIBILITY
208 __optional_storage(__optional_storage&& __x)
209 noexcept(is_nothrow_move_constructible<value_type>::value)
210 : __engaged_(__x.__engaged_)
213 ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_));
216 _LIBCPP_INLINE_VISIBILITY
217 constexpr __optional_storage(const value_type& __v)
221 _LIBCPP_INLINE_VISIBILITY
222 constexpr __optional_storage(value_type&& __v)
223 : __val_(_VSTD::move(__v)),
226 template <class... _Args>
227 _LIBCPP_INLINE_VISIBILITY
229 explicit __optional_storage(in_place_t, _Args&&... __args)
230 : __val_(_VSTD::forward<_Args>(__args)...),
235 class __optional_storage<_Tp, true>
238 typedef _Tp value_type;
244 bool __engaged_ = false;
246 _LIBCPP_INLINE_VISIBILITY
247 constexpr __optional_storage() noexcept
248 : __null_state_('\0') {}
250 _LIBCPP_INLINE_VISIBILITY
251 __optional_storage(const __optional_storage& __x)
252 : __engaged_(__x.__engaged_)
255 ::new(_VSTD::addressof(__val_)) value_type(__x.__val_);
258 _LIBCPP_INLINE_VISIBILITY
259 __optional_storage(__optional_storage&& __x)
260 noexcept(is_nothrow_move_constructible<value_type>::value)
261 : __engaged_(__x.__engaged_)
264 ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_));
267 _LIBCPP_INLINE_VISIBILITY
268 constexpr __optional_storage(const value_type& __v)
272 _LIBCPP_INLINE_VISIBILITY
273 constexpr __optional_storage(value_type&& __v)
274 : __val_(_VSTD::move(__v)),
277 template <class... _Args>
278 _LIBCPP_INLINE_VISIBILITY
280 explicit __optional_storage(in_place_t, _Args&&... __args)
281 : __val_(_VSTD::forward<_Args>(__args)...),
287 : private __optional_storage<_Tp>
289 typedef __optional_storage<_Tp> __base;
291 typedef _Tp value_type;
293 static_assert(!is_reference<value_type>::value,
294 "Instantiation of optional with a reference type is ill-formed.");
295 static_assert(!is_same<typename remove_cv<value_type>::type, in_place_t>::value,
296 "Instantiation of optional with a in_place_t type is ill-formed.");
297 static_assert(!is_same<typename remove_cv<value_type>::type, nullopt_t>::value,
298 "Instantiation of optional with a nullopt_t type is ill-formed.");
299 static_assert(is_object<value_type>::value,
300 "Instantiation of optional with a non-object type is undefined behavior.");
301 static_assert(is_nothrow_destructible<value_type>::value,
302 "Instantiation of optional with an object type that is not noexcept destructible is undefined behavior.");
304 _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
305 _LIBCPP_INLINE_VISIBILITY optional(const optional&) = default;
306 _LIBCPP_INLINE_VISIBILITY optional(optional&&) = default;
307 _LIBCPP_INLINE_VISIBILITY ~optional() = default;
308 _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
309 _LIBCPP_INLINE_VISIBILITY constexpr optional(const value_type& __v)
311 _LIBCPP_INLINE_VISIBILITY constexpr optional(value_type&& __v)
312 : __base(_VSTD::move(__v)) {}
314 template <class... _Args,
315 class = typename enable_if
317 is_constructible<value_type, _Args...>::value
320 _LIBCPP_INLINE_VISIBILITY
322 explicit optional(in_place_t, _Args&&... __args)
323 : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
325 template <class _Up, class... _Args,
326 class = typename enable_if
328 is_constructible<value_type, initializer_list<_Up>&, _Args...>::value
331 _LIBCPP_INLINE_VISIBILITY
333 explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
334 : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
336 _LIBCPP_INLINE_VISIBILITY
337 optional& operator=(nullopt_t) noexcept
339 if (this->__engaged_)
341 this->__val_.~value_type();
342 this->__engaged_ = false;
347 _LIBCPP_INLINE_VISIBILITY
349 operator=(const optional& __opt)
351 if (this->__engaged_ == __opt.__engaged_)
353 if (this->__engaged_)
354 this->__val_ = __opt.__val_;
358 if (this->__engaged_)
359 this->__val_.~value_type();
361 ::new(_VSTD::addressof(this->__val_)) value_type(__opt.__val_);
362 this->__engaged_ = __opt.__engaged_;
367 _LIBCPP_INLINE_VISIBILITY
369 operator=(optional&& __opt)
370 noexcept(is_nothrow_move_assignable<value_type>::value &&
371 is_nothrow_move_constructible<value_type>::value)
373 if (this->__engaged_ == __opt.__engaged_)
375 if (this->__engaged_)
376 this->__val_ = _VSTD::move(__opt.__val_);
380 if (this->__engaged_)
381 this->__val_.~value_type();
383 ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_));
384 this->__engaged_ = __opt.__engaged_;
390 class = typename enable_if
392 is_same<typename remove_reference<_Up>::type, value_type>::value &&
393 is_constructible<value_type, _Up>::value &&
394 is_assignable<value_type&, _Up>::value
397 _LIBCPP_INLINE_VISIBILITY
401 if (this->__engaged_)
402 this->__val_ = _VSTD::forward<_Up>(__v);
405 ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Up>(__v));
406 this->__engaged_ = true;
411 template <class... _Args,
412 class = typename enable_if
414 is_constructible<value_type, _Args...>::value
417 _LIBCPP_INLINE_VISIBILITY
419 emplace(_Args&&... __args)
422 ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
423 this->__engaged_ = true;
426 template <class _Up, class... _Args,
427 class = typename enable_if
429 is_constructible<value_type, initializer_list<_Up>&, _Args...>::value
432 _LIBCPP_INLINE_VISIBILITY
434 emplace(initializer_list<_Up> __il, _Args&&... __args)
437 ::new(_VSTD::addressof(this->__val_)) value_type(__il, _VSTD::forward<_Args>(__args)...);
438 this->__engaged_ = true;
441 _LIBCPP_INLINE_VISIBILITY
443 swap(optional& __opt)
444 noexcept(is_nothrow_move_constructible<value_type>::value &&
445 __is_nothrow_swappable<value_type>::value)
448 if (this->__engaged_ == __opt.__engaged_)
450 if (this->__engaged_)
451 swap(this->__val_, __opt.__val_);
455 if (this->__engaged_)
457 ::new(_VSTD::addressof(__opt.__val_)) value_type(_VSTD::move(this->__val_));
458 this->__val_.~value_type();
462 ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_));
463 __opt.__val_.~value_type();
465 swap(this->__engaged_, __opt.__engaged_);
469 _LIBCPP_INLINE_VISIBILITY
474 _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
475 return __operator_arrow(__has_operator_addressof<value_type>{});
478 _LIBCPP_INLINE_VISIBILITY
482 _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
483 return _VSTD::addressof(this->__val_);
486 _LIBCPP_INLINE_VISIBILITY
491 _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
495 _LIBCPP_INLINE_VISIBILITY
499 _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
503 _LIBCPP_INLINE_VISIBILITY
504 constexpr explicit operator bool() const noexcept {return this->__engaged_;}
506 _LIBCPP_INLINE_VISIBILITY
507 constexpr value_type const& value() const
509 if (!this->__engaged_)
510 throw bad_optional_access("optional<T>::value: not engaged");
514 _LIBCPP_INLINE_VISIBILITY
517 if (!this->__engaged_)
518 throw bad_optional_access("optional<T>::value: not engaged");
523 _LIBCPP_INLINE_VISIBILITY
524 constexpr value_type value_or(_Up&& __v) const&
526 static_assert(is_copy_constructible<value_type>::value,
527 "optional<T>::value_or: T must be copy constructible");
528 static_assert(is_convertible<_Up, value_type>::value,
529 "optional<T>::value_or: U must be convertible to T");
530 return this->__engaged_ ? this->__val_ :
531 static_cast<value_type>(_VSTD::forward<_Up>(__v));
535 _LIBCPP_INLINE_VISIBILITY
536 value_type value_or(_Up&& __v) &&
538 static_assert(is_move_constructible<value_type>::value,
539 "optional<T>::value_or: T must be move constructible");
540 static_assert(is_convertible<_Up, value_type>::value,
541 "optional<T>::value_or: U must be convertible to T");
542 return this->__engaged_ ? _VSTD::move(this->__val_) :
543 static_cast<value_type>(_VSTD::forward<_Up>(__v));
547 _LIBCPP_INLINE_VISIBILITY
549 __operator_arrow(true_type) const
551 return _VSTD::addressof(this->__val_);
554 _LIBCPP_INLINE_VISIBILITY
557 __operator_arrow(false_type) const
559 return &this->__val_;
564 inline _LIBCPP_INLINE_VISIBILITY
567 operator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
569 if (static_cast<bool>(__x) != static_cast<bool>(__y))
571 if (!static_cast<bool>(__x))
577 inline _LIBCPP_INLINE_VISIBILITY
580 operator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
582 if (!static_cast<bool>(__y))
584 if (!static_cast<bool>(__x))
586 return less<_Tp>{}(*__x, *__y);
590 inline _LIBCPP_INLINE_VISIBILITY
593 operator==(const optional<_Tp>& __x, nullopt_t) noexcept
595 return !static_cast<bool>(__x);
599 inline _LIBCPP_INLINE_VISIBILITY
602 operator==(nullopt_t, const optional<_Tp>& __x) noexcept
604 return !static_cast<bool>(__x);
608 inline _LIBCPP_INLINE_VISIBILITY
611 operator<(const optional<_Tp>&, nullopt_t) noexcept
617 inline _LIBCPP_INLINE_VISIBILITY
620 operator<(nullopt_t, const optional<_Tp>& __x) noexcept
622 return static_cast<bool>(__x);
626 inline _LIBCPP_INLINE_VISIBILITY
629 operator==(const optional<_Tp>& __x, const _Tp& __v)
631 return static_cast<bool>(__x) ? *__x == __v : false;
635 inline _LIBCPP_INLINE_VISIBILITY
638 operator==(const _Tp& __v, const optional<_Tp>& __x)
640 return static_cast<bool>(__x) ? *__x == __v : false;
644 inline _LIBCPP_INLINE_VISIBILITY
647 operator<(const optional<_Tp>& __x, const _Tp& __v)
649 return static_cast<bool>(__x) ? less<_Tp>{}(*__x, __v) : true;
653 inline _LIBCPP_INLINE_VISIBILITY
656 operator<(const _Tp& __v, const optional<_Tp>& __x)
658 return static_cast<bool>(__x) ? less<_Tp>{}(__v, *__x) : false;
662 inline _LIBCPP_INLINE_VISIBILITY
664 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
670 inline _LIBCPP_INLINE_VISIBILITY
672 optional<typename decay<_Tp>::type>
673 make_optional(_Tp&& __v)
675 return optional<typename decay<_Tp>::type>(_VSTD::forward<_Tp>(__v));
678 }}} // namespace std::experimental::__library_fundamentals_v1
680 _LIBCPP_BEGIN_NAMESPACE_STD
683 struct _LIBCPP_TYPE_VIS_ONLY hash<std::experimental::optional<_Tp> >
685 typedef std::experimental::optional<_Tp> argument_type;
686 typedef size_t result_type;
688 _LIBCPP_INLINE_VISIBILITY
689 result_type operator()(const argument_type& __opt) const _NOEXCEPT
691 return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0;
695 _LIBCPP_END_NAMESPACE_STD
697 #endif // _LIBCPP_STD_VER > 11
699 #endif // _LIBCPP_ARRAY