blob: 735ef479e02f0b7012c65baf10b8fd07ebe22fb3 [file] [log] [blame]
Eric Fiselier35ce4852016-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
Eric Fiselier46c0fcb2016-10-16 03:21:35 +0000684 <__lazy_and<
685 integral_constant<bool,
686 !is_same_v<decay_t<_Up>, optional> &&
687 !(is_same_v<_Up, value_type> && is_scalar_v<value_type>)
688 >,
689 is_constructible<value_type, _Up>,
690 is_assignable<value_type&, _Up>
691 >::value>
Eric Fiselier35ce4852016-10-12 07:46:20 +0000692 >
693 _LIBCPP_INLINE_VISIBILITY
694 optional&
695 operator=(_Up&& __v)
696 {
697 if (this->has_value())
698 this->__get() = _VSTD::forward<_Up>(__v);
699 else
700 this->__construct(_VSTD::forward<_Up>(__v));
701 return *this;
702 }
703
704 // LWG2756
705 template <class _Up, enable_if_t<
706 _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>()
707 , int> = 0>
708 _LIBCPP_INLINE_VISIBILITY
709 optional&
710 operator=(const optional<_Up>& __v)
711 {
712 this->__assign_from(__v);
713 return *this;
714 }
715
716 // LWG2756
717 template <class _Up, enable_if_t<
718 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>()
719 , int> = 0>
720 _LIBCPP_INLINE_VISIBILITY
721 optional&
722 operator=(optional<_Up>&& __v)
723 {
724 this->__assign_from(_VSTD::move(__v));
725 return *this;
726 }
727
728 template <class... _Args,
729 class = enable_if_t
730 <
731 is_constructible_v<value_type, _Args...>
732 >
733 >
734 _LIBCPP_INLINE_VISIBILITY
735 void
736 emplace(_Args&&... __args)
737 {
738 reset();
739 this->__construct(_VSTD::forward<_Args>(__args)...);
740 }
741
742 template <class _Up, class... _Args,
743 class = enable_if_t
744 <
745 is_constructible_v<value_type, initializer_list<_Up>&, _Args...>
746 >
747 >
748 _LIBCPP_INLINE_VISIBILITY
749 void
750 emplace(initializer_list<_Up> __il, _Args&&... __args)
751 {
752 reset();
753 this->__construct(__il, _VSTD::forward<_Args>(__args)...);
754 }
755
756 _LIBCPP_INLINE_VISIBILITY
757 void swap(optional& __opt)
758 noexcept(is_nothrow_move_constructible_v<value_type> &&
759 is_nothrow_swappable_v<value_type>)
760 {
761 if (this->has_value() == __opt.has_value())
762 {
763 using _VSTD::swap;
764 if (this->has_value())
765 swap(this->__get(), __opt.__get());
766 }
767 else
768 {
769 if (this->has_value())
770 {
771 __opt.__construct(_VSTD::move(this->__get()));
772 reset();
773 }
774 else
775 {
776 this->__construct(_VSTD::move(__opt.__get()));
777 __opt.reset();
778 }
779 }
780 }
781
782 _LIBCPP_INLINE_VISIBILITY
783 constexpr
784 add_pointer_t<value_type const>
785 operator->() const
786 {
787 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
788#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
789 return _VSTD::addressof(this->__get());
790#else
791 return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
792#endif
793 }
794
795 _LIBCPP_INLINE_VISIBILITY
796 constexpr
797 add_pointer_t<value_type>
798 operator->()
799 {
800 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
801#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
802 return _VSTD::addressof(this->__get());
803#else
804 return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
805#endif
806 }
807
808 _LIBCPP_INLINE_VISIBILITY
809 constexpr
810 const value_type&
811 operator*() const&
812 {
813 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
814 return this->__get();
815 }
816
817 _LIBCPP_INLINE_VISIBILITY
818 constexpr
819 value_type&
820 operator*() &
821 {
822 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
823 return this->__get();
824 }
825
826 _LIBCPP_INLINE_VISIBILITY
827 constexpr
828 value_type&&
829 operator*() &&
830 {
831 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
832 return _VSTD::move(this->__get());
833 }
834
835 _LIBCPP_INLINE_VISIBILITY
836 constexpr
837 const value_type&&
838 operator*() const&&
839 {
840 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
841 return _VSTD::move(this->__get());
842 }
843
844 _LIBCPP_INLINE_VISIBILITY
845 constexpr explicit operator bool() const noexcept { return has_value(); }
846
847 using __base::has_value;
848 using __base::__get;
849
850 _LIBCPP_INLINE_VISIBILITY
851 constexpr value_type const& value() const&
852 {
853 if (!this->has_value())
854 __throw_bad_optional_access();
855 return this->__get();
856 }
857
858 _LIBCPP_INLINE_VISIBILITY
859 constexpr value_type& value() &
860 {
861 if (!this->has_value())
862 __throw_bad_optional_access();
863 return this->__get();
864 }
865
866 _LIBCPP_INLINE_VISIBILITY
867 constexpr value_type&& value() &&
868 {
869 if (!this->has_value())
870 __throw_bad_optional_access();
871 return _VSTD::move(this->__get());
872 }
873
874 _LIBCPP_INLINE_VISIBILITY
875 constexpr value_type const&& value() const&&
876 {
877 if (!this->has_value())
878 __throw_bad_optional_access();
879 return _VSTD::move(this->__get());
880 }
881
882 template <class _Up>
883 _LIBCPP_INLINE_VISIBILITY
884 constexpr value_type value_or(_Up&& __v) const&
885 {
886 static_assert(is_copy_constructible_v<value_type>,
887 "optional<T>::value_or: T must be copy constructible");
888 static_assert(is_convertible_v<_Up, value_type>,
889 "optional<T>::value_or: U must be convertible to T");
890 return this->has_value() ? this->__get() :
891 static_cast<value_type>(_VSTD::forward<_Up>(__v));
892 }
893
894 template <class _Up>
895 _LIBCPP_INLINE_VISIBILITY
896 value_type value_or(_Up&& __v) &&
897 {
898 static_assert(is_move_constructible_v<value_type>,
899 "optional<T>::value_or: T must be move constructible");
900 static_assert(is_convertible_v<_Up, value_type>,
901 "optional<T>::value_or: U must be convertible to T");
902 return this->has_value() ? _VSTD::move(this->__get()) :
903 static_cast<value_type>(_VSTD::forward<_Up>(__v));
904 }
905
906 using __base::reset;
907
908private:
909 template <class _Up>
910 _LIBCPP_INLINE_VISIBILITY
911 static _Up*
912 __operator_arrow(true_type, _Up& __x)
913 {
914 return _VSTD::addressof(__x);
915 }
916
917 template <class _Up>
918 _LIBCPP_INLINE_VISIBILITY
919 static constexpr _Up*
920 __operator_arrow(false_type, _Up& __x)
921 {
922 return &__x;
923 }
924};
925
926// Comparisons between optionals
927template <class _Tp>
928_LIBCPP_INLINE_VISIBILITY constexpr
929enable_if_t<
930 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
931 _VSTD::declval<const _Tp&>()), bool>,
932 bool
933>
934operator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
935{
936 if (static_cast<bool>(__x) != static_cast<bool>(__y))
937 return false;
938 if (!static_cast<bool>(__x))
939 return true;
940 return *__x == *__y;
941}
942
943template <class _Tp>
944_LIBCPP_INLINE_VISIBILITY constexpr
945enable_if_t<
946 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
947 _VSTD::declval<const _Tp&>()), bool>,
948 bool
949>
950operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y)
951{
952 if (static_cast<bool>(__x) != static_cast<bool>(__y))
953 return true;
954 if (!static_cast<bool>(__x))
955 return false;
956 return *__x != *__y;
957}
958
959template <class _Tp>
960_LIBCPP_INLINE_VISIBILITY constexpr
961enable_if_t<
962 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
963 _VSTD::declval<const _Tp&>()), bool>,
964 bool
965>
966operator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
967{
968 if (!static_cast<bool>(__y))
969 return false;
970 if (!static_cast<bool>(__x))
971 return true;
972 return *__x < *__y;
973}
974
975template <class _Tp>
976_LIBCPP_INLINE_VISIBILITY constexpr
977enable_if_t<
978 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
979 _VSTD::declval<const _Tp&>()), bool>,
980 bool
981>
982operator>(const optional<_Tp>& __x, const optional<_Tp>& __y)
983{
984 if (!static_cast<bool>(__x))
985 return false;
986 if (!static_cast<bool>(__y))
987 return true;
988 return *__x > *__y;
989}
990
991template <class _Tp>
992_LIBCPP_INLINE_VISIBILITY constexpr
993enable_if_t<
994 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
995 _VSTD::declval<const _Tp&>()), bool>,
996 bool
997>
998operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y)
999{
1000 if (!static_cast<bool>(__x))
1001 return true;
1002 if (!static_cast<bool>(__y))
1003 return false;
1004 return *__x <= *__y;
1005}
1006
1007template <class _Tp>
1008_LIBCPP_INLINE_VISIBILITY constexpr
1009enable_if_t<
1010 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1011 _VSTD::declval<const _Tp&>()), bool>,
1012 bool
1013>
1014operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y)
1015{
1016 if (!static_cast<bool>(__y))
1017 return true;
1018 if (!static_cast<bool>(__x))
1019 return false;
1020 return *__x >= *__y;
1021}
1022
1023// Comparisons with nullopt
1024template <class _Tp>
1025_LIBCPP_INLINE_VISIBILITY constexpr
1026bool
1027operator==(const optional<_Tp>& __x, nullopt_t) noexcept
1028{
1029 return !static_cast<bool>(__x);
1030}
1031
1032template <class _Tp>
1033_LIBCPP_INLINE_VISIBILITY constexpr
1034bool
1035operator==(nullopt_t, const optional<_Tp>& __x) noexcept
1036{
1037 return !static_cast<bool>(__x);
1038}
1039
1040template <class _Tp>
1041_LIBCPP_INLINE_VISIBILITY constexpr
1042bool
1043operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
1044{
1045 return static_cast<bool>(__x);
1046}
1047
1048template <class _Tp>
1049_LIBCPP_INLINE_VISIBILITY constexpr
1050bool
1051operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
1052{
1053 return static_cast<bool>(__x);
1054}
1055
1056template <class _Tp>
1057_LIBCPP_INLINE_VISIBILITY constexpr
1058bool
1059operator<(const optional<_Tp>&, nullopt_t) noexcept
1060{
1061 return false;
1062}
1063
1064template <class _Tp>
1065_LIBCPP_INLINE_VISIBILITY constexpr
1066bool
1067operator<(nullopt_t, const optional<_Tp>& __x) noexcept
1068{
1069 return static_cast<bool>(__x);
1070}
1071
1072template <class _Tp>
1073_LIBCPP_INLINE_VISIBILITY constexpr
1074bool
1075operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
1076{
1077 return !static_cast<bool>(__x);
1078}
1079
1080template <class _Tp>
1081_LIBCPP_INLINE_VISIBILITY constexpr
1082bool
Eric Fiselier0e5ebbc2016-12-23 23:37:52 +00001083operator<=(nullopt_t, const optional<_Tp>&) noexcept
Eric Fiselier35ce4852016-10-12 07:46:20 +00001084{
1085 return true;
1086}
1087
1088template <class _Tp>
1089_LIBCPP_INLINE_VISIBILITY constexpr
1090bool
1091operator>(const optional<_Tp>& __x, nullopt_t) noexcept
1092{
1093 return static_cast<bool>(__x);
1094}
1095
1096template <class _Tp>
1097_LIBCPP_INLINE_VISIBILITY constexpr
1098bool
Eric Fiselier0e5ebbc2016-12-23 23:37:52 +00001099operator>(nullopt_t, const optional<_Tp>&) noexcept
Eric Fiselier35ce4852016-10-12 07:46:20 +00001100{
1101 return false;
1102}
1103
1104template <class _Tp>
1105_LIBCPP_INLINE_VISIBILITY constexpr
1106bool
1107operator>=(const optional<_Tp>&, nullopt_t) noexcept
1108{
1109 return true;
1110}
1111
1112template <class _Tp>
1113_LIBCPP_INLINE_VISIBILITY constexpr
1114bool
1115operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
1116{
1117 return !static_cast<bool>(__x);
1118}
1119
1120// Comparisons with T
1121template <class _Tp>
1122_LIBCPP_INLINE_VISIBILITY constexpr
1123enable_if_t<
1124 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1125 _VSTD::declval<const _Tp&>()), bool>,
1126 bool
1127>
1128operator==(const optional<_Tp>& __x, const _Tp& __v)
1129{
1130 return static_cast<bool>(__x) ? *__x == __v : false;
1131}
1132
1133template <class _Tp>
1134_LIBCPP_INLINE_VISIBILITY constexpr
1135enable_if_t<
1136 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1137 _VSTD::declval<const _Tp&>()), bool>,
1138 bool
1139>
1140operator==(const _Tp& __v, const optional<_Tp>& __x)
1141{
1142 return static_cast<bool>(__x) ? __v == *__x : false;
1143}
1144
1145template <class _Tp>
1146_LIBCPP_INLINE_VISIBILITY constexpr
1147enable_if_t<
1148 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1149 _VSTD::declval<const _Tp&>()), bool>,
1150 bool
1151>
1152operator!=(const optional<_Tp>& __x, const _Tp& __v)
1153{
1154 return static_cast<bool>(__x) ? *__x != __v : true;
1155}
1156
1157template <class _Tp>
1158_LIBCPP_INLINE_VISIBILITY constexpr
1159enable_if_t<
1160 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1161 _VSTD::declval<const _Tp&>()), bool>,
1162 bool
1163>
1164operator!=(const _Tp& __v, const optional<_Tp>& __x)
1165{
1166 return static_cast<bool>(__x) ? __v != *__x : true;
1167}
1168
1169template <class _Tp>
1170_LIBCPP_INLINE_VISIBILITY constexpr
1171enable_if_t<
1172 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1173 _VSTD::declval<const _Tp&>()), bool>,
1174 bool
1175>
1176operator<(const optional<_Tp>& __x, const _Tp& __v)
1177{
1178 return static_cast<bool>(__x) ? *__x < __v : true;
1179}
1180
1181template <class _Tp>
1182_LIBCPP_INLINE_VISIBILITY constexpr
1183enable_if_t<
1184 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1185 _VSTD::declval<const _Tp&>()), bool>,
1186 bool
1187>
1188operator<(const _Tp& __v, const optional<_Tp>& __x)
1189{
1190 return static_cast<bool>(__x) ? __v < *__x : false;
1191}
1192
1193template <class _Tp>
1194_LIBCPP_INLINE_VISIBILITY constexpr
1195enable_if_t<
1196 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1197 _VSTD::declval<const _Tp&>()), bool>,
1198 bool
1199>
1200operator<=(const optional<_Tp>& __x, const _Tp& __v)
1201{
1202 return static_cast<bool>(__x) ? *__x <= __v : true;
1203}
1204
1205template <class _Tp>
1206_LIBCPP_INLINE_VISIBILITY constexpr
1207enable_if_t<
1208 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1209 _VSTD::declval<const _Tp&>()), bool>,
1210 bool
1211>
1212operator<=(const _Tp& __v, const optional<_Tp>& __x)
1213{
1214 return static_cast<bool>(__x) ? __v <= *__x : false;
1215}
1216
1217template <class _Tp>
1218_LIBCPP_INLINE_VISIBILITY constexpr
1219enable_if_t<
1220 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1221 _VSTD::declval<const _Tp&>()), bool>,
1222 bool
1223>
1224operator>(const optional<_Tp>& __x, const _Tp& __v)
1225{
1226 return static_cast<bool>(__x) ? *__x > __v : false;
1227}
1228
1229template <class _Tp>
1230_LIBCPP_INLINE_VISIBILITY constexpr
1231enable_if_t<
1232 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1233 _VSTD::declval<const _Tp&>()), bool>,
1234 bool
1235>
1236operator>(const _Tp& __v, const optional<_Tp>& __x)
1237{
1238 return static_cast<bool>(__x) ? __v > *__x : true;
1239}
1240
1241template <class _Tp>
1242_LIBCPP_INLINE_VISIBILITY constexpr
1243enable_if_t<
1244 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1245 _VSTD::declval<const _Tp&>()), bool>,
1246 bool
1247>
1248operator>=(const optional<_Tp>& __x, const _Tp& __v)
1249{
1250 return static_cast<bool>(__x) ? *__x >= __v : false;
1251}
1252
1253template <class _Tp>
1254_LIBCPP_INLINE_VISIBILITY constexpr
1255enable_if_t<
1256 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1257 _VSTD::declval<const _Tp&>()), bool>,
1258 bool
1259>
1260operator>=(const _Tp& __v, const optional<_Tp>& __x)
1261{
1262 return static_cast<bool>(__x) ? __v >= *__x : true;
1263}
1264
1265
1266template <class _Tp>
1267inline _LIBCPP_INLINE_VISIBILITY
1268enable_if_t<
1269 is_move_constructible_v<_Tp> && is_swappable_v<_Tp>,
1270 void
1271>
1272swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
1273{
1274 __x.swap(__y);
1275}
1276
1277template <class _Tp>
1278_LIBCPP_INLINE_VISIBILITY constexpr
1279optional<decay_t<_Tp>> make_optional(_Tp&& __v)
1280{
1281 return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v));
1282}
1283
1284template <class _Tp, class... _Args>
1285_LIBCPP_INLINE_VISIBILITY constexpr
1286optional<_Tp> make_optional(_Args&&... __args)
1287{
1288 return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...);
1289}
1290
1291template <class _Tp, class _Up, class... _Args>
1292_LIBCPP_INLINE_VISIBILITY constexpr
1293optional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args)
1294{
1295 return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...);
1296}
1297
1298template <class _Tp>
1299struct _LIBCPP_TYPE_VIS_ONLY hash<optional<_Tp> >
1300{
1301 typedef optional<_Tp> argument_type;
1302 typedef size_t result_type;
1303
1304 _LIBCPP_INLINE_VISIBILITY
1305 result_type operator()(const argument_type& __opt) const _NOEXCEPT
1306 {
1307 return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0;
1308 }
1309};
1310
1311_LIBCPP_END_NAMESPACE_STD
1312
1313#endif // _LIBCPP_STD_VER > 14
1314
1315#endif // _LIBCPP_OPTIONAL