blob: 46252c7e0e01d9a0faa7dd114b5b0c7ee144cd32 [file] [log] [blame]
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001// -*- C++ -*-
2//===-------------------------- optional ----------------------------------===//
3//
4// The LLVM Compiler Infrastructure
5//
6// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_OPTIONAL
12#define _LIBCPP_OPTIONAL
13
14/*
15 optional synopsis
16
17// C++1z
18
19namespace std {
20 // 20.6.3, optional for object types
21 template <class T> class optional;
22
23 // 20.6.4, no-value state indicator
24 struct nullopt_t{see below };
25 constexpr nullopt_t nullopt(unspecified );
26
27 // 20.6.5, class bad_optional_access
28 class bad_optional_access;
29
30 // 20.6.6, relational operators
31 template <class T>
32 constexpr bool operator==(const optional<T>&, const optional<T>&);
33 template <class T>
34 constexpr bool operator!=(const optional<T>&, const optional<T>&);
35 template <class T>
36 constexpr bool operator<(const optional<T>&, const optional<T>&);
37 template <class T>
38 constexpr bool operator>(const optional<T>&, const optional<T>&);
39 template <class T>
40 constexpr bool operator<=(const optional<T>&, const optional<T>&);
41 template <class T>
42 constexpr bool operator>=(const optional<T>&, const optional<T>&);
43 template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
44 template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept;
45 template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept;
46 template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept;
47 template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept;
48 template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept;
49 template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept;
50 template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept;
51 template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept;
52 template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept;
53 template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept;
54 template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept;
55
56 // 20.6.8, comparison with T
57 template <class T> constexpr bool operator==(const optional<T>&, const T&);
58 template <class T> constexpr bool operator==(const T&, const optional<T>&);
59 template <class T> constexpr bool operator!=(const optional<T>&, const T&);
60 template <class T> constexpr bool operator!=(const T&, const optional<T>&);
61 template <class T> constexpr bool operator<(const optional<T>&, const T&);
62 template <class T> constexpr bool operator<(const T&, const optional<T>&);
63 template <class T> constexpr bool operator<=(const optional<T>&, const T&);
64 template <class T> constexpr bool operator<=(const T&, const optional<T>&);
65 template <class T> constexpr bool operator>(const optional<T>&, const T&);
66 template <class T> constexpr bool operator>(const T&, const optional<T>&);
67 template <class T> constexpr bool operator>=(const optional<T>&, const T&);
68 template <class T> constexpr bool operator>=(const T&, const optional<T>&);
69
70 // 20.6.9, specialized algorithms
71 template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below );
72 template <class T> constexpr optional<see below > make_optional(T&&);
73 template <class T, class... Args>
74 constexpr optional<T> make_optional(Args&&... args);
75 template <class T, class U, class... Args>
76 constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args);
77
78 // 20.6.10, hash support
79 template <class T> struct hash;
80 template <class T> struct hash<optional<T>>;
81
82 template <class T> class optional {
83 public:
84 using value_type = T;
85
86 // 20.6.3.1, constructors
87 constexpr optional() noexcept;
88 constexpr optional(nullopt_t) noexcept;
89 optional(const optional &);
90 optional(optional &&) noexcept(see below );
91 template <class... Args> constexpr explicit optional(in_place_t, Args &&...);
92 template <class U, class... Args>
93 constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...);
94 template <class U = T>
95 constexpr EXPLICIT optional(U &&);
96 template <class U>
97 constexpr EXPLICIT optional(const optional<U> &);
98 template <class U>
99 constexpr EXPLICIT optional(optional<U> &&);
100
101 // 20.6.3.2, destructor
102 ~optional();
103
104 // 20.6.3.3, assignment
105 optional &operator=(nullopt_t) noexcept;
106 optional &operator=(const optional &);
107 optional &operator=(optional &&) noexcept(see below );
108 template <class U = T> optional &operator=(U &&);
109 template <class U> optional &operator=(const optional<U> &);
110 template <class U> optional &operator=(optional<U> &&);
111 template <class... Args> void emplace(Args &&...);
112 template <class U, class... Args>
113 void emplace(initializer_list<U>, Args &&...);
114
115 // 20.6.3.4, swap
116 void swap(optional &) noexcept(see below );
117
118 // 20.6.3.5, observers
119 constexpr T const *operator->() const;
120 constexpr T *operator->();
121 constexpr T const &operator*() const &;
122 constexpr T &operator*() &;
123 constexpr T &&operator*() &&;
124 constexpr const T &&operator*() const &&;
125 constexpr explicit operator bool() const noexcept;
126 constexpr bool has_value() const noexcept;
127 constexpr T const &value() const &;
128 constexpr T &value() &;
129 constexpr T &&value() &&;
130 constexpr const T &&value() const &&;
131 template <class U> constexpr T value_or(U &&) const &;
132 template <class U> constexpr T value_or(U &&) &&;
133
134 // 20.6.3.6, modifiers
135 void reset() noexcept;
136
137 private:
138 T *val; // exposition only
139 };
140} // namespace std
141
142*/
143
144#include <__config>
145#include <__debug>
146#include <__functional_base>
147#include <__undef_min_max>
148#include <functional>
149#include <initializer_list>
150#include <new>
151#include <stdexcept>
152#include <type_traits>
153#include <utility>
154
155#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
156#pragma GCC system_header
157#endif
158
159namespace std // purposefully not using versioning namespace
160{
161
162class _LIBCPP_EXCEPTION_ABI bad_optional_access
163 : public logic_error
164{
165public:
166 _LIBCPP_INLINE_VISIBILITY
167 bad_optional_access() : logic_error("bad optional access") {}
168
169 // Get the key function ~bad_optional_access() into the dylib
170 _LIBCPP_FUNC_VIS
171 virtual ~bad_optional_access() _NOEXCEPT;
172};
173
174} // std
175
176#if _LIBCPP_STD_VER > 14
177
178_LIBCPP_BEGIN_NAMESPACE_STD
179
180_LIBCPP_NORETURN
181inline _LIBCPP_INLINE_VISIBILITY
182void __throw_bad_optional_access() {
183#ifndef _LIBCPP_NO_EXCEPTIONS
184 throw bad_optional_access();
185#else
186 _VSTD::abort();
187#endif
188}
189
190struct nullopt_t
191{
192 struct __secret_tag { _LIBCPP_INLINE_VISIBILITY explicit __secret_tag() = default; };
193 _LIBCPP_INLINE_VISIBILITY constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {}
194};
195
196/* inline */ constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}};
197
198template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
199struct __optional_destruct_base;
200
201template <class _Tp>
202struct __optional_destruct_base<_Tp, false>
203{
204 typedef _Tp value_type;
205 static_assert(is_object_v<value_type>,
206 "instantiation of optional with a non-object type is undefined behavior");
207 union
208 {
209 char __null_state_;
210 value_type __val_;
211 };
212 bool __engaged_;
213
214 _LIBCPP_INLINE_VISIBILITY
215 ~__optional_destruct_base()
216 {
217 if (__engaged_)
218 __val_.~value_type();
219 }
220
221 _LIBCPP_INLINE_VISIBILITY
222 constexpr __optional_destruct_base() noexcept
223 : __null_state_(),
224 __engaged_(false) {}
225
226 template <class... _Args>
227 _LIBCPP_INLINE_VISIBILITY
228 constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
229 : __val_(_VSTD::forward<_Args>(__args)...),
230 __engaged_(true) {}
231
232 _LIBCPP_INLINE_VISIBILITY
233 void reset() noexcept
234 {
235 if (__engaged_)
236 {
237 __val_.~value_type();
238 __engaged_ = false;
239 }
240 }
241};
242
243template <class _Tp>
244struct __optional_destruct_base<_Tp, true>
245{
246 typedef _Tp value_type;
247 static_assert(is_object_v<value_type>,
248 "instantiation of optional with a non-object type is undefined behavior");
249 union
250 {
251 char __null_state_;
252 value_type __val_;
253 };
254 bool __engaged_;
255
256 _LIBCPP_INLINE_VISIBILITY
257 constexpr __optional_destruct_base() noexcept
258 : __null_state_(),
259 __engaged_(false) {}
260
261 template <class... _Args>
262 _LIBCPP_INLINE_VISIBILITY
263 constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
264 : __val_(_VSTD::forward<_Args>(__args)...),
265 __engaged_(true) {}
266
267 _LIBCPP_INLINE_VISIBILITY
268 void reset() noexcept
269 {
270 if (__engaged_)
271 {
272 __engaged_ = false;
273 }
274 }
275};
276
277template <class _Tp, bool = is_reference<_Tp>::value>
278struct __optional_storage_base : __optional_destruct_base<_Tp>
279{
280 using __base = __optional_destruct_base<_Tp>;
281 using value_type = _Tp;
282 using __base::__base;
283
284 _LIBCPP_INLINE_VISIBILITY
285 constexpr bool has_value() const noexcept
286 {
287 return this->__engaged_;
288 }
289
290 _LIBCPP_INLINE_VISIBILITY
291 constexpr value_type& __get() & noexcept
292 {
293 return this->__val_;
294 }
295 _LIBCPP_INLINE_VISIBILITY
296 constexpr const value_type& __get() const& noexcept
297 {
298 return this->__val_;
299 }
300 _LIBCPP_INLINE_VISIBILITY
301 constexpr value_type&& __get() && noexcept
302 {
303 return _VSTD::move(this->__val_);
304 }
305 _LIBCPP_INLINE_VISIBILITY
306 constexpr const value_type&& __get() const&& noexcept
307 {
308 return _VSTD::move(this->__val_);
309 }
310
311 template <class... _Args>
312 _LIBCPP_INLINE_VISIBILITY
313 void __construct(_Args&&... __args)
314 {
315 _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
316 ::new((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
317 this->__engaged_ = true;
318 }
319
320 template <class _That>
321 _LIBCPP_INLINE_VISIBILITY
322 void __construct_from(_That&& __opt)
323 {
324 if (__opt.has_value())
325 __construct(_VSTD::forward<_That>(__opt).__get());
326 }
327
328 template <class _That>
329 _LIBCPP_INLINE_VISIBILITY
330 void __assign_from(_That&& __opt)
331 {
332 if (this->__engaged_ == __opt.has_value())
333 {
334 if (this->__engaged_)
335 this->__val_ = _VSTD::forward<_That>(__opt).__get();
336 }
337 else
338 {
339 if (this->__engaged_)
340 this->reset();
341 else
342 __construct(_VSTD::forward<_That>(__opt).__get());
343 }
344 }
345};
346
347// optional<T&> is currently required ill-formed, however it may to be in the
348// future. For this reason it has already been implemented to ensure we can
349// make the change in an ABI compatible manner.
350template <class _Tp>
351struct __optional_storage_base<_Tp, true>
352{
353 using value_type = _Tp;
354 using __raw_type = remove_reference_t<_Tp>;
355 __raw_type* __value_;
356
357 template <class _Up>
358 static constexpr bool __can_bind_reference() {
359 using _RawUp = typename remove_reference<_Up>::type;
360 using _UpPtr = _RawUp*;
361 using _RawTp = typename remove_reference<_Tp>::type;
362 using _TpPtr = _RawTp*;
363 using _CheckLValueArg = integral_constant<bool,
364 (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value)
365 || is_same<_RawUp, reference_wrapper<_RawTp>>::value
366 || is_same<_RawUp, reference_wrapper<typename remove_const<_RawTp>::type>>::value
367 >;
368 return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value)
369 || (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value &&
370 is_convertible<_UpPtr, _TpPtr>::value);
371 }
372
373 _LIBCPP_INLINE_VISIBILITY
374 constexpr __optional_storage_base() noexcept
375 : __value_(nullptr) {}
376
377 template <class _UArg>
378 _LIBCPP_INLINE_VISIBILITY
379 constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg)
380 : __value_(_VSTD::addressof(__uarg))
381 {
382 static_assert(__can_bind_reference<_UArg>(),
383 "Attempted to construct a reference element in tuple from a "
384 "possible temporary");
385 }
386
387 _LIBCPP_INLINE_VISIBILITY
388 void reset() noexcept { __value_ = nullptr; }
389
390 _LIBCPP_INLINE_VISIBILITY
391 constexpr bool has_value() const noexcept
392 { return __value_ != nullptr; }
393
394 _LIBCPP_INLINE_VISIBILITY
395 constexpr value_type& __get() const& noexcept
396 { return *__value_; }
397
398 _LIBCPP_INLINE_VISIBILITY
399 constexpr value_type&& __get() const&& noexcept
400 { return _VSTD::forward<value_type>(*__value_); }
401
402 template <class _UArg>
403 _LIBCPP_INLINE_VISIBILITY
404 void __construct(_UArg&& __val)
405 {
406 _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
407 static_assert(__can_bind_reference<_UArg>(),
408 "Attempted to construct a reference element in tuple from a "
409 "possible temporary");
410 __value_ = _VSTD::addressof(__val);
411 }
412
413 template <class _That>
414 _LIBCPP_INLINE_VISIBILITY
415 void __construct_from(_That&& __opt)
416 {
417 if (__opt.has_value())
418 __construct(_VSTD::forward<_That>(__opt).__get());
419 }
420
421 template <class _That>
422 _LIBCPP_INLINE_VISIBILITY
423 void __assign_from(_That&& __opt)
424 {
425 if (has_value() == __opt.has_value())
426 {
427 if (has_value())
428 *__value_ = _VSTD::forward<_That>(__opt).__get();
429 }
430 else
431 {
432 if (has_value())
433 reset();
434 else
435 __construct(_VSTD::forward<_That>(__opt).__get());
436 }
437 }
438};
439
440template <class _Tp, bool = is_trivially_copyable<_Tp>::value>
441struct __optional_storage;
442
443template <class _Tp>
444struct __optional_storage<_Tp, true> : __optional_storage_base<_Tp>
445{
446 using __optional_storage_base<_Tp>::__optional_storage_base;
447};
448
449template <class _Tp>
450struct __optional_storage<_Tp, false> : __optional_storage_base<_Tp>
451{
452 using value_type = _Tp;
453 using __optional_storage_base<_Tp>::__optional_storage_base;
454
455 _LIBCPP_INLINE_VISIBILITY
456 __optional_storage() = default;
457
458 _LIBCPP_INLINE_VISIBILITY
459 __optional_storage(const __optional_storage& __opt)
460 {
461 this->__construct_from(__opt);
462 }
463
464 _LIBCPP_INLINE_VISIBILITY
465 __optional_storage(__optional_storage&& __opt)
466 noexcept(is_nothrow_move_constructible_v<value_type>)
467 {
468 this->__construct_from(_VSTD::move(__opt));
469 }
470
471 _LIBCPP_INLINE_VISIBILITY
472 __optional_storage& operator=(const __optional_storage& __opt)
473 {
474 this->__assign_from(__opt);
475 return *this;
476 }
477
478 _LIBCPP_INLINE_VISIBILITY
479 __optional_storage& operator=(__optional_storage&& __opt)
480 noexcept(is_nothrow_move_assignable_v<value_type> &&
481 is_nothrow_move_constructible_v<value_type>)
482 {
483 this->__assign_from(_VSTD::move(__opt));
484 return *this;
485 }
486};
487
488template <class _Tp>
489using __optional_sfinae_ctor_base_t = __sfinae_ctor_base<
490 is_copy_constructible<_Tp>::value,
491 is_move_constructible<_Tp>::value
492>;
493
494template <class _Tp>
495using __optional_sfinae_assign_base_t = __sfinae_assign_base<
496 (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value),
497 (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value)
498>;
499
500template <class _Tp>
501class optional
502 : private __optional_storage<_Tp>
503 , private __optional_sfinae_ctor_base_t<_Tp>
504 , private __optional_sfinae_assign_base_t<_Tp>
505{
506 using __base = __optional_storage<_Tp>;
507public:
508 using value_type = _Tp;
509
510private:
511 // Disable the reference extension using this static assert.
512 static_assert(!is_same_v<value_type, in_place_t>,
513 "instantiation of optional with in_place_t is ill-formed");
514 static_assert(!is_same_v<__uncvref_t<value_type>, nullopt_t>,
515 "instantiation of optional with nullopt_t is ill-formed");
516 static_assert(!is_reference_v<value_type>,
517 "instantiation of optional with a reference type is ill-formed");
518 static_assert(is_destructible_v<value_type>,
519 "instantiation of optional with a non-destructible type is ill-formed");
520
521 // LWG2756: conditionally explicit conversion from _Up
522 struct _CheckOptionalArgsConstructor {
523 template <class _Up>
524 static constexpr bool __enable_implicit() {
525 return is_constructible_v<_Tp, _Up&&> &&
526 is_convertible_v<_Up&&, _Tp>;
527 }
528
529 template <class _Up>
530 static constexpr bool __enable_explicit() {
531 return is_constructible_v<_Tp, _Up&&> &&
532 !is_convertible_v<_Up&&, _Tp>;
533 }
534 };
535 template <class _Up>
536 using _CheckOptionalArgsCtor = conditional_t<
537 !is_same_v<in_place_t, _Up> &&
538 !is_same_v<decay_t<_Up>, optional>,
539 _CheckOptionalArgsConstructor,
540 __check_tuple_constructor_fail
541 >;
542 template <class _QualUp>
543 struct _CheckOptionalLikeConstructor {
544 template <class _Up, class _Opt = optional<_Up>>
545 using __check_constructible_from_opt = __lazy_or<
546 is_constructible<_Tp, _Opt&>,
547 is_constructible<_Tp, _Opt const&>,
548 is_constructible<_Tp, _Opt&&>,
549 is_constructible<_Tp, _Opt const&&>,
550 is_convertible<_Opt&, _Tp>,
551 is_convertible<_Opt const&, _Tp>,
552 is_convertible<_Opt&&, _Tp>,
553 is_convertible<_Opt const&&, _Tp>
554 >;
555 template <class _Up, class _Opt = optional<_Up>>
556 using __check_assignable_from_opt = __lazy_or<
557 is_assignable<_Tp&, _Opt&>,
558 is_assignable<_Tp&, _Opt const&>,
559 is_assignable<_Tp&, _Opt&&>,
560 is_assignable<_Tp&, _Opt const&&>
561 >;
562 template <class _Up, class _QUp = _QualUp>
563 static constexpr bool __enable_implicit() {
564 return is_convertible<_QUp, _Tp>::value &&
565 !__check_constructible_from_opt<_Up>::value;
566 }
567 template <class _Up, class _QUp = _QualUp>
568 static constexpr bool __enable_explicit() {
569 return !is_convertible<_QUp, _Tp>::value &&
570 !__check_constructible_from_opt<_Up>::value;
571 }
572 template <class _Up, class _QUp = _QualUp>
573 static constexpr bool __enable_assign() {
574 // Construction and assignability of _Qup to _Tp has already been
575 // checked.
576 return !__check_constructible_from_opt<_Up>::value &&
577 !__check_assignable_from_opt<_Up>::value;
578 }
579 };
580
581 template <class _Up, class _QualUp>
582 using _CheckOptionalLikeCtor = conditional_t<
583 __lazy_and<
584 __lazy_not<is_same<_Up, _Tp>>,
585 is_constructible<_Tp, _QualUp>
586 >::value,
587 _CheckOptionalLikeConstructor<_QualUp>,
588 __check_tuple_constructor_fail
589 >;
590 template <class _Up, class _QualUp>
591 using _CheckOptionalLikeAssign = conditional_t<
592 __lazy_and<
593 __lazy_not<is_same<_Up, _Tp>>,
594 is_constructible<_Tp, _QualUp>,
595 is_assignable<_Tp&, _QualUp>
596 >::value,
597 _CheckOptionalLikeConstructor<_QualUp>,
598 __check_tuple_constructor_fail
599 >;
600public:
601
602 _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
603 _LIBCPP_INLINE_VISIBILITY optional(const optional&) = default;
604 _LIBCPP_INLINE_VISIBILITY optional(optional&&) = default;
605 _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
606
607 template <class... _Args, class = enable_if_t<
608 is_constructible_v<value_type, _Args...>>
609 >
610 _LIBCPP_INLINE_VISIBILITY
611 constexpr explicit optional(in_place_t, _Args&&... __args)
612 : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
613
614 template <class _Up, class... _Args, class = enable_if_t<
615 is_constructible_v<value_type, initializer_list<_Up>&, _Args...>>
616 >
617 _LIBCPP_INLINE_VISIBILITY
618 constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
619 : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
620
621 template <class _Up = value_type, enable_if_t<
622 _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>()
623 , int> = 0>
624 _LIBCPP_INLINE_VISIBILITY
625 constexpr optional(_Up&& __v)
626 : __base(in_place, _VSTD::forward<_Up>(__v)) {}
627
628 template <class _Up, enable_if_t<
629 _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>()
630 , int> = 0>
631 _LIBCPP_INLINE_VISIBILITY
632 constexpr explicit optional(_Up&& __v)
633 : __base(in_place, _VSTD::forward<_Up>(__v)) {}
634
635 // LWG2756: conditionally explicit conversion from const optional<_Up>&
636 template <class _Up, enable_if_t<
637 _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>()
638 , int> = 0>
639 _LIBCPP_INLINE_VISIBILITY
640 optional(const optional<_Up>& __v)
641 {
642 this->__construct_from(__v);
643 }
644 template <class _Up, enable_if_t<
645 _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>()
646 , int> = 0>
647 _LIBCPP_INLINE_VISIBILITY
648 explicit optional(const optional<_Up>& __v)
649 {
650 this->__construct_from(__v);
651 }
652
653 // LWG2756: conditionally explicit conversion from optional<_Up>&&
654 template <class _Up, enable_if_t<
655 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>()
656 , int> = 0>
657 _LIBCPP_INLINE_VISIBILITY
658 optional(optional<_Up>&& __v)
659 {
660 this->__construct_from(_VSTD::move(__v));
661 }
662 template <class _Up, enable_if_t<
663 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>()
664 , int> = 0>
665 _LIBCPP_INLINE_VISIBILITY
666 explicit optional(optional<_Up>&& __v)
667 {
668 this->__construct_from(_VSTD::move(__v));
669 }
670
671 _LIBCPP_INLINE_VISIBILITY
672 optional& operator=(nullopt_t) noexcept
673 {
674 reset();
675 return *this;
676 }
677
678 _LIBCPP_INLINE_VISIBILITY optional& operator=(const optional&) = default;
679 _LIBCPP_INLINE_VISIBILITY optional& operator=(optional&&) = default;
680
681 // LWG2756
682 template <class _Up = value_type,
683 class = enable_if_t
684 <
685 !is_same_v<_Up, optional> &&
686 !(is_same_v<_Up, value_type> && is_scalar_v<value_type>) &&
687 is_constructible_v<value_type, _Up> &&
688 is_assignable_v<value_type&, _Up>
689 >
690 >
691 _LIBCPP_INLINE_VISIBILITY
692 optional&
693 operator=(_Up&& __v)
694 {
695 if (this->has_value())
696 this->__get() = _VSTD::forward<_Up>(__v);
697 else
698 this->__construct(_VSTD::forward<_Up>(__v));
699 return *this;
700 }
701
702 // LWG2756
703 template <class _Up, enable_if_t<
704 _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>()
705 , int> = 0>
706 _LIBCPP_INLINE_VISIBILITY
707 optional&
708 operator=(const optional<_Up>& __v)
709 {
710 this->__assign_from(__v);
711 return *this;
712 }
713
714 // LWG2756
715 template <class _Up, enable_if_t<
716 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>()
717 , int> = 0>
718 _LIBCPP_INLINE_VISIBILITY
719 optional&
720 operator=(optional<_Up>&& __v)
721 {
722 this->__assign_from(_VSTD::move(__v));
723 return *this;
724 }
725
726 template <class... _Args,
727 class = enable_if_t
728 <
729 is_constructible_v<value_type, _Args...>
730 >
731 >
732 _LIBCPP_INLINE_VISIBILITY
733 void
734 emplace(_Args&&... __args)
735 {
736 reset();
737 this->__construct(_VSTD::forward<_Args>(__args)...);
738 }
739
740 template <class _Up, class... _Args,
741 class = enable_if_t
742 <
743 is_constructible_v<value_type, initializer_list<_Up>&, _Args...>
744 >
745 >
746 _LIBCPP_INLINE_VISIBILITY
747 void
748 emplace(initializer_list<_Up> __il, _Args&&... __args)
749 {
750 reset();
751 this->__construct(__il, _VSTD::forward<_Args>(__args)...);
752 }
753
754 _LIBCPP_INLINE_VISIBILITY
755 void swap(optional& __opt)
756 noexcept(is_nothrow_move_constructible_v<value_type> &&
757 is_nothrow_swappable_v<value_type>)
758 {
759 if (this->has_value() == __opt.has_value())
760 {
761 using _VSTD::swap;
762 if (this->has_value())
763 swap(this->__get(), __opt.__get());
764 }
765 else
766 {
767 if (this->has_value())
768 {
769 __opt.__construct(_VSTD::move(this->__get()));
770 reset();
771 }
772 else
773 {
774 this->__construct(_VSTD::move(__opt.__get()));
775 __opt.reset();
776 }
777 }
778 }
779
780 _LIBCPP_INLINE_VISIBILITY
781 constexpr
782 add_pointer_t<value_type const>
783 operator->() const
784 {
785 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
786#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
787 return _VSTD::addressof(this->__get());
788#else
789 return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
790#endif
791 }
792
793 _LIBCPP_INLINE_VISIBILITY
794 constexpr
795 add_pointer_t<value_type>
796 operator->()
797 {
798 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
799#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
800 return _VSTD::addressof(this->__get());
801#else
802 return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
803#endif
804 }
805
806 _LIBCPP_INLINE_VISIBILITY
807 constexpr
808 const value_type&
809 operator*() const&
810 {
811 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
812 return this->__get();
813 }
814
815 _LIBCPP_INLINE_VISIBILITY
816 constexpr
817 value_type&
818 operator*() &
819 {
820 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
821 return this->__get();
822 }
823
824 _LIBCPP_INLINE_VISIBILITY
825 constexpr
826 value_type&&
827 operator*() &&
828 {
829 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
830 return _VSTD::move(this->__get());
831 }
832
833 _LIBCPP_INLINE_VISIBILITY
834 constexpr
835 const value_type&&
836 operator*() const&&
837 {
838 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
839 return _VSTD::move(this->__get());
840 }
841
842 _LIBCPP_INLINE_VISIBILITY
843 constexpr explicit operator bool() const noexcept { return has_value(); }
844
845 using __base::has_value;
846 using __base::__get;
847
848 _LIBCPP_INLINE_VISIBILITY
849 constexpr value_type const& value() const&
850 {
851 if (!this->has_value())
852 __throw_bad_optional_access();
853 return this->__get();
854 }
855
856 _LIBCPP_INLINE_VISIBILITY
857 constexpr value_type& value() &
858 {
859 if (!this->has_value())
860 __throw_bad_optional_access();
861 return this->__get();
862 }
863
864 _LIBCPP_INLINE_VISIBILITY
865 constexpr value_type&& value() &&
866 {
867 if (!this->has_value())
868 __throw_bad_optional_access();
869 return _VSTD::move(this->__get());
870 }
871
872 _LIBCPP_INLINE_VISIBILITY
873 constexpr value_type const&& value() const&&
874 {
875 if (!this->has_value())
876 __throw_bad_optional_access();
877 return _VSTD::move(this->__get());
878 }
879
880 template <class _Up>
881 _LIBCPP_INLINE_VISIBILITY
882 constexpr value_type value_or(_Up&& __v) const&
883 {
884 static_assert(is_copy_constructible_v<value_type>,
885 "optional<T>::value_or: T must be copy constructible");
886 static_assert(is_convertible_v<_Up, value_type>,
887 "optional<T>::value_or: U must be convertible to T");
888 return this->has_value() ? this->__get() :
889 static_cast<value_type>(_VSTD::forward<_Up>(__v));
890 }
891
892 template <class _Up>
893 _LIBCPP_INLINE_VISIBILITY
894 value_type value_or(_Up&& __v) &&
895 {
896 static_assert(is_move_constructible_v<value_type>,
897 "optional<T>::value_or: T must be move constructible");
898 static_assert(is_convertible_v<_Up, value_type>,
899 "optional<T>::value_or: U must be convertible to T");
900 return this->has_value() ? _VSTD::move(this->__get()) :
901 static_cast<value_type>(_VSTD::forward<_Up>(__v));
902 }
903
904 using __base::reset;
905
906private:
907 template <class _Up>
908 _LIBCPP_INLINE_VISIBILITY
909 static _Up*
910 __operator_arrow(true_type, _Up& __x)
911 {
912 return _VSTD::addressof(__x);
913 }
914
915 template <class _Up>
916 _LIBCPP_INLINE_VISIBILITY
917 static constexpr _Up*
918 __operator_arrow(false_type, _Up& __x)
919 {
920 return &__x;
921 }
922};
923
924// Comparisons between optionals
925template <class _Tp>
926_LIBCPP_INLINE_VISIBILITY constexpr
927enable_if_t<
928 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
929 _VSTD::declval<const _Tp&>()), bool>,
930 bool
931>
932operator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
933{
934 if (static_cast<bool>(__x) != static_cast<bool>(__y))
935 return false;
936 if (!static_cast<bool>(__x))
937 return true;
938 return *__x == *__y;
939}
940
941template <class _Tp>
942_LIBCPP_INLINE_VISIBILITY constexpr
943enable_if_t<
944 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
945 _VSTD::declval<const _Tp&>()), bool>,
946 bool
947>
948operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y)
949{
950 if (static_cast<bool>(__x) != static_cast<bool>(__y))
951 return true;
952 if (!static_cast<bool>(__x))
953 return false;
954 return *__x != *__y;
955}
956
957template <class _Tp>
958_LIBCPP_INLINE_VISIBILITY constexpr
959enable_if_t<
960 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
961 _VSTD::declval<const _Tp&>()), bool>,
962 bool
963>
964operator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
965{
966 if (!static_cast<bool>(__y))
967 return false;
968 if (!static_cast<bool>(__x))
969 return true;
970 return *__x < *__y;
971}
972
973template <class _Tp>
974_LIBCPP_INLINE_VISIBILITY constexpr
975enable_if_t<
976 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
977 _VSTD::declval<const _Tp&>()), bool>,
978 bool
979>
980operator>(const optional<_Tp>& __x, const optional<_Tp>& __y)
981{
982 if (!static_cast<bool>(__x))
983 return false;
984 if (!static_cast<bool>(__y))
985 return true;
986 return *__x > *__y;
987}
988
989template <class _Tp>
990_LIBCPP_INLINE_VISIBILITY constexpr
991enable_if_t<
992 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
993 _VSTD::declval<const _Tp&>()), bool>,
994 bool
995>
996operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y)
997{
998 if (!static_cast<bool>(__x))
999 return true;
1000 if (!static_cast<bool>(__y))
1001 return false;
1002 return *__x <= *__y;
1003}
1004
1005template <class _Tp>
1006_LIBCPP_INLINE_VISIBILITY constexpr
1007enable_if_t<
1008 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1009 _VSTD::declval<const _Tp&>()), bool>,
1010 bool
1011>
1012operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y)
1013{
1014 if (!static_cast<bool>(__y))
1015 return true;
1016 if (!static_cast<bool>(__x))
1017 return false;
1018 return *__x >= *__y;
1019}
1020
1021// Comparisons with nullopt
1022template <class _Tp>
1023_LIBCPP_INLINE_VISIBILITY constexpr
1024bool
1025operator==(const optional<_Tp>& __x, nullopt_t) noexcept
1026{
1027 return !static_cast<bool>(__x);
1028}
1029
1030template <class _Tp>
1031_LIBCPP_INLINE_VISIBILITY constexpr
1032bool
1033operator==(nullopt_t, const optional<_Tp>& __x) noexcept
1034{
1035 return !static_cast<bool>(__x);
1036}
1037
1038template <class _Tp>
1039_LIBCPP_INLINE_VISIBILITY constexpr
1040bool
1041operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
1042{
1043 return static_cast<bool>(__x);
1044}
1045
1046template <class _Tp>
1047_LIBCPP_INLINE_VISIBILITY constexpr
1048bool
1049operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
1050{
1051 return static_cast<bool>(__x);
1052}
1053
1054template <class _Tp>
1055_LIBCPP_INLINE_VISIBILITY constexpr
1056bool
1057operator<(const optional<_Tp>&, nullopt_t) noexcept
1058{
1059 return false;
1060}
1061
1062template <class _Tp>
1063_LIBCPP_INLINE_VISIBILITY constexpr
1064bool
1065operator<(nullopt_t, const optional<_Tp>& __x) noexcept
1066{
1067 return static_cast<bool>(__x);
1068}
1069
1070template <class _Tp>
1071_LIBCPP_INLINE_VISIBILITY constexpr
1072bool
1073operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
1074{
1075 return !static_cast<bool>(__x);
1076}
1077
1078template <class _Tp>
1079_LIBCPP_INLINE_VISIBILITY constexpr
1080bool
1081operator<=(nullopt_t, const optional<_Tp>& __x) noexcept
1082{
1083 return true;
1084}
1085
1086template <class _Tp>
1087_LIBCPP_INLINE_VISIBILITY constexpr
1088bool
1089operator>(const optional<_Tp>& __x, nullopt_t) noexcept
1090{
1091 return static_cast<bool>(__x);
1092}
1093
1094template <class _Tp>
1095_LIBCPP_INLINE_VISIBILITY constexpr
1096bool
1097operator>(nullopt_t, const optional<_Tp>& __x) noexcept
1098{
1099 return false;
1100}
1101
1102template <class _Tp>
1103_LIBCPP_INLINE_VISIBILITY constexpr
1104bool
1105operator>=(const optional<_Tp>&, nullopt_t) noexcept
1106{
1107 return true;
1108}
1109
1110template <class _Tp>
1111_LIBCPP_INLINE_VISIBILITY constexpr
1112bool
1113operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
1114{
1115 return !static_cast<bool>(__x);
1116}
1117
1118// Comparisons with T
1119template <class _Tp>
1120_LIBCPP_INLINE_VISIBILITY constexpr
1121enable_if_t<
1122 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1123 _VSTD::declval<const _Tp&>()), bool>,
1124 bool
1125>
1126operator==(const optional<_Tp>& __x, const _Tp& __v)
1127{
1128 return static_cast<bool>(__x) ? *__x == __v : false;
1129}
1130
1131template <class _Tp>
1132_LIBCPP_INLINE_VISIBILITY constexpr
1133enable_if_t<
1134 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1135 _VSTD::declval<const _Tp&>()), bool>,
1136 bool
1137>
1138operator==(const _Tp& __v, const optional<_Tp>& __x)
1139{
1140 return static_cast<bool>(__x) ? __v == *__x : false;
1141}
1142
1143template <class _Tp>
1144_LIBCPP_INLINE_VISIBILITY constexpr
1145enable_if_t<
1146 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1147 _VSTD::declval<const _Tp&>()), bool>,
1148 bool
1149>
1150operator!=(const optional<_Tp>& __x, const _Tp& __v)
1151{
1152 return static_cast<bool>(__x) ? *__x != __v : true;
1153}
1154
1155template <class _Tp>
1156_LIBCPP_INLINE_VISIBILITY constexpr
1157enable_if_t<
1158 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1159 _VSTD::declval<const _Tp&>()), bool>,
1160 bool
1161>
1162operator!=(const _Tp& __v, const optional<_Tp>& __x)
1163{
1164 return static_cast<bool>(__x) ? __v != *__x : true;
1165}
1166
1167template <class _Tp>
1168_LIBCPP_INLINE_VISIBILITY constexpr
1169enable_if_t<
1170 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1171 _VSTD::declval<const _Tp&>()), bool>,
1172 bool
1173>
1174operator<(const optional<_Tp>& __x, const _Tp& __v)
1175{
1176 return static_cast<bool>(__x) ? *__x < __v : true;
1177}
1178
1179template <class _Tp>
1180_LIBCPP_INLINE_VISIBILITY constexpr
1181enable_if_t<
1182 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1183 _VSTD::declval<const _Tp&>()), bool>,
1184 bool
1185>
1186operator<(const _Tp& __v, const optional<_Tp>& __x)
1187{
1188 return static_cast<bool>(__x) ? __v < *__x : false;
1189}
1190
1191template <class _Tp>
1192_LIBCPP_INLINE_VISIBILITY constexpr
1193enable_if_t<
1194 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1195 _VSTD::declval<const _Tp&>()), bool>,
1196 bool
1197>
1198operator<=(const optional<_Tp>& __x, const _Tp& __v)
1199{
1200 return static_cast<bool>(__x) ? *__x <= __v : true;
1201}
1202
1203template <class _Tp>
1204_LIBCPP_INLINE_VISIBILITY constexpr
1205enable_if_t<
1206 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1207 _VSTD::declval<const _Tp&>()), bool>,
1208 bool
1209>
1210operator<=(const _Tp& __v, const optional<_Tp>& __x)
1211{
1212 return static_cast<bool>(__x) ? __v <= *__x : false;
1213}
1214
1215template <class _Tp>
1216_LIBCPP_INLINE_VISIBILITY constexpr
1217enable_if_t<
1218 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1219 _VSTD::declval<const _Tp&>()), bool>,
1220 bool
1221>
1222operator>(const optional<_Tp>& __x, const _Tp& __v)
1223{
1224 return static_cast<bool>(__x) ? *__x > __v : false;
1225}
1226
1227template <class _Tp>
1228_LIBCPP_INLINE_VISIBILITY constexpr
1229enable_if_t<
1230 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1231 _VSTD::declval<const _Tp&>()), bool>,
1232 bool
1233>
1234operator>(const _Tp& __v, const optional<_Tp>& __x)
1235{
1236 return static_cast<bool>(__x) ? __v > *__x : true;
1237}
1238
1239template <class _Tp>
1240_LIBCPP_INLINE_VISIBILITY constexpr
1241enable_if_t<
1242 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1243 _VSTD::declval<const _Tp&>()), bool>,
1244 bool
1245>
1246operator>=(const optional<_Tp>& __x, const _Tp& __v)
1247{
1248 return static_cast<bool>(__x) ? *__x >= __v : false;
1249}
1250
1251template <class _Tp>
1252_LIBCPP_INLINE_VISIBILITY constexpr
1253enable_if_t<
1254 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1255 _VSTD::declval<const _Tp&>()), bool>,
1256 bool
1257>
1258operator>=(const _Tp& __v, const optional<_Tp>& __x)
1259{
1260 return static_cast<bool>(__x) ? __v >= *__x : true;
1261}
1262
1263
1264template <class _Tp>
1265inline _LIBCPP_INLINE_VISIBILITY
1266enable_if_t<
1267 is_move_constructible_v<_Tp> && is_swappable_v<_Tp>,
1268 void
1269>
1270swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
1271{
1272 __x.swap(__y);
1273}
1274
1275template <class _Tp>
1276_LIBCPP_INLINE_VISIBILITY constexpr
1277optional<decay_t<_Tp>> make_optional(_Tp&& __v)
1278{
1279 return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v));
1280}
1281
1282template <class _Tp, class... _Args>
1283_LIBCPP_INLINE_VISIBILITY constexpr
1284optional<_Tp> make_optional(_Args&&... __args)
1285{
1286 return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...);
1287}
1288
1289template <class _Tp, class _Up, class... _Args>
1290_LIBCPP_INLINE_VISIBILITY constexpr
1291optional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args)
1292{
1293 return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...);
1294}
1295
1296template <class _Tp>
1297struct _LIBCPP_TYPE_VIS_ONLY hash<optional<_Tp> >
1298{
1299 typedef optional<_Tp> argument_type;
1300 typedef size_t result_type;
1301
1302 _LIBCPP_INLINE_VISIBILITY
1303 result_type operator()(const argument_type& __opt) const _NOEXCEPT
1304 {
1305 return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0;
1306 }
1307};
1308
1309_LIBCPP_END_NAMESPACE_STD
1310
1311#endif // _LIBCPP_STD_VER > 14
1312
1313#endif // _LIBCPP_OPTIONAL