blob: 8c7a242113a05e9215059becbf21edbd6d26bbb7 [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 {
Casey Carter84b8a402017-04-17 20:15:16 +000020 // 23.6.3, optional for object types
Eric Fiselierd4ec6352016-10-12 07:46:20 +000021 template <class T> class optional;
22
Casey Carter84b8a402017-04-17 20:15:16 +000023 // 23.6.4, no-value state indicator
Eric Fiselierd4ec6352016-10-12 07:46:20 +000024 struct nullopt_t{see below };
25 constexpr nullopt_t nullopt(unspecified );
26
Casey Carter84b8a402017-04-17 20:15:16 +000027 // 23.6.5, class bad_optional_access
Eric Fiselierd4ec6352016-10-12 07:46:20 +000028 class bad_optional_access;
29
Casey Carter84b8a402017-04-17 20:15:16 +000030 // 23.6.6, relational operators
31 template <class T, class U>
32 constexpr bool operator==(const optional<T>&, const optional<U>&);
33 template <class T, class U>
34 constexpr bool operator!=(const optional<T>&, const optional<U>&);
35 template <class T, class U>
36 constexpr bool operator<(const optional<T>&, const optional<U>&);
37 template <class T, class U>
38 constexpr bool operator>(const optional<T>&, const optional<U>&);
39 template <class T, class U>
40 constexpr bool operator<=(const optional<T>&, const optional<U>&);
41 template <class T, class U>
42 constexpr bool operator>=(const optional<T>&, const optional<U>&);
43
44 // 23.6.7 comparison with nullopt
Eric Fiselierd4ec6352016-10-12 07:46:20 +000045 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 template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept;
56 template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept;
57
Casey Carter84b8a402017-04-17 20:15:16 +000058 // 23.6.8, comparison with T
59 template <class T, class U> constexpr bool operator==(const optional<T>&, const U&);
60 template <class T, class U> constexpr bool operator==(const U&, const optional<T>&);
61 template <class T, class U> constexpr bool operator!=(const optional<T>&, const U&);
62 template <class T, class U> constexpr bool operator!=(const U&, const optional<T>&);
63 template <class T, class U> constexpr bool operator<(const optional<T>&, const U&);
64 template <class T, class U> constexpr bool operator<(const U&, const optional<T>&);
65 template <class T, class U> constexpr bool operator<=(const optional<T>&, const U&);
66 template <class T, class U> constexpr bool operator<=(const U&, const optional<T>&);
67 template <class T, class U> constexpr bool operator>(const optional<T>&, const U&);
68 template <class T, class U> constexpr bool operator>(const U&, const optional<T>&);
69 template <class T, class U> constexpr bool operator>=(const optional<T>&, const U&);
70 template <class T, class U> constexpr bool operator>=(const U&, const optional<T>&);
Eric Fiselierd4ec6352016-10-12 07:46:20 +000071
Casey Carter84b8a402017-04-17 20:15:16 +000072 // 23.6.9, specialized algorithms
Eric Fiselierd4ec6352016-10-12 07:46:20 +000073 template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below );
74 template <class T> constexpr optional<see below > make_optional(T&&);
75 template <class T, class... Args>
76 constexpr optional<T> make_optional(Args&&... args);
77 template <class T, class U, class... Args>
78 constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args);
79
Casey Carter84b8a402017-04-17 20:15:16 +000080 // 23.6.10, hash support
Eric Fiselierd4ec6352016-10-12 07:46:20 +000081 template <class T> struct hash;
82 template <class T> struct hash<optional<T>>;
83
84 template <class T> class optional {
85 public:
86 using value_type = T;
87
Casey Carter84b8a402017-04-17 20:15:16 +000088 // 23.6.3.1, constructors
Eric Fiselierd4ec6352016-10-12 07:46:20 +000089 constexpr optional() noexcept;
90 constexpr optional(nullopt_t) noexcept;
91 optional(const optional &);
Marshall Clow45ff9822017-04-12 22:51:27 +000092 optional(optional &&) noexcept(see below);
Eric Fiselierd4ec6352016-10-12 07:46:20 +000093 template <class... Args> constexpr explicit optional(in_place_t, Args &&...);
94 template <class U, class... Args>
95 constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...);
96 template <class U = T>
97 constexpr EXPLICIT optional(U &&);
98 template <class U>
99 constexpr EXPLICIT optional(const optional<U> &);
100 template <class U>
101 constexpr EXPLICIT optional(optional<U> &&);
102
Casey Carter84b8a402017-04-17 20:15:16 +0000103 // 23.6.3.2, destructor
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000104 ~optional();
105
Casey Carter84b8a402017-04-17 20:15:16 +0000106 // 23.6.3.3, assignment
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000107 optional &operator=(nullopt_t) noexcept;
108 optional &operator=(const optional &);
109 optional &operator=(optional &&) noexcept(see below );
110 template <class U = T> optional &operator=(U &&);
111 template <class U> optional &operator=(const optional<U> &);
112 template <class U> optional &operator=(optional<U> &&);
Marshall Clow45ff9822017-04-12 22:51:27 +0000113 template <class... Args> T& emplace(Args &&...);
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000114 template <class U, class... Args>
Marshall Clow45ff9822017-04-12 22:51:27 +0000115 T& emplace(initializer_list<U>, Args &&...);
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000116
Casey Carter84b8a402017-04-17 20:15:16 +0000117 // 23.6.3.4, swap
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000118 void swap(optional &) noexcept(see below );
119
Casey Carter84b8a402017-04-17 20:15:16 +0000120 // 23.6.3.5, observers
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000121 constexpr T const *operator->() const;
122 constexpr T *operator->();
123 constexpr T const &operator*() const &;
124 constexpr T &operator*() &;
125 constexpr T &&operator*() &&;
126 constexpr const T &&operator*() const &&;
127 constexpr explicit operator bool() const noexcept;
128 constexpr bool has_value() const noexcept;
129 constexpr T const &value() const &;
130 constexpr T &value() &;
131 constexpr T &&value() &&;
132 constexpr const T &&value() const &&;
133 template <class U> constexpr T value_or(U &&) const &;
134 template <class U> constexpr T value_or(U &&) &&;
135
Casey Carter84b8a402017-04-17 20:15:16 +0000136 // 23.6.3.6, modifiers
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000137 void reset() noexcept;
138
139 private:
140 T *val; // exposition only
141 };
142} // namespace std
143
144*/
145
146#include <__config>
147#include <__debug>
148#include <__functional_base>
149#include <__undef_min_max>
150#include <functional>
151#include <initializer_list>
152#include <new>
153#include <stdexcept>
154#include <type_traits>
155#include <utility>
156
157#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
158#pragma GCC system_header
159#endif
160
161namespace std // purposefully not using versioning namespace
162{
163
164class _LIBCPP_EXCEPTION_ABI bad_optional_access
Marshall Clowa627d4a2017-02-05 20:06:38 +0000165 : public exception
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000166{
167public:
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000168 // Get the key function ~bad_optional_access() into the dylib
Marshall Clow53fc0372017-02-05 20:52:32 +0000169 virtual ~bad_optional_access() _NOEXCEPT;
Marshall Clowa627d4a2017-02-05 20:06:38 +0000170 virtual const char* what() const _NOEXCEPT;
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000171};
172
173} // std
174
175#if _LIBCPP_STD_VER > 14
176
177_LIBCPP_BEGIN_NAMESPACE_STD
178
179_LIBCPP_NORETURN
180inline _LIBCPP_INLINE_VISIBILITY
181void __throw_bad_optional_access() {
182#ifndef _LIBCPP_NO_EXCEPTIONS
183 throw bad_optional_access();
184#else
185 _VSTD::abort();
186#endif
187}
188
189struct nullopt_t
190{
191 struct __secret_tag { _LIBCPP_INLINE_VISIBILITY explicit __secret_tag() = default; };
192 _LIBCPP_INLINE_VISIBILITY constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {}
193};
194
195/* inline */ constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}};
196
197template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
198struct __optional_destruct_base;
199
200template <class _Tp>
201struct __optional_destruct_base<_Tp, false>
202{
203 typedef _Tp value_type;
204 static_assert(is_object_v<value_type>,
205 "instantiation of optional with a non-object type is undefined behavior");
206 union
207 {
208 char __null_state_;
209 value_type __val_;
210 };
211 bool __engaged_;
212
213 _LIBCPP_INLINE_VISIBILITY
214 ~__optional_destruct_base()
215 {
216 if (__engaged_)
217 __val_.~value_type();
218 }
219
220 _LIBCPP_INLINE_VISIBILITY
221 constexpr __optional_destruct_base() noexcept
222 : __null_state_(),
223 __engaged_(false) {}
224
225 template <class... _Args>
226 _LIBCPP_INLINE_VISIBILITY
227 constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
228 : __val_(_VSTD::forward<_Args>(__args)...),
229 __engaged_(true) {}
230
231 _LIBCPP_INLINE_VISIBILITY
232 void reset() noexcept
233 {
234 if (__engaged_)
235 {
236 __val_.~value_type();
237 __engaged_ = false;
238 }
239 }
240};
241
242template <class _Tp>
243struct __optional_destruct_base<_Tp, true>
244{
245 typedef _Tp value_type;
246 static_assert(is_object_v<value_type>,
247 "instantiation of optional with a non-object type is undefined behavior");
248 union
249 {
250 char __null_state_;
251 value_type __val_;
252 };
253 bool __engaged_;
254
255 _LIBCPP_INLINE_VISIBILITY
256 constexpr __optional_destruct_base() noexcept
257 : __null_state_(),
258 __engaged_(false) {}
259
260 template <class... _Args>
261 _LIBCPP_INLINE_VISIBILITY
262 constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
263 : __val_(_VSTD::forward<_Args>(__args)...),
264 __engaged_(true) {}
265
266 _LIBCPP_INLINE_VISIBILITY
267 void reset() noexcept
268 {
269 if (__engaged_)
270 {
271 __engaged_ = false;
272 }
273 }
274};
275
276template <class _Tp, bool = is_reference<_Tp>::value>
277struct __optional_storage_base : __optional_destruct_base<_Tp>
278{
279 using __base = __optional_destruct_base<_Tp>;
280 using value_type = _Tp;
281 using __base::__base;
282
283 _LIBCPP_INLINE_VISIBILITY
284 constexpr bool has_value() const noexcept
285 {
286 return this->__engaged_;
287 }
288
289 _LIBCPP_INLINE_VISIBILITY
290 constexpr value_type& __get() & noexcept
291 {
292 return this->__val_;
293 }
294 _LIBCPP_INLINE_VISIBILITY
295 constexpr const value_type& __get() const& noexcept
296 {
297 return this->__val_;
298 }
299 _LIBCPP_INLINE_VISIBILITY
300 constexpr value_type&& __get() && noexcept
301 {
302 return _VSTD::move(this->__val_);
303 }
304 _LIBCPP_INLINE_VISIBILITY
305 constexpr const value_type&& __get() const&& noexcept
306 {
307 return _VSTD::move(this->__val_);
308 }
309
310 template <class... _Args>
311 _LIBCPP_INLINE_VISIBILITY
312 void __construct(_Args&&... __args)
313 {
314 _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
315 ::new((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
316 this->__engaged_ = true;
317 }
318
319 template <class _That>
320 _LIBCPP_INLINE_VISIBILITY
321 void __construct_from(_That&& __opt)
322 {
323 if (__opt.has_value())
324 __construct(_VSTD::forward<_That>(__opt).__get());
325 }
326
327 template <class _That>
328 _LIBCPP_INLINE_VISIBILITY
329 void __assign_from(_That&& __opt)
330 {
331 if (this->__engaged_ == __opt.has_value())
332 {
333 if (this->__engaged_)
334 this->__val_ = _VSTD::forward<_That>(__opt).__get();
335 }
336 else
337 {
338 if (this->__engaged_)
339 this->reset();
340 else
341 __construct(_VSTD::forward<_That>(__opt).__get());
342 }
343 }
344};
345
346// optional<T&> is currently required ill-formed, however it may to be in the
347// future. For this reason it has already been implemented to ensure we can
348// make the change in an ABI compatible manner.
349template <class _Tp>
350struct __optional_storage_base<_Tp, true>
351{
352 using value_type = _Tp;
353 using __raw_type = remove_reference_t<_Tp>;
354 __raw_type* __value_;
355
356 template <class _Up>
357 static constexpr bool __can_bind_reference() {
358 using _RawUp = typename remove_reference<_Up>::type;
359 using _UpPtr = _RawUp*;
360 using _RawTp = typename remove_reference<_Tp>::type;
361 using _TpPtr = _RawTp*;
362 using _CheckLValueArg = integral_constant<bool,
363 (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value)
364 || is_same<_RawUp, reference_wrapper<_RawTp>>::value
365 || is_same<_RawUp, reference_wrapper<typename remove_const<_RawTp>::type>>::value
366 >;
367 return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value)
368 || (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value &&
369 is_convertible<_UpPtr, _TpPtr>::value);
370 }
371
372 _LIBCPP_INLINE_VISIBILITY
373 constexpr __optional_storage_base() noexcept
374 : __value_(nullptr) {}
375
376 template <class _UArg>
377 _LIBCPP_INLINE_VISIBILITY
378 constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg)
379 : __value_(_VSTD::addressof(__uarg))
380 {
381 static_assert(__can_bind_reference<_UArg>(),
382 "Attempted to construct a reference element in tuple from a "
383 "possible temporary");
384 }
385
386 _LIBCPP_INLINE_VISIBILITY
387 void reset() noexcept { __value_ = nullptr; }
388
389 _LIBCPP_INLINE_VISIBILITY
390 constexpr bool has_value() const noexcept
391 { return __value_ != nullptr; }
392
393 _LIBCPP_INLINE_VISIBILITY
394 constexpr value_type& __get() const& noexcept
395 { return *__value_; }
396
397 _LIBCPP_INLINE_VISIBILITY
398 constexpr value_type&& __get() const&& noexcept
399 { return _VSTD::forward<value_type>(*__value_); }
400
401 template <class _UArg>
402 _LIBCPP_INLINE_VISIBILITY
403 void __construct(_UArg&& __val)
404 {
405 _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
406 static_assert(__can_bind_reference<_UArg>(),
407 "Attempted to construct a reference element in tuple from a "
408 "possible temporary");
409 __value_ = _VSTD::addressof(__val);
410 }
411
412 template <class _That>
413 _LIBCPP_INLINE_VISIBILITY
414 void __construct_from(_That&& __opt)
415 {
416 if (__opt.has_value())
417 __construct(_VSTD::forward<_That>(__opt).__get());
418 }
419
420 template <class _That>
421 _LIBCPP_INLINE_VISIBILITY
422 void __assign_from(_That&& __opt)
423 {
424 if (has_value() == __opt.has_value())
425 {
426 if (has_value())
427 *__value_ = _VSTD::forward<_That>(__opt).__get();
428 }
429 else
430 {
431 if (has_value())
432 reset();
433 else
434 __construct(_VSTD::forward<_That>(__opt).__get());
435 }
436 }
437};
438
439template <class _Tp, bool = is_trivially_copyable<_Tp>::value>
440struct __optional_storage;
441
442template <class _Tp>
443struct __optional_storage<_Tp, true> : __optional_storage_base<_Tp>
444{
445 using __optional_storage_base<_Tp>::__optional_storage_base;
446};
447
448template <class _Tp>
449struct __optional_storage<_Tp, false> : __optional_storage_base<_Tp>
450{
451 using value_type = _Tp;
452 using __optional_storage_base<_Tp>::__optional_storage_base;
453
454 _LIBCPP_INLINE_VISIBILITY
455 __optional_storage() = default;
456
457 _LIBCPP_INLINE_VISIBILITY
458 __optional_storage(const __optional_storage& __opt)
459 {
460 this->__construct_from(__opt);
461 }
462
463 _LIBCPP_INLINE_VISIBILITY
464 __optional_storage(__optional_storage&& __opt)
465 noexcept(is_nothrow_move_constructible_v<value_type>)
466 {
467 this->__construct_from(_VSTD::move(__opt));
468 }
469
470 _LIBCPP_INLINE_VISIBILITY
471 __optional_storage& operator=(const __optional_storage& __opt)
472 {
473 this->__assign_from(__opt);
474 return *this;
475 }
476
477 _LIBCPP_INLINE_VISIBILITY
478 __optional_storage& operator=(__optional_storage&& __opt)
479 noexcept(is_nothrow_move_assignable_v<value_type> &&
480 is_nothrow_move_constructible_v<value_type>)
481 {
482 this->__assign_from(_VSTD::move(__opt));
483 return *this;
484 }
485};
486
487template <class _Tp>
488using __optional_sfinae_ctor_base_t = __sfinae_ctor_base<
489 is_copy_constructible<_Tp>::value,
490 is_move_constructible<_Tp>::value
491>;
492
493template <class _Tp>
494using __optional_sfinae_assign_base_t = __sfinae_assign_base<
495 (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value),
496 (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value)
497>;
498
499template <class _Tp>
500class optional
501 : private __optional_storage<_Tp>
502 , private __optional_sfinae_ctor_base_t<_Tp>
503 , private __optional_sfinae_assign_base_t<_Tp>
504{
505 using __base = __optional_storage<_Tp>;
506public:
507 using value_type = _Tp;
508
509private:
510 // Disable the reference extension using this static assert.
511 static_assert(!is_same_v<value_type, in_place_t>,
512 "instantiation of optional with in_place_t is ill-formed");
513 static_assert(!is_same_v<__uncvref_t<value_type>, nullopt_t>,
514 "instantiation of optional with nullopt_t is ill-formed");
515 static_assert(!is_reference_v<value_type>,
516 "instantiation of optional with a reference type is ill-formed");
517 static_assert(is_destructible_v<value_type>,
518 "instantiation of optional with a non-destructible type is ill-formed");
519
520 // LWG2756: conditionally explicit conversion from _Up
521 struct _CheckOptionalArgsConstructor {
522 template <class _Up>
523 static constexpr bool __enable_implicit() {
524 return is_constructible_v<_Tp, _Up&&> &&
525 is_convertible_v<_Up&&, _Tp>;
526 }
527
528 template <class _Up>
529 static constexpr bool __enable_explicit() {
530 return is_constructible_v<_Tp, _Up&&> &&
531 !is_convertible_v<_Up&&, _Tp>;
532 }
533 };
534 template <class _Up>
535 using _CheckOptionalArgsCtor = conditional_t<
Eric Fiselierf7b1d302017-03-30 19:43:50 +0000536 !is_same_v<decay_t<_Up>, in_place_t> &&
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000537 !is_same_v<decay_t<_Up>, optional>,
538 _CheckOptionalArgsConstructor,
539 __check_tuple_constructor_fail
540 >;
541 template <class _QualUp>
542 struct _CheckOptionalLikeConstructor {
543 template <class _Up, class _Opt = optional<_Up>>
544 using __check_constructible_from_opt = __lazy_or<
545 is_constructible<_Tp, _Opt&>,
546 is_constructible<_Tp, _Opt const&>,
547 is_constructible<_Tp, _Opt&&>,
548 is_constructible<_Tp, _Opt const&&>,
549 is_convertible<_Opt&, _Tp>,
550 is_convertible<_Opt const&, _Tp>,
551 is_convertible<_Opt&&, _Tp>,
552 is_convertible<_Opt const&&, _Tp>
553 >;
554 template <class _Up, class _Opt = optional<_Up>>
555 using __check_assignable_from_opt = __lazy_or<
556 is_assignable<_Tp&, _Opt&>,
557 is_assignable<_Tp&, _Opt const&>,
558 is_assignable<_Tp&, _Opt&&>,
559 is_assignable<_Tp&, _Opt const&&>
560 >;
561 template <class _Up, class _QUp = _QualUp>
562 static constexpr bool __enable_implicit() {
563 return is_convertible<_QUp, _Tp>::value &&
564 !__check_constructible_from_opt<_Up>::value;
565 }
566 template <class _Up, class _QUp = _QualUp>
567 static constexpr bool __enable_explicit() {
568 return !is_convertible<_QUp, _Tp>::value &&
569 !__check_constructible_from_opt<_Up>::value;
570 }
571 template <class _Up, class _QUp = _QualUp>
572 static constexpr bool __enable_assign() {
573 // Construction and assignability of _Qup to _Tp has already been
574 // checked.
575 return !__check_constructible_from_opt<_Up>::value &&
576 !__check_assignable_from_opt<_Up>::value;
577 }
578 };
579
580 template <class _Up, class _QualUp>
581 using _CheckOptionalLikeCtor = conditional_t<
582 __lazy_and<
583 __lazy_not<is_same<_Up, _Tp>>,
584 is_constructible<_Tp, _QualUp>
585 >::value,
586 _CheckOptionalLikeConstructor<_QualUp>,
587 __check_tuple_constructor_fail
588 >;
589 template <class _Up, class _QualUp>
590 using _CheckOptionalLikeAssign = conditional_t<
591 __lazy_and<
592 __lazy_not<is_same<_Up, _Tp>>,
593 is_constructible<_Tp, _QualUp>,
594 is_assignable<_Tp&, _QualUp>
595 >::value,
596 _CheckOptionalLikeConstructor<_QualUp>,
597 __check_tuple_constructor_fail
598 >;
599public:
600
601 _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
602 _LIBCPP_INLINE_VISIBILITY optional(const optional&) = default;
603 _LIBCPP_INLINE_VISIBILITY optional(optional&&) = default;
604 _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
605
606 template <class... _Args, class = enable_if_t<
607 is_constructible_v<value_type, _Args...>>
608 >
609 _LIBCPP_INLINE_VISIBILITY
610 constexpr explicit optional(in_place_t, _Args&&... __args)
611 : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
612
613 template <class _Up, class... _Args, class = enable_if_t<
614 is_constructible_v<value_type, initializer_list<_Up>&, _Args...>>
615 >
616 _LIBCPP_INLINE_VISIBILITY
617 constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
618 : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
619
620 template <class _Up = value_type, enable_if_t<
621 _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>()
622 , int> = 0>
623 _LIBCPP_INLINE_VISIBILITY
624 constexpr optional(_Up&& __v)
625 : __base(in_place, _VSTD::forward<_Up>(__v)) {}
626
627 template <class _Up, enable_if_t<
628 _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>()
629 , int> = 0>
630 _LIBCPP_INLINE_VISIBILITY
631 constexpr explicit optional(_Up&& __v)
632 : __base(in_place, _VSTD::forward<_Up>(__v)) {}
633
634 // LWG2756: conditionally explicit conversion from const optional<_Up>&
635 template <class _Up, enable_if_t<
636 _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>()
637 , int> = 0>
638 _LIBCPP_INLINE_VISIBILITY
639 optional(const optional<_Up>& __v)
640 {
641 this->__construct_from(__v);
642 }
643 template <class _Up, enable_if_t<
644 _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>()
645 , int> = 0>
646 _LIBCPP_INLINE_VISIBILITY
647 explicit optional(const optional<_Up>& __v)
648 {
649 this->__construct_from(__v);
650 }
651
652 // LWG2756: conditionally explicit conversion from optional<_Up>&&
653 template <class _Up, enable_if_t<
654 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>()
655 , int> = 0>
656 _LIBCPP_INLINE_VISIBILITY
657 optional(optional<_Up>&& __v)
658 {
659 this->__construct_from(_VSTD::move(__v));
660 }
661 template <class _Up, enable_if_t<
662 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>()
663 , int> = 0>
664 _LIBCPP_INLINE_VISIBILITY
665 explicit optional(optional<_Up>&& __v)
666 {
667 this->__construct_from(_VSTD::move(__v));
668 }
669
670 _LIBCPP_INLINE_VISIBILITY
671 optional& operator=(nullopt_t) noexcept
672 {
673 reset();
674 return *this;
675 }
676
677 _LIBCPP_INLINE_VISIBILITY optional& operator=(const optional&) = default;
678 _LIBCPP_INLINE_VISIBILITY optional& operator=(optional&&) = default;
679
680 // LWG2756
681 template <class _Up = value_type,
682 class = enable_if_t
Eric Fiselierb9014262016-10-16 03:21:35 +0000683 <__lazy_and<
684 integral_constant<bool,
685 !is_same_v<decay_t<_Up>, optional> &&
686 !(is_same_v<_Up, value_type> && is_scalar_v<value_type>)
687 >,
688 is_constructible<value_type, _Up>,
689 is_assignable<value_type&, _Up>
690 >::value>
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000691 >
692 _LIBCPP_INLINE_VISIBILITY
693 optional&
694 operator=(_Up&& __v)
695 {
696 if (this->has_value())
697 this->__get() = _VSTD::forward<_Up>(__v);
698 else
699 this->__construct(_VSTD::forward<_Up>(__v));
700 return *this;
701 }
702
703 // LWG2756
704 template <class _Up, enable_if_t<
705 _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>()
706 , int> = 0>
707 _LIBCPP_INLINE_VISIBILITY
708 optional&
709 operator=(const optional<_Up>& __v)
710 {
711 this->__assign_from(__v);
712 return *this;
713 }
714
715 // LWG2756
716 template <class _Up, enable_if_t<
717 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>()
718 , int> = 0>
719 _LIBCPP_INLINE_VISIBILITY
720 optional&
721 operator=(optional<_Up>&& __v)
722 {
723 this->__assign_from(_VSTD::move(__v));
724 return *this;
725 }
726
727 template <class... _Args,
728 class = enable_if_t
729 <
730 is_constructible_v<value_type, _Args...>
731 >
732 >
733 _LIBCPP_INLINE_VISIBILITY
Marshall Clow45ff9822017-04-12 22:51:27 +0000734 _Tp &
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000735 emplace(_Args&&... __args)
736 {
737 reset();
738 this->__construct(_VSTD::forward<_Args>(__args)...);
Marshall Clow45ff9822017-04-12 22:51:27 +0000739 return this->__get();
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000740 }
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
Marshall Clow45ff9822017-04-12 22:51:27 +0000749 _Tp &
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000750 emplace(initializer_list<_Up> __il, _Args&&... __args)
751 {
752 reset();
753 this->__construct(__il, _VSTD::forward<_Args>(__args)...);
Marshall Clow45ff9822017-04-12 22:51:27 +0000754 return this->__get();
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000755 }
756
757 _LIBCPP_INLINE_VISIBILITY
758 void swap(optional& __opt)
759 noexcept(is_nothrow_move_constructible_v<value_type> &&
760 is_nothrow_swappable_v<value_type>)
761 {
762 if (this->has_value() == __opt.has_value())
763 {
764 using _VSTD::swap;
765 if (this->has_value())
766 swap(this->__get(), __opt.__get());
767 }
768 else
769 {
770 if (this->has_value())
771 {
772 __opt.__construct(_VSTD::move(this->__get()));
773 reset();
774 }
775 else
776 {
777 this->__construct(_VSTD::move(__opt.__get()));
778 __opt.reset();
779 }
780 }
781 }
782
783 _LIBCPP_INLINE_VISIBILITY
784 constexpr
785 add_pointer_t<value_type const>
786 operator->() const
787 {
788 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
789#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
790 return _VSTD::addressof(this->__get());
791#else
792 return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
793#endif
794 }
795
796 _LIBCPP_INLINE_VISIBILITY
797 constexpr
798 add_pointer_t<value_type>
799 operator->()
800 {
801 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
802#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
803 return _VSTD::addressof(this->__get());
804#else
805 return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
806#endif
807 }
808
809 _LIBCPP_INLINE_VISIBILITY
810 constexpr
811 const value_type&
812 operator*() const&
813 {
814 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
815 return this->__get();
816 }
817
818 _LIBCPP_INLINE_VISIBILITY
819 constexpr
820 value_type&
821 operator*() &
822 {
823 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
824 return this->__get();
825 }
826
827 _LIBCPP_INLINE_VISIBILITY
828 constexpr
829 value_type&&
830 operator*() &&
831 {
832 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
833 return _VSTD::move(this->__get());
834 }
835
836 _LIBCPP_INLINE_VISIBILITY
837 constexpr
838 const value_type&&
839 operator*() const&&
840 {
841 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
842 return _VSTD::move(this->__get());
843 }
844
845 _LIBCPP_INLINE_VISIBILITY
846 constexpr explicit operator bool() const noexcept { return has_value(); }
847
848 using __base::has_value;
849 using __base::__get;
850
851 _LIBCPP_INLINE_VISIBILITY
852 constexpr value_type const& value() const&
853 {
854 if (!this->has_value())
855 __throw_bad_optional_access();
856 return this->__get();
857 }
858
859 _LIBCPP_INLINE_VISIBILITY
860 constexpr value_type& value() &
861 {
862 if (!this->has_value())
863 __throw_bad_optional_access();
864 return this->__get();
865 }
866
867 _LIBCPP_INLINE_VISIBILITY
868 constexpr value_type&& value() &&
869 {
870 if (!this->has_value())
871 __throw_bad_optional_access();
872 return _VSTD::move(this->__get());
873 }
874
875 _LIBCPP_INLINE_VISIBILITY
876 constexpr value_type const&& value() const&&
877 {
878 if (!this->has_value())
879 __throw_bad_optional_access();
880 return _VSTD::move(this->__get());
881 }
882
883 template <class _Up>
884 _LIBCPP_INLINE_VISIBILITY
885 constexpr value_type value_or(_Up&& __v) const&
886 {
887 static_assert(is_copy_constructible_v<value_type>,
888 "optional<T>::value_or: T must be copy constructible");
889 static_assert(is_convertible_v<_Up, value_type>,
890 "optional<T>::value_or: U must be convertible to T");
891 return this->has_value() ? this->__get() :
892 static_cast<value_type>(_VSTD::forward<_Up>(__v));
893 }
894
895 template <class _Up>
896 _LIBCPP_INLINE_VISIBILITY
897 value_type value_or(_Up&& __v) &&
898 {
899 static_assert(is_move_constructible_v<value_type>,
900 "optional<T>::value_or: T must be move constructible");
901 static_assert(is_convertible_v<_Up, value_type>,
902 "optional<T>::value_or: U must be convertible to T");
903 return this->has_value() ? _VSTD::move(this->__get()) :
904 static_cast<value_type>(_VSTD::forward<_Up>(__v));
905 }
906
907 using __base::reset;
908
909private:
910 template <class _Up>
911 _LIBCPP_INLINE_VISIBILITY
912 static _Up*
913 __operator_arrow(true_type, _Up& __x)
914 {
915 return _VSTD::addressof(__x);
916 }
917
918 template <class _Up>
919 _LIBCPP_INLINE_VISIBILITY
920 static constexpr _Up*
921 __operator_arrow(false_type, _Up& __x)
922 {
923 return &__x;
924 }
925};
926
927// Comparisons between optionals
Eric Fiselier8af90142017-03-30 20:06:52 +0000928template <class _Tp, class _Up>
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000929_LIBCPP_INLINE_VISIBILITY constexpr
930enable_if_t<
931 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
Eric Fiselier8af90142017-03-30 20:06:52 +0000932 _VSTD::declval<const _Up&>()), bool>,
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000933 bool
934>
Eric Fiselier8af90142017-03-30 20:06:52 +0000935operator==(const optional<_Tp>& __x, const optional<_Up>& __y)
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000936{
937 if (static_cast<bool>(__x) != static_cast<bool>(__y))
938 return false;
939 if (!static_cast<bool>(__x))
940 return true;
941 return *__x == *__y;
942}
943
Eric Fiselier8af90142017-03-30 20:06:52 +0000944template <class _Tp, class _Up>
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000945_LIBCPP_INLINE_VISIBILITY constexpr
946enable_if_t<
947 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
Eric Fiselier8af90142017-03-30 20:06:52 +0000948 _VSTD::declval<const _Up&>()), bool>,
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000949 bool
950>
Eric Fiselier8af90142017-03-30 20:06:52 +0000951operator!=(const optional<_Tp>& __x, const optional<_Up>& __y)
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000952{
953 if (static_cast<bool>(__x) != static_cast<bool>(__y))
954 return true;
955 if (!static_cast<bool>(__x))
956 return false;
957 return *__x != *__y;
958}
959
Eric Fiselier8af90142017-03-30 20:06:52 +0000960template <class _Tp, class _Up>
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000961_LIBCPP_INLINE_VISIBILITY constexpr
962enable_if_t<
963 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
Eric Fiselier8af90142017-03-30 20:06:52 +0000964 _VSTD::declval<const _Up&>()), bool>,
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000965 bool
966>
Eric Fiselier8af90142017-03-30 20:06:52 +0000967operator<(const optional<_Tp>& __x, const optional<_Up>& __y)
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000968{
969 if (!static_cast<bool>(__y))
970 return false;
971 if (!static_cast<bool>(__x))
972 return true;
973 return *__x < *__y;
974}
975
Eric Fiselier8af90142017-03-30 20:06:52 +0000976template <class _Tp, class _Up>
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000977_LIBCPP_INLINE_VISIBILITY constexpr
978enable_if_t<
979 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
Eric Fiselier8af90142017-03-30 20:06:52 +0000980 _VSTD::declval<const _Up&>()), bool>,
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000981 bool
982>
Eric Fiselier8af90142017-03-30 20:06:52 +0000983operator>(const optional<_Tp>& __x, const optional<_Up>& __y)
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000984{
985 if (!static_cast<bool>(__x))
986 return false;
987 if (!static_cast<bool>(__y))
988 return true;
989 return *__x > *__y;
990}
991
Eric Fiselier8af90142017-03-30 20:06:52 +0000992template <class _Tp, class _Up>
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000993_LIBCPP_INLINE_VISIBILITY constexpr
994enable_if_t<
995 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
Eric Fiselier8af90142017-03-30 20:06:52 +0000996 _VSTD::declval<const _Up&>()), bool>,
Eric Fiselierd4ec6352016-10-12 07:46:20 +0000997 bool
998>
Eric Fiselier8af90142017-03-30 20:06:52 +0000999operator<=(const optional<_Tp>& __x, const optional<_Up>& __y)
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001000{
1001 if (!static_cast<bool>(__x))
1002 return true;
1003 if (!static_cast<bool>(__y))
1004 return false;
1005 return *__x <= *__y;
1006}
1007
Eric Fiselier8af90142017-03-30 20:06:52 +00001008template <class _Tp, class _Up>
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001009_LIBCPP_INLINE_VISIBILITY constexpr
1010enable_if_t<
1011 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
Eric Fiselier8af90142017-03-30 20:06:52 +00001012 _VSTD::declval<const _Up&>()), bool>,
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001013 bool
1014>
Eric Fiselier8af90142017-03-30 20:06:52 +00001015operator>=(const optional<_Tp>& __x, const optional<_Up>& __y)
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001016{
1017 if (!static_cast<bool>(__y))
1018 return true;
1019 if (!static_cast<bool>(__x))
1020 return false;
1021 return *__x >= *__y;
1022}
1023
1024// Comparisons with nullopt
1025template <class _Tp>
1026_LIBCPP_INLINE_VISIBILITY constexpr
1027bool
1028operator==(const optional<_Tp>& __x, nullopt_t) noexcept
1029{
1030 return !static_cast<bool>(__x);
1031}
1032
1033template <class _Tp>
1034_LIBCPP_INLINE_VISIBILITY constexpr
1035bool
1036operator==(nullopt_t, const optional<_Tp>& __x) noexcept
1037{
1038 return !static_cast<bool>(__x);
1039}
1040
1041template <class _Tp>
1042_LIBCPP_INLINE_VISIBILITY constexpr
1043bool
1044operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
1045{
1046 return static_cast<bool>(__x);
1047}
1048
1049template <class _Tp>
1050_LIBCPP_INLINE_VISIBILITY constexpr
1051bool
1052operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
1053{
1054 return static_cast<bool>(__x);
1055}
1056
1057template <class _Tp>
1058_LIBCPP_INLINE_VISIBILITY constexpr
1059bool
1060operator<(const optional<_Tp>&, nullopt_t) noexcept
1061{
1062 return false;
1063}
1064
1065template <class _Tp>
1066_LIBCPP_INLINE_VISIBILITY constexpr
1067bool
1068operator<(nullopt_t, const optional<_Tp>& __x) noexcept
1069{
1070 return static_cast<bool>(__x);
1071}
1072
1073template <class _Tp>
1074_LIBCPP_INLINE_VISIBILITY constexpr
1075bool
1076operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
1077{
1078 return !static_cast<bool>(__x);
1079}
1080
1081template <class _Tp>
1082_LIBCPP_INLINE_VISIBILITY constexpr
1083bool
Eric Fiselier6003c772016-12-23 23:37:52 +00001084operator<=(nullopt_t, const optional<_Tp>&) noexcept
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001085{
1086 return true;
1087}
1088
1089template <class _Tp>
1090_LIBCPP_INLINE_VISIBILITY constexpr
1091bool
1092operator>(const optional<_Tp>& __x, nullopt_t) noexcept
1093{
1094 return static_cast<bool>(__x);
1095}
1096
1097template <class _Tp>
1098_LIBCPP_INLINE_VISIBILITY constexpr
1099bool
Eric Fiselier6003c772016-12-23 23:37:52 +00001100operator>(nullopt_t, const optional<_Tp>&) noexcept
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001101{
1102 return false;
1103}
1104
1105template <class _Tp>
1106_LIBCPP_INLINE_VISIBILITY constexpr
1107bool
1108operator>=(const optional<_Tp>&, nullopt_t) noexcept
1109{
1110 return true;
1111}
1112
1113template <class _Tp>
1114_LIBCPP_INLINE_VISIBILITY constexpr
1115bool
1116operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
1117{
1118 return !static_cast<bool>(__x);
1119}
1120
1121// Comparisons with T
Eric Fiselier8af90142017-03-30 20:06:52 +00001122template <class _Tp, class _Up>
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001123_LIBCPP_INLINE_VISIBILITY constexpr
1124enable_if_t<
1125 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
Eric Fiselier8af90142017-03-30 20:06:52 +00001126 _VSTD::declval<const _Up&>()), bool>,
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001127 bool
1128>
Eric Fiselier8af90142017-03-30 20:06:52 +00001129operator==(const optional<_Tp>& __x, const _Up& __v)
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001130{
1131 return static_cast<bool>(__x) ? *__x == __v : false;
1132}
1133
Eric Fiselier8af90142017-03-30 20:06:52 +00001134template <class _Tp, class _Up>
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001135_LIBCPP_INLINE_VISIBILITY constexpr
1136enable_if_t<
1137 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
Eric Fiselier8af90142017-03-30 20:06:52 +00001138 _VSTD::declval<const _Up&>()), bool>,
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001139 bool
1140>
Eric Fiselier8af90142017-03-30 20:06:52 +00001141operator==(const _Tp& __v, const optional<_Up>& __x)
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001142{
1143 return static_cast<bool>(__x) ? __v == *__x : false;
1144}
1145
Eric Fiselier8af90142017-03-30 20:06:52 +00001146template <class _Tp, class _Up>
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001147_LIBCPP_INLINE_VISIBILITY constexpr
1148enable_if_t<
1149 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
Eric Fiselier8af90142017-03-30 20:06:52 +00001150 _VSTD::declval<const _Up&>()), bool>,
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001151 bool
1152>
Eric Fiselier8af90142017-03-30 20:06:52 +00001153operator!=(const optional<_Tp>& __x, const _Up& __v)
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001154{
1155 return static_cast<bool>(__x) ? *__x != __v : true;
1156}
1157
Eric Fiselier8af90142017-03-30 20:06:52 +00001158template <class _Tp, class _Up>
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001159_LIBCPP_INLINE_VISIBILITY constexpr
1160enable_if_t<
1161 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
Eric Fiselier8af90142017-03-30 20:06:52 +00001162 _VSTD::declval<const _Up&>()), bool>,
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001163 bool
1164>
Eric Fiselier8af90142017-03-30 20:06:52 +00001165operator!=(const _Tp& __v, const optional<_Up>& __x)
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001166{
1167 return static_cast<bool>(__x) ? __v != *__x : true;
1168}
1169
Eric Fiselier8af90142017-03-30 20:06:52 +00001170template <class _Tp, class _Up>
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001171_LIBCPP_INLINE_VISIBILITY constexpr
1172enable_if_t<
1173 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
Eric Fiselier8af90142017-03-30 20:06:52 +00001174 _VSTD::declval<const _Up&>()), bool>,
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001175 bool
1176>
Eric Fiselier8af90142017-03-30 20:06:52 +00001177operator<(const optional<_Tp>& __x, const _Up& __v)
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001178{
1179 return static_cast<bool>(__x) ? *__x < __v : true;
1180}
1181
Eric Fiselier8af90142017-03-30 20:06:52 +00001182template <class _Tp, class _Up>
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001183_LIBCPP_INLINE_VISIBILITY constexpr
1184enable_if_t<
1185 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
Eric Fiselier8af90142017-03-30 20:06:52 +00001186 _VSTD::declval<const _Up&>()), bool>,
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001187 bool
1188>
Eric Fiselier8af90142017-03-30 20:06:52 +00001189operator<(const _Tp& __v, const optional<_Up>& __x)
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001190{
1191 return static_cast<bool>(__x) ? __v < *__x : false;
1192}
1193
Eric Fiselier8af90142017-03-30 20:06:52 +00001194template <class _Tp, class _Up>
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001195_LIBCPP_INLINE_VISIBILITY constexpr
1196enable_if_t<
1197 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
Eric Fiselier8af90142017-03-30 20:06:52 +00001198 _VSTD::declval<const _Up&>()), bool>,
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001199 bool
1200>
Eric Fiselier8af90142017-03-30 20:06:52 +00001201operator<=(const optional<_Tp>& __x, const _Up& __v)
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001202{
1203 return static_cast<bool>(__x) ? *__x <= __v : true;
1204}
1205
Eric Fiselier8af90142017-03-30 20:06:52 +00001206template <class _Tp, class _Up>
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001207_LIBCPP_INLINE_VISIBILITY constexpr
1208enable_if_t<
1209 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
Eric Fiselier8af90142017-03-30 20:06:52 +00001210 _VSTD::declval<const _Up&>()), bool>,
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001211 bool
1212>
Eric Fiselier8af90142017-03-30 20:06:52 +00001213operator<=(const _Tp& __v, const optional<_Up>& __x)
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001214{
1215 return static_cast<bool>(__x) ? __v <= *__x : false;
1216}
1217
Eric Fiselier8af90142017-03-30 20:06:52 +00001218template <class _Tp, class _Up>
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001219_LIBCPP_INLINE_VISIBILITY constexpr
1220enable_if_t<
1221 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
Eric Fiselier8af90142017-03-30 20:06:52 +00001222 _VSTD::declval<const _Up&>()), bool>,
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001223 bool
1224>
Eric Fiselier8af90142017-03-30 20:06:52 +00001225operator>(const optional<_Tp>& __x, const _Up& __v)
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001226{
1227 return static_cast<bool>(__x) ? *__x > __v : false;
1228}
1229
Eric Fiselier8af90142017-03-30 20:06:52 +00001230template <class _Tp, class _Up>
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001231_LIBCPP_INLINE_VISIBILITY constexpr
1232enable_if_t<
1233 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
Eric Fiselier8af90142017-03-30 20:06:52 +00001234 _VSTD::declval<const _Up&>()), bool>,
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001235 bool
1236>
Eric Fiselier8af90142017-03-30 20:06:52 +00001237operator>(const _Tp& __v, const optional<_Up>& __x)
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001238{
1239 return static_cast<bool>(__x) ? __v > *__x : true;
1240}
1241
Eric Fiselier8af90142017-03-30 20:06:52 +00001242template <class _Tp, class _Up>
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001243_LIBCPP_INLINE_VISIBILITY constexpr
1244enable_if_t<
1245 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
Eric Fiselier8af90142017-03-30 20:06:52 +00001246 _VSTD::declval<const _Up&>()), bool>,
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001247 bool
1248>
Eric Fiselier8af90142017-03-30 20:06:52 +00001249operator>=(const optional<_Tp>& __x, const _Up& __v)
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001250{
1251 return static_cast<bool>(__x) ? *__x >= __v : false;
1252}
1253
Eric Fiselier8af90142017-03-30 20:06:52 +00001254template <class _Tp, class _Up>
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001255_LIBCPP_INLINE_VISIBILITY constexpr
1256enable_if_t<
1257 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
Eric Fiselier8af90142017-03-30 20:06:52 +00001258 _VSTD::declval<const _Up&>()), bool>,
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001259 bool
1260>
Eric Fiselier8af90142017-03-30 20:06:52 +00001261operator>=(const _Tp& __v, const optional<_Up>& __x)
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001262{
1263 return static_cast<bool>(__x) ? __v >= *__x : true;
1264}
1265
1266
1267template <class _Tp>
1268inline _LIBCPP_INLINE_VISIBILITY
1269enable_if_t<
1270 is_move_constructible_v<_Tp> && is_swappable_v<_Tp>,
1271 void
1272>
1273swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
1274{
1275 __x.swap(__y);
1276}
1277
1278template <class _Tp>
1279_LIBCPP_INLINE_VISIBILITY constexpr
1280optional<decay_t<_Tp>> make_optional(_Tp&& __v)
1281{
1282 return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v));
1283}
1284
1285template <class _Tp, class... _Args>
1286_LIBCPP_INLINE_VISIBILITY constexpr
1287optional<_Tp> make_optional(_Args&&... __args)
1288{
1289 return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...);
1290}
1291
1292template <class _Tp, class _Up, class... _Args>
1293_LIBCPP_INLINE_VISIBILITY constexpr
1294optional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args)
1295{
1296 return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...);
1297}
1298
1299template <class _Tp>
Eric Fiselier698a97b2017-01-21 00:02:12 +00001300struct _LIBCPP_TEMPLATE_VIS hash<
1301 __enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>>
1302>
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001303{
1304 typedef optional<_Tp> argument_type;
1305 typedef size_t result_type;
1306
1307 _LIBCPP_INLINE_VISIBILITY
Marshall Clow49036892017-03-23 02:40:28 +00001308 result_type operator()(const argument_type& __opt) const
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001309 {
Eric Fiselier698a97b2017-01-21 00:02:12 +00001310 return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0;
Eric Fiselierd4ec6352016-10-12 07:46:20 +00001311 }
1312};
1313
1314_LIBCPP_END_NAMESPACE_STD
1315
1316#endif // _LIBCPP_STD_VER > 14
1317
1318#endif // _LIBCPP_OPTIONAL