1// <optional> -*- C++ -*-
2
3// Copyright (C) 2013-2018 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file include/optional
26 * This is a Standard C++ Library header.
27 */
28
29#ifndef _GLIBCXX_OPTIONAL
30#define _GLIBCXX_OPTIONAL 1
31
32#pragma GCC system_header
33
34#if __cplusplus >= 201703L
35
36#include <utility>
37#include <type_traits>
38#include <stdexcept>
39#include <new>
40#include <initializer_list>
41#include <bits/functexcept.h>
42#include <bits/functional_hash.h>
43#include <bits/enable_special_members.h>
44
45namespace std _GLIBCXX_VISIBILITY(default)
46{
47_GLIBCXX_BEGIN_NAMESPACE_VERSION
48
49 /**
50 * @addtogroup utilities
51 * @{
52 */
53
54#define __cpp_lib_optional 201603
55
56 template<typename _Tp>
57 class optional;
58
59 /// Tag type to disengage optional objects.
60 struct nullopt_t
61 {
62 // Do not user-declare default constructor at all for
63 // optional_value = {} syntax to work.
64 // nullopt_t() = delete;
65
66 // Used for constructing nullopt.
67 enum class _Construct { _Token };
68
69 // Must be constexpr for nullopt_t to be literal.
70 explicit constexpr nullopt_t(_Construct) { }
71 };
72
73 /// Tag to disengage optional objects.
74 inline constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token };
75
76 /**
77 * @brief Exception class thrown when a disengaged optional object is
78 * dereferenced.
79 * @ingroup exceptions
80 */
81 class bad_optional_access : public exception
82 {
83 public:
84 bad_optional_access() { }
85
86 virtual const char* what() const noexcept override
87 { return "bad optional access"; }
88
89 virtual ~bad_optional_access() noexcept = default;
90 };
91
92 void
93 __throw_bad_optional_access()
94 __attribute__((__noreturn__));
95
96 // XXX Does not belong here.
97 inline void
98 __throw_bad_optional_access()
99 { _GLIBCXX_THROW_OR_ABORT(bad_optional_access()); }
100
101
102 // Payload for optionals with non-trivial destructor.
103 template <typename _Tp,
104 bool /*_HasTrivialDestructor*/ =
105 is_trivially_destructible_v<_Tp>,
106 bool /*_HasTrivialCopy */ =
107 is_trivially_copy_assignable_v<_Tp>
108 && is_trivially_copy_constructible_v<_Tp>,
109 bool /*_HasTrivialMove */ =
110 is_trivially_move_assignable_v<_Tp>
111 && is_trivially_move_constructible_v<_Tp>>
112 struct _Optional_payload
113 {
114 constexpr _Optional_payload() noexcept : _M_empty() { }
115
116 template <typename... _Args>
117 constexpr
118 _Optional_payload(in_place_t, _Args&&... __args)
119 : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { }
120
121 template<typename _Up, typename... _Args>
122 constexpr
123 _Optional_payload(std::initializer_list<_Up> __il,
124 _Args&&... __args)
125 : _M_payload(__il, std::forward<_Args>(__args)...),
126 _M_engaged(true)
127 { }
128
129 constexpr
130 _Optional_payload(bool __engaged, const _Optional_payload& __other)
131 : _Optional_payload(__other)
132 { }
133
134 constexpr
135 _Optional_payload(bool __engaged, _Optional_payload&& __other)
136 : _Optional_payload(std::move(__other))
137 { }
138
139 constexpr
140 _Optional_payload(const _Optional_payload& __other)
141 {
142 if (__other._M_engaged)
143 this->_M_construct(__other._M_payload);
144 }
145
146 constexpr
147 _Optional_payload(_Optional_payload&& __other)
148 {
149 if (__other._M_engaged)
150 this->_M_construct(std::move(__other._M_payload));
151 }
152
153 constexpr
154 _Optional_payload&
155 operator=(const _Optional_payload& __other)
156 {
157 if (this->_M_engaged && __other._M_engaged)
158 this->_M_get() = __other._M_get();
159 else
160 {
161 if (__other._M_engaged)
162 this->_M_construct(__other._M_get());
163 else
164 this->_M_reset();
165 }
166 return *this;
167 }
168
169 constexpr
170 _Optional_payload&
171 operator=(_Optional_payload&& __other)
172 noexcept(__and_<is_nothrow_move_constructible<_Tp>,
173 is_nothrow_move_assignable<_Tp>>())
174 {
175 if (this->_M_engaged && __other._M_engaged)
176 this->_M_get() = std::move(__other._M_get());
177 else
178 {
179 if (__other._M_engaged)
180 this->_M_construct(std::move(__other._M_get()));
181 else
182 this->_M_reset();
183 }
184 return *this;
185 }
186
187 using _Stored_type = remove_const_t<_Tp>;
188
189 struct _Empty_byte { };
190
191 union {
192 _Empty_byte _M_empty;
193 _Stored_type _M_payload;
194 };
195 bool _M_engaged = false;
196
197 ~_Optional_payload()
198 {
199 if (_M_engaged)
200 _M_payload.~_Stored_type();
201 }
202
203 template<typename... _Args>
204 void
205 _M_construct(_Args&&... __args)
206 noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
207 {
208 ::new ((void *) std::__addressof(this->_M_payload))
209 _Stored_type(std::forward<_Args>(__args)...);
210 this->_M_engaged = true;
211 }
212
213 // The _M_get operations have _M_engaged as a precondition.
214 constexpr _Tp&
215 _M_get() noexcept
216 { return this->_M_payload; }
217
218 constexpr const _Tp&
219 _M_get() const noexcept
220 { return this->_M_payload; }
221
222 // _M_reset is a 'safe' operation with no precondition.
223 constexpr
224 void
225 _M_reset() noexcept
226 {
227 if (this->_M_engaged)
228 {
229 this->_M_engaged = false;
230 this->_M_payload.~_Stored_type();
231 }
232 }
233 };
234
235 // Payload for potentially-constexpr optionals.
236 template <typename _Tp>
237 struct _Optional_payload<_Tp, true, true, true>
238 {
239 constexpr _Optional_payload() noexcept
240 : _M_empty(), _M_engaged(false) { }
241
242 template<typename... _Args>
243 constexpr
244 _Optional_payload(in_place_t, _Args&&... __args)
245 : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true)
246 { }
247
248 template<typename _Up, typename... _Args>
249 constexpr
250 _Optional_payload(std::initializer_list<_Up> __il,
251 _Args&&... __args)
252 : _M_payload(__il, std::forward<_Args>(__args)...),
253 _M_engaged(true)
254 { }
255
256 constexpr
257 _Optional_payload(bool __engaged, const _Optional_payload& __other)
258 : _M_engaged(__engaged)
259 {
260 if (__engaged)
261 _M_construct(__other._M_get());
262 }
263
264 constexpr
265 _Optional_payload(bool __engaged, _Optional_payload&& __other)
266 : _M_engaged(__engaged)
267 {
268 if (__engaged)
269 _M_construct(std::move(__other._M_get()));
270 }
271
272 using _Stored_type = remove_const_t<_Tp>;
273
274 struct _Empty_byte { };
275
276 union {
277 _Empty_byte _M_empty;
278 _Stored_type _M_payload;
279 };
280 bool _M_engaged;
281
282 // The _M_get operations have _M_engaged as a precondition.
283 constexpr _Tp&
284 _M_get() noexcept
285 { return this->_M_payload; }
286
287 constexpr const _Tp&
288 _M_get() const noexcept
289 { return this->_M_payload; }
290 };
291
292 // Payload for optionals with non-trivial copy assignment.
293 template <typename _Tp>
294 struct _Optional_payload<_Tp, true, false, true>
295 {
296 constexpr _Optional_payload() noexcept
297 : _M_empty(), _M_engaged(false) { }
298
299 template<typename... _Args>
300 constexpr
301 _Optional_payload(in_place_t, _Args&&... __args)
302 : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true)
303 { }
304
305 template<typename _Up, typename... _Args>
306 constexpr
307 _Optional_payload(std::initializer_list<_Up> __il,
308 _Args&&... __args)
309 : _M_payload(__il, std::forward<_Args>(__args)...),
310 _M_engaged(true)
311 { }
312
313 constexpr
314 _Optional_payload(bool __engaged, const _Optional_payload& __other)
315 : _M_engaged(__engaged)
316 {
317 if (__engaged)
318 _M_construct(__other._M_get());
319 }
320
321 constexpr
322 _Optional_payload(bool __engaged, _Optional_payload&& __other)
323 : _M_engaged(__engaged)
324 {
325 if (__engaged)
326 _M_construct(std::move(__other._M_get()));
327 }
328
329 _Optional_payload(const _Optional_payload&) = default;
330 _Optional_payload(_Optional_payload&&) = default;
331
332 constexpr
333 _Optional_payload&
334 operator=(const _Optional_payload& __other)
335 {
336 if (this->_M_engaged && __other._M_engaged)
337 this->_M_get() = __other._M_get();
338 else
339 {
340 if (__other._M_engaged)
341 this->_M_construct(__other._M_get());
342 else
343 this->_M_reset();
344 }
345 return *this;
346 }
347
348 _Optional_payload&
349 operator=(_Optional_payload&& __other) = default;
350
351 using _Stored_type = remove_const_t<_Tp>;
352
353 struct _Empty_byte { };
354
355 union {
356 _Empty_byte _M_empty;
357 _Stored_type _M_payload;
358 };
359 bool _M_engaged;
360
361 template<typename... _Args>
362 void
363 _M_construct(_Args&&... __args)
364 noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
365 {
366 ::new ((void *) std::__addressof(this->_M_payload))
367 _Stored_type(std::forward<_Args>(__args)...);
368 this->_M_engaged = true;
369 }
370
371 // The _M_get operations have _M_engaged as a precondition.
372 constexpr _Tp&
373 _M_get() noexcept
374 { return this->_M_payload; }
375
376 constexpr const _Tp&
377 _M_get() const noexcept
378 { return this->_M_payload; }
379
380 // _M_reset is a 'safe' operation with no precondition.
381 constexpr
382 void
383 _M_reset() noexcept
384 {
385 if (this->_M_engaged)
386 {
387 this->_M_engaged = false;
388 this->_M_payload.~_Stored_type();
389 }
390 }
391 };
392
393 // Payload for optionals with non-trivial move assignment.
394 template <typename _Tp>
395 struct _Optional_payload<_Tp, true, true, false>
396 {
397 constexpr _Optional_payload() noexcept
398 : _M_empty(), _M_engaged(false) { }
399
400 template<typename... _Args>
401 constexpr
402 _Optional_payload(in_place_t, _Args&&... __args)
403 : _M_payload(std::forward<_Args>(__args)...),
404 _M_engaged(true)
405 { }
406
407 template<typename _Up, typename... _Args>
408 constexpr
409 _Optional_payload(std::initializer_list<_Up> __il,
410 _Args&&... __args)
411 : _M_payload(__il, std::forward<_Args>(__args)...),
412 _M_engaged(true)
413 { }
414
415 constexpr
416 _Optional_payload(bool __engaged, const _Optional_payload& __other)
417 : _M_engaged(__engaged)
418 {
419 if (__engaged)
420 _M_construct(__other._M_get());
421 }
422
423 constexpr
424 _Optional_payload(bool __engaged, _Optional_payload&& __other)
425 : _M_engaged(__engaged)
426 {
427 if (__engaged)
428 _M_construct(std::move(__other._M_get()));
429 }
430
431 _Optional_payload(const _Optional_payload&) = default;
432 _Optional_payload(_Optional_payload&&) = default;
433
434 _Optional_payload&
435 operator=(const _Optional_payload& __other) = default;
436
437 constexpr
438 _Optional_payload&
439 operator=(_Optional_payload&& __other)
440 noexcept(__and_<is_nothrow_move_constructible<_Tp>,
441 is_nothrow_move_assignable<_Tp>>())
442 {
443 if (this->_M_engaged && __other._M_engaged)
444 this->_M_get() = std::move(__other._M_get());
445 else
446 {
447 if (__other._M_engaged)
448 this->_M_construct(std::move(__other._M_get()));
449 else
450 this->_M_reset();
451 }
452 return *this;
453 }
454
455 using _Stored_type = remove_const_t<_Tp>;
456
457 struct _Empty_byte { };
458
459 union {
460 _Empty_byte _M_empty;
461 _Stored_type _M_payload;
462 };
463 bool _M_engaged;
464
465 template<typename... _Args>
466 void
467 _M_construct(_Args&&... __args)
468 noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
469 {
470 ::new ((void *) std::__addressof(this->_M_payload))
471 _Stored_type(std::forward<_Args>(__args)...);
472 this->_M_engaged = true;
473 }
474
475 // The _M_get operations have _M_engaged as a precondition.
476 constexpr _Tp&
477 _M_get() noexcept
478 { return this->_M_payload; }
479
480 constexpr const _Tp&
481 _M_get() const noexcept
482 { return this->_M_payload; }
483
484 // _M_reset is a 'safe' operation with no precondition.
485 constexpr
486 void
487 _M_reset() noexcept
488 {
489 if (this->_M_engaged)
490 {
491 this->_M_engaged = false;
492 this->_M_payload.~_Stored_type();
493 }
494 }
495 };
496
497 // Payload for optionals with non-trivial copy and move assignment.
498 template <typename _Tp>
499 struct _Optional_payload<_Tp, true, false, false>
500 {
501 constexpr _Optional_payload() noexcept
502 : _M_empty(), _M_engaged(false) {}
503
504 template<typename... _Args>
505 constexpr
506 _Optional_payload(in_place_t, _Args&&... __args)
507 : _M_payload(std::forward<_Args>(__args)...),
508 _M_engaged(true)
509 { }
510
511 template<typename _Up, typename... _Args>
512 constexpr
513 _Optional_payload(std::initializer_list<_Up> __il,
514 _Args&&... __args)
515 : _M_payload(__il, std::forward<_Args>(__args)...),
516 _M_engaged(true)
517 { }
518
519 constexpr
520 _Optional_payload(bool __engaged, const _Optional_payload& __other)
521 : _M_engaged(__engaged)
522 {
523 if (__engaged)
524 _M_construct(__other._M_get());
525 }
526
527 constexpr
528 _Optional_payload(bool __engaged, _Optional_payload&& __other)
529 : _M_engaged(__engaged)
530 {
531 if (__engaged)
532 _M_construct(std::move(__other._M_get()));
533 }
534
535 _Optional_payload(const _Optional_payload&) = default;
536 _Optional_payload(_Optional_payload&&) = default;
537
538 constexpr
539 _Optional_payload&
540 operator=(const _Optional_payload& __other)
541 {
542 if (this->_M_engaged && __other._M_engaged)
543 this->_M_get() = __other._M_get();
544 else
545 {
546 if (__other._M_engaged)
547 this->_M_construct(__other._M_get());
548 else
549 this->_M_reset();
550 }
551 return *this;
552 }
553
554 constexpr
555 _Optional_payload&
556 operator=(_Optional_payload&& __other)
557 noexcept(__and_<is_nothrow_move_constructible<_Tp>,
558 is_nothrow_move_assignable<_Tp>>())
559 {
560 if (this->_M_engaged && __other._M_engaged)
561 this->_M_get() = std::move(__other._M_get());
562 else
563 {
564 if (__other._M_engaged)
565 this->_M_construct(std::move(__other._M_get()));
566 else
567 this->_M_reset();
568 }
569 return *this;
570 }
571
572 using _Stored_type = remove_const_t<_Tp>;
573
574 struct _Empty_byte { };
575
576 union {
577 _Empty_byte _M_empty;
578 _Stored_type _M_payload;
579 };
580 bool _M_engaged;
581
582 template<typename... _Args>
583 void
584 _M_construct(_Args&&... __args)
585 noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
586 {
587 ::new ((void *) std::__addressof(this->_M_payload))
588 _Stored_type(std::forward<_Args>(__args)...);
589 this->_M_engaged = true;
590 }
591
592 // The _M_get operations have _M_engaged as a precondition.
593 constexpr _Tp&
594 _M_get() noexcept
595 { return this->_M_payload; }
596
597 constexpr const _Tp&
598 _M_get() const noexcept
599 { return this->_M_payload; }
600
601 // _M_reset is a 'safe' operation with no precondition.
602 constexpr
603 void
604 _M_reset() noexcept
605 {
606 if (this->_M_engaged)
607 {
608 this->_M_engaged = false;
609 this->_M_payload.~_Stored_type();
610 }
611 }
612 };
613
614 template<typename _Tp, typename _Dp>
615 class _Optional_base_impl
616 {
617 protected:
618 using _Stored_type = remove_const_t<_Tp>;
619
620 // The _M_construct operation has !_M_engaged as a precondition
621 // while _M_destruct has _M_engaged as a precondition.
622 template<typename... _Args>
623 void
624 _M_construct(_Args&&... __args)
625 noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
626 {
627 ::new
628 (std::__addressof(static_cast<_Dp*>(this)->_M_payload._M_payload))
629 _Stored_type(std::forward<_Args>(__args)...);
630 static_cast<_Dp*>(this)->_M_payload._M_engaged = true;
631 }
632
633 void
634 _M_destruct() noexcept
635 {
636 static_cast<_Dp*>(this)->_M_payload._M_engaged = false;
637 static_cast<_Dp*>(this)->_M_payload._M_payload.~_Stored_type();
638 }
639
640 // _M_reset is a 'safe' operation with no precondition.
641 constexpr
642 void
643 _M_reset() noexcept
644 {
645 if (static_cast<_Dp*>(this)->_M_payload._M_engaged)
646 static_cast<_Dp*>(this)->_M_destruct();
647 }
648 };
649
650 /**
651 * @brief Class template that takes care of copy/move constructors
652 of optional
653 *
654 * Such a separate base class template is necessary in order to
655 * conditionally make copy/move constructors trivial.
656 * @see optional, _Enable_special_members
657 */
658 template<typename _Tp,
659 bool = is_trivially_copy_constructible_v<_Tp>,
660 bool = is_trivially_move_constructible_v<_Tp>>
661 class _Optional_base
662 // protected inheritance because optional needs to reach that base too
663 : protected _Optional_base_impl<_Tp, _Optional_base<_Tp>>
664 {
665 friend class _Optional_base_impl<_Tp, _Optional_base<_Tp>>;
666
667 public:
668 // Constructors for disengaged optionals.
669 constexpr _Optional_base() = default;
670
671 // Constructors for engaged optionals.
672 template<typename... _Args,
673 enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
674 constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
675 : _M_payload(in_place,
676 std::forward<_Args>(__args)...) { }
677
678 template<typename _Up, typename... _Args,
679 enable_if_t<is_constructible_v<_Tp,
680 initializer_list<_Up>&,
681 _Args&&...>, bool> = false>
682 constexpr explicit _Optional_base(in_place_t,
683 initializer_list<_Up> __il,
684 _Args&&... __args)
685 : _M_payload(in_place,
686 __il, std::forward<_Args>(__args)...)
687 { }
688
689 // Copy and move constructors.
690 constexpr _Optional_base(const _Optional_base& __other)
691 : _M_payload(__other._M_payload._M_engaged,
692 __other._M_payload)
693 { }
694
695 constexpr _Optional_base(_Optional_base&& __other)
696 noexcept(is_nothrow_move_constructible<_Tp>())
697 : _M_payload(__other._M_payload._M_engaged,
698 std::move(__other._M_payload))
699 { }
700
701 // Assignment operators.
702 _Optional_base& operator=(const _Optional_base&) = default;
703 _Optional_base& operator=(_Optional_base&&) = default;
704
705 protected:
706
707 constexpr bool _M_is_engaged() const noexcept
708 { return this->_M_payload._M_engaged; }
709
710 // The _M_get operations have _M_engaged as a precondition.
711 constexpr _Tp&
712 _M_get() noexcept
713 {
714 __glibcxx_assert(this->_M_is_engaged());
715 return this->_M_payload._M_payload;
716 }
717
718 constexpr const _Tp&
719 _M_get() const noexcept
720 {
721 __glibcxx_assert(this->_M_is_engaged());
722 return this->_M_payload._M_payload;
723 }
724
725 private:
726 _Optional_payload<_Tp> _M_payload;
727 };
728
729 template<typename _Tp>
730 class _Optional_base<_Tp, false, true>
731 : protected _Optional_base_impl<_Tp, _Optional_base<_Tp>>
732 {
733 friend class _Optional_base_impl<_Tp, _Optional_base<_Tp>>;
734 public:
735
736 // Constructors for disengaged optionals.
737 constexpr _Optional_base() = default;
738
739 // Constructors for engaged optionals.
740 template<typename... _Args,
741 enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
742 constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
743 : _M_payload(in_place,
744 std::forward<_Args>(__args)...) { }
745
746 template<typename _Up, typename... _Args,
747 enable_if_t<is_constructible_v<_Tp,
748 initializer_list<_Up>&,
749 _Args&&...>, bool> = false>
750 constexpr explicit _Optional_base(in_place_t,
751 initializer_list<_Up> __il,
752 _Args&&... __args)
753 : _M_payload(in_place,
754 __il, std::forward<_Args>(__args)...)
755 { }
756
757 // Copy and move constructors.
758 constexpr _Optional_base(const _Optional_base& __other)
759 : _M_payload(__other._M_payload._M_engaged,
760 __other._M_payload)
761 { }
762
763 constexpr _Optional_base(_Optional_base&& __other) = default;
764
765 // Assignment operators.
766 _Optional_base& operator=(const _Optional_base&) = default;
767 _Optional_base& operator=(_Optional_base&&) = default;
768
769 protected:
770
771 constexpr bool _M_is_engaged() const noexcept
772 { return this->_M_payload._M_engaged; }
773
774 // The _M_get operations have _M_engaged as a precondition.
775 constexpr _Tp&
776 _M_get() noexcept
777 {
778 __glibcxx_assert(this->_M_is_engaged());
779 return this->_M_payload._M_payload;
780 }
781
782 constexpr const _Tp&
783 _M_get() const noexcept
784 {
785 __glibcxx_assert(this->_M_is_engaged());
786 return this->_M_payload._M_payload;
787 }
788
789 private:
790 _Optional_payload<_Tp> _M_payload;
791 };
792
793 template<typename _Tp>
794 class _Optional_base<_Tp, true, false>
795 : protected _Optional_base_impl<_Tp, _Optional_base<_Tp>>
796 {
797 friend class _Optional_base_impl<_Tp, _Optional_base<_Tp>>;
798 public:
799
800 // Constructors for disengaged optionals.
801 constexpr _Optional_base() = default;
802
803 // Constructors for engaged optionals.
804 template<typename... _Args,
805 enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
806 constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
807 : _M_payload(in_place,
808 std::forward<_Args>(__args)...) { }
809
810 template<typename _Up, typename... _Args,
811 enable_if_t<is_constructible_v<_Tp,
812 initializer_list<_Up>&,
813 _Args&&...>, bool> = false>
814 constexpr explicit _Optional_base(in_place_t,
815 initializer_list<_Up> __il,
816 _Args&&... __args)
817 : _M_payload(in_place,
818 __il, std::forward<_Args>(__args)...)
819 { }
820
821 // Copy and move constructors.
822 constexpr _Optional_base(const _Optional_base& __other) = default;
823
824 constexpr _Optional_base(_Optional_base&& __other)
825 noexcept(is_nothrow_move_constructible<_Tp>())
826 : _M_payload(__other._M_payload._M_engaged,
827 std::move(__other._M_payload))
828 { }
829
830 // Assignment operators.
831 _Optional_base& operator=(const _Optional_base&) = default;
832 _Optional_base& operator=(_Optional_base&&) = default;
833
834 protected:
835
836 constexpr bool _M_is_engaged() const noexcept
837 { return this->_M_payload._M_engaged; }
838
839 // The _M_get operations have _M_engaged as a precondition.
840 constexpr _Tp&
841 _M_get() noexcept
842 {
843 __glibcxx_assert(this->_M_is_engaged());
844 return this->_M_payload._M_payload;
845 }
846
847 constexpr const _Tp&
848 _M_get() const noexcept
849 {
850 __glibcxx_assert(this->_M_is_engaged());
851 return this->_M_payload._M_payload;
852 }
853
854 private:
855 _Optional_payload<_Tp> _M_payload;
856 };
857
858 template<typename _Tp>
859 class _Optional_base<_Tp, true, true>
860 : protected _Optional_base_impl<_Tp, _Optional_base<_Tp>>
861 {
862 friend class _Optional_base_impl<_Tp, _Optional_base<_Tp>>;
863 public:
864
865 // Constructors for disengaged optionals.
866 constexpr _Optional_base() = default;
867
868 // Constructors for engaged optionals.
869 template<typename... _Args,
870 enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
871 constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
872 : _M_payload(in_place,
873 std::forward<_Args>(__args)...) { }
874
875 template<typename _Up, typename... _Args,
876 enable_if_t<is_constructible_v<_Tp,
877 initializer_list<_Up>&,
878 _Args&&...>, bool> = false>
879 constexpr explicit _Optional_base(in_place_t,
880 initializer_list<_Up> __il,
881 _Args&&... __args)
882 : _M_payload(in_place,
883 __il, std::forward<_Args>(__args)...)
884 { }
885
886 // Copy and move constructors.
887 constexpr _Optional_base(const _Optional_base& __other) = default;
888 constexpr _Optional_base(_Optional_base&& __other) = default;
889
890 // Assignment operators.
891 _Optional_base& operator=(const _Optional_base&) = default;
892 _Optional_base& operator=(_Optional_base&&) = default;
893
894 protected:
895
896 constexpr bool _M_is_engaged() const noexcept
897 { return this->_M_payload._M_engaged; }
898
899 // The _M_get operations have _M_engaged as a precondition.
900 constexpr _Tp&
901 _M_get() noexcept
902 {
903 __glibcxx_assert(this->_M_is_engaged());
904 return this->_M_payload._M_payload;
905 }
906
907 constexpr const _Tp&
908 _M_get() const noexcept
909 {
910 __glibcxx_assert(this->_M_is_engaged());
911 return this->_M_payload._M_payload;
912 }
913
914 private:
915 _Optional_payload<_Tp> _M_payload;
916 };
917
918 template<typename _Tp>
919 class optional;
920
921 template<typename _Tp, typename _Up>
922 using __converts_from_optional =
923 __or_<is_constructible<_Tp, const optional<_Up>&>,
924 is_constructible<_Tp, optional<_Up>&>,
925 is_constructible<_Tp, const optional<_Up>&&>,
926 is_constructible<_Tp, optional<_Up>&&>,
927 is_convertible<const optional<_Up>&, _Tp>,
928 is_convertible<optional<_Up>&, _Tp>,
929 is_convertible<const optional<_Up>&&, _Tp>,
930 is_convertible<optional<_Up>&&, _Tp>>;
931
932 template<typename _Tp, typename _Up>
933 using __assigns_from_optional =
934 __or_<is_assignable<_Tp&, const optional<_Up>&>,
935 is_assignable<_Tp&, optional<_Up>&>,
936 is_assignable<_Tp&, const optional<_Up>&&>,
937 is_assignable<_Tp&, optional<_Up>&&>>;
938
939 /**
940 * @brief Class template for optional values.
941 */
942 template<typename _Tp>
943 class optional
944 : private _Optional_base<_Tp>,
945 private _Enable_copy_move<
946 // Copy constructor.
947 is_copy_constructible<_Tp>::value,
948 // Copy assignment.
949 __and_<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>::value,
950 // Move constructor.
951 is_move_constructible<_Tp>::value,
952 // Move assignment.
953 __and_<is_move_constructible<_Tp>, is_move_assignable<_Tp>>::value,
954 // Unique tag type.
955 optional<_Tp>>
956 {
957 static_assert(!is_same_v<remove_cv_t<_Tp>, nullopt_t>);
958 static_assert(!is_same_v<remove_cv_t<_Tp>, in_place_t>);
959 static_assert(!is_reference_v<_Tp>);
960
961 private:
962 using _Base = _Optional_base<_Tp>;
963
964 public:
965 using value_type = _Tp;
966
967 constexpr optional() = default;
968
969 constexpr optional(nullopt_t) noexcept { }
970
971 // Converting constructors for engaged optionals.
972 template <typename _Up = _Tp,
973 enable_if_t<__and_<
974 __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
975 __not_<is_same<in_place_t, decay_t<_Up>>>,
976 is_constructible<_Tp, _Up&&>,
977 is_convertible<_Up&&, _Tp>
978 >::value, bool> = true>
979 constexpr optional(_Up&& __t)
980 : _Base(std::in_place, std::forward<_Up>(__t)) { }
981
982 template <typename _Up = _Tp,
983 enable_if_t<__and_<
984 __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
985 __not_<is_same<in_place_t, decay_t<_Up>>>,
986 is_constructible<_Tp, _Up&&>,
987 __not_<is_convertible<_Up&&, _Tp>>
988 >::value, bool> = false>
989 explicit constexpr optional(_Up&& __t)
990 : _Base(std::in_place, std::forward<_Up>(__t)) { }
991
992 template <typename _Up,
993 enable_if_t<__and_<
994 __not_<is_same<_Tp, _Up>>,
995 is_constructible<_Tp, const _Up&>,
996 is_convertible<const _Up&, _Tp>,
997 __not_<__converts_from_optional<_Tp, _Up>>
998 >::value, bool> = true>
999 constexpr optional(const optional<_Up>& __t)
1000 {
1001 if (__t)
1002 emplace(*__t);
1003 }
1004
1005 template <typename _Up,
1006 enable_if_t<__and_<
1007 __not_<is_same<_Tp, _Up>>,
1008 is_constructible<_Tp, const _Up&>,
1009 __not_<is_convertible<const _Up&, _Tp>>,
1010 __not_<__converts_from_optional<_Tp, _Up>>
1011 >::value, bool> = false>
1012 explicit constexpr optional(const optional<_Up>& __t)
1013 {
1014 if (__t)
1015 emplace(*__t);
1016 }
1017
1018 template <typename _Up,
1019 enable_if_t<__and_<
1020 __not_<is_same<_Tp, _Up>>,
1021 is_constructible<_Tp, _Up&&>,
1022 is_convertible<_Up&&, _Tp>,
1023 __not_<__converts_from_optional<_Tp, _Up>>
1024 >::value, bool> = true>
1025 constexpr optional(optional<_Up>&& __t)
1026 {
1027 if (__t)
1028 emplace(std::move(*__t));
1029 }
1030
1031 template <typename _Up,
1032 enable_if_t<__and_<
1033 __not_<is_same<_Tp, _Up>>,
1034 is_constructible<_Tp, _Up&&>,
1035 __not_<is_convertible<_Up&&, _Tp>>,
1036 __not_<__converts_from_optional<_Tp, _Up>>
1037 >::value, bool> = false>
1038 explicit constexpr optional(optional<_Up>&& __t)
1039 {
1040 if (__t)
1041 emplace(std::move(*__t));
1042 }
1043
1044 template<typename... _Args,
1045 enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
1046 explicit constexpr optional(in_place_t, _Args&&... __args)
1047 : _Base(std::in_place, std::forward<_Args>(__args)...) { }
1048
1049 template<typename _Up, typename... _Args,
1050 enable_if_t<is_constructible_v<_Tp,
1051 initializer_list<_Up>&,
1052 _Args&&...>, bool> = false>
1053 explicit constexpr optional(in_place_t,
1054 initializer_list<_Up> __il,
1055 _Args&&... __args)
1056 : _Base(std::in_place, __il, std::forward<_Args>(__args)...) { }
1057
1058 // Assignment operators.
1059 optional&
1060 operator=(nullopt_t) noexcept
1061 {
1062 this->_M_reset();
1063 return *this;
1064 }
1065
1066 template<typename _Up = _Tp>
1067 enable_if_t<__and_<
1068 __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
1069 is_constructible<_Tp, _Up>,
1070 __not_<__and_<is_scalar<_Tp>,
1071 is_same<_Tp, decay_t<_Up>>>>,
1072 is_assignable<_Tp&, _Up>>::value,
1073 optional&>
1074 operator=(_Up&& __u)
1075 {
1076 if (this->_M_is_engaged())
1077 this->_M_get() = std::forward<_Up>(__u);
1078 else
1079 this->_M_construct(std::forward<_Up>(__u));
1080
1081 return *this;
1082 }
1083
1084 template<typename _Up>
1085 enable_if_t<__and_<
1086 __not_<is_same<_Tp, _Up>>,
1087 is_constructible<_Tp, const _Up&>,
1088 is_assignable<_Tp&, _Up>,
1089 __not_<__converts_from_optional<_Tp, _Up>>,
1090 __not_<__assigns_from_optional<_Tp, _Up>>
1091 >::value,
1092 optional&>
1093 operator=(const optional<_Up>& __u)
1094 {
1095 if (__u)
1096 {
1097 if (this->_M_is_engaged())
1098 this->_M_get() = *__u;
1099 else
1100 this->_M_construct(*__u);
1101 }
1102 else
1103 {
1104 this->_M_reset();
1105 }
1106 return *this;
1107 }
1108
1109 template<typename _Up>
1110 enable_if_t<__and_<
1111 __not_<is_same<_Tp, _Up>>,
1112 is_constructible<_Tp, _Up>,
1113 is_assignable<_Tp&, _Up>,
1114 __not_<__converts_from_optional<_Tp, _Up>>,
1115 __not_<__assigns_from_optional<_Tp, _Up>>
1116 >::value,
1117 optional&>
1118 operator=(optional<_Up>&& __u)
1119 {
1120 if (__u)
1121 {
1122 if (this->_M_is_engaged())
1123 this->_M_get() = std::move(*__u);
1124 else
1125 this->_M_construct(std::move(*__u));
1126 }
1127 else
1128 {
1129 this->_M_reset();
1130 }
1131
1132 return *this;
1133 }
1134
1135 template<typename... _Args>
1136 enable_if_t<is_constructible<_Tp, _Args&&...>::value, _Tp&>
1137 emplace(_Args&&... __args)
1138 {
1139 this->_M_reset();
1140 this->_M_construct(std::forward<_Args>(__args)...);
1141 return this->_M_get();
1142 }
1143
1144 template<typename _Up, typename... _Args>
1145 enable_if_t<is_constructible<_Tp, initializer_list<_Up>&,
1146 _Args&&...>::value, _Tp&>
1147 emplace(initializer_list<_Up> __il, _Args&&... __args)
1148 {
1149 this->_M_reset();
1150 this->_M_construct(__il, std::forward<_Args>(__args)...);
1151 return this->_M_get();
1152 }
1153
1154 // Destructor is implicit, implemented in _Optional_base.
1155
1156 // Swap.
1157 void
1158 swap(optional& __other)
1159 noexcept(is_nothrow_move_constructible<_Tp>()
1160 && is_nothrow_swappable_v<_Tp>)
1161 {
1162 using std::swap;
1163
1164 if (this->_M_is_engaged() && __other._M_is_engaged())
1165 swap(this->_M_get(), __other._M_get());
1166 else if (this->_M_is_engaged())
1167 {
1168 __other._M_construct(std::move(this->_M_get()));
1169 this->_M_destruct();
1170 }
1171 else if (__other._M_is_engaged())
1172 {
1173 this->_M_construct(std::move(__other._M_get()));
1174 __other._M_destruct();
1175 }
1176 }
1177
1178 // Observers.
1179 constexpr const _Tp*
1180 operator->() const
1181 { return std::__addressof(this->_M_get()); }
1182
1183 constexpr
1184 _Tp*
1185 operator->()
1186 { return std::__addressof(this->_M_get()); }
1187
1188 constexpr const _Tp&
1189 operator*() const&
1190 { return this->_M_get(); }
1191
1192 constexpr _Tp&
1193 operator*()&
1194 { return this->_M_get(); }
1195
1196 constexpr _Tp&&
1197 operator*()&&
1198 { return std::move(this->_M_get()); }
1199
1200 constexpr const _Tp&&
1201 operator*() const&&
1202 { return std::move(this->_M_get()); }
1203
1204 constexpr explicit operator bool() const noexcept
1205 { return this->_M_is_engaged(); }
1206
1207 constexpr bool has_value() const noexcept
1208 { return this->_M_is_engaged(); }
1209
1210 constexpr const _Tp&
1211 value() const&
1212 {
1213 return this->_M_is_engaged()
1214 ? this->_M_get()
1215 : (__throw_bad_optional_access(),
1216 this->_M_get());
1217 }
1218
1219 constexpr _Tp&
1220 value()&
1221 {
1222 return this->_M_is_engaged()
1223 ? this->_M_get()
1224 : (__throw_bad_optional_access(),
1225 this->_M_get());
1226 }
1227
1228 constexpr _Tp&&
1229 value()&&
1230 {
1231 return this->_M_is_engaged()
1232 ? std::move(this->_M_get())
1233 : (__throw_bad_optional_access(),
1234 std::move(this->_M_get()));
1235 }
1236
1237 constexpr const _Tp&&
1238 value() const&&
1239 {
1240 return this->_M_is_engaged()
1241 ? std::move(this->_M_get())
1242 : (__throw_bad_optional_access(),
1243 std::move(this->_M_get()));
1244 }
1245
1246 template<typename _Up>
1247 constexpr _Tp
1248 value_or(_Up&& __u) const&
1249 {
1250 static_assert(is_copy_constructible_v<_Tp>);
1251 static_assert(is_convertible_v<_Up&&, _Tp>);
1252
1253 return this->_M_is_engaged()
1254 ? this->_M_get()
1255 : static_cast<_Tp>(std::forward<_Up>(__u));
1256 }
1257
1258 template<typename _Up>
1259 _Tp
1260 value_or(_Up&& __u) &&
1261 {
1262 static_assert(is_move_constructible_v<_Tp>);
1263 static_assert(is_convertible_v<_Up&&, _Tp>);
1264
1265 return this->_M_is_engaged()
1266 ? std::move(this->_M_get())
1267 : static_cast<_Tp>(std::forward<_Up>(__u));
1268 }
1269 void reset() noexcept { this->_M_reset(); }
1270 };
1271
1272 template<typename _Tp>
1273 using __optional_relop_t =
1274 enable_if_t<is_convertible<_Tp, bool>::value, bool>;
1275
1276 // Comparisons between optional values.
1277 template<typename _Tp, typename _Up>
1278 constexpr auto
1279 operator==(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1280 -> __optional_relop_t<decltype(declval<_Tp>() == declval<_Up>())>
1281 {
1282 return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
1283 && (!__lhs || *__lhs == *__rhs);
1284 }
1285
1286 template<typename _Tp, typename _Up>
1287 constexpr auto
1288 operator!=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1289 -> __optional_relop_t<decltype(declval<_Tp>() != declval<_Up>())>
1290 {
1291 return static_cast<bool>(__lhs) != static_cast<bool>(__rhs)
1292 || (static_cast<bool>(__lhs) && *__lhs != *__rhs);
1293 }
1294
1295 template<typename _Tp, typename _Up>
1296 constexpr auto
1297 operator<(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1298 -> __optional_relop_t<decltype(declval<_Tp>() < declval<_Up>())>
1299 {
1300 return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
1301 }
1302
1303 template<typename _Tp, typename _Up>
1304 constexpr auto
1305 operator>(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1306 -> __optional_relop_t<decltype(declval<_Tp>() > declval<_Up>())>
1307 {
1308 return static_cast<bool>(__lhs) && (!__rhs || *__lhs > *__rhs);
1309 }
1310
1311 template<typename _Tp, typename _Up>
1312 constexpr auto
1313 operator<=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1314 -> __optional_relop_t<decltype(declval<_Tp>() <= declval<_Up>())>
1315 {
1316 return !__lhs || (static_cast<bool>(__rhs) && *__lhs <= *__rhs);
1317 }
1318
1319 template<typename _Tp, typename _Up>
1320 constexpr auto
1321 operator>=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1322 -> __optional_relop_t<decltype(declval<_Tp>() >= declval<_Up>())>
1323 {
1324 return !__rhs || (static_cast<bool>(__lhs) && *__lhs >= *__rhs);
1325 }
1326
1327 // Comparisons with nullopt.
1328 template<typename _Tp>
1329 constexpr bool
1330 operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept
1331 { return !__lhs; }
1332
1333 template<typename _Tp>
1334 constexpr bool
1335 operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept
1336 { return !__rhs; }
1337
1338 template<typename _Tp>
1339 constexpr bool
1340 operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept
1341 { return static_cast<bool>(__lhs); }
1342
1343 template<typename _Tp>
1344 constexpr bool
1345 operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept
1346 { return static_cast<bool>(__rhs); }
1347
1348 template<typename _Tp>
1349 constexpr bool
1350 operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
1351 { return false; }
1352
1353 template<typename _Tp>
1354 constexpr bool
1355 operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
1356 { return static_cast<bool>(__rhs); }
1357
1358 template<typename _Tp>
1359 constexpr bool
1360 operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept
1361 { return static_cast<bool>(__lhs); }
1362
1363 template<typename _Tp>
1364 constexpr bool
1365 operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
1366 { return false; }
1367
1368 template<typename _Tp>
1369 constexpr bool
1370 operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept
1371 { return !__lhs; }
1372
1373 template<typename _Tp>
1374 constexpr bool
1375 operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
1376 { return true; }
1377
1378 template<typename _Tp>
1379 constexpr bool
1380 operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
1381 { return true; }
1382
1383 template<typename _Tp>
1384 constexpr bool
1385 operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept
1386 { return !__rhs; }
1387
1388 // Comparisons with value type.
1389 template<typename _Tp, typename _Up>
1390 constexpr auto
1391 operator==(const optional<_Tp>& __lhs, const _Up& __rhs)
1392 -> __optional_relop_t<decltype(declval<_Tp>() == declval<_Up>())>
1393 { return __lhs && *__lhs == __rhs; }
1394
1395 template<typename _Tp, typename _Up>
1396 constexpr auto
1397 operator==(const _Up& __lhs, const optional<_Tp>& __rhs)
1398 -> __optional_relop_t<decltype(declval<_Up>() == declval<_Tp>())>
1399 { return __rhs && __lhs == *__rhs; }
1400
1401 template<typename _Tp, typename _Up>
1402 constexpr auto
1403 operator!=(const optional<_Tp>& __lhs, const _Up& __rhs)
1404 -> __optional_relop_t<decltype(declval<_Tp>() != declval<_Up>())>
1405 { return !__lhs || *__lhs != __rhs; }
1406
1407 template<typename _Tp, typename _Up>
1408 constexpr auto
1409 operator!=(const _Up& __lhs, const optional<_Tp>& __rhs)
1410 -> __optional_relop_t<decltype(declval<_Up>() != declval<_Tp>())>
1411 { return !__rhs || __lhs != *__rhs; }
1412
1413 template<typename _Tp, typename _Up>
1414 constexpr auto
1415 operator<(const optional<_Tp>& __lhs, const _Up& __rhs)
1416 -> __optional_relop_t<decltype(declval<_Tp>() < declval<_Up>())>
1417 { return !__lhs || *__lhs < __rhs; }
1418
1419 template<typename _Tp, typename _Up>
1420 constexpr auto
1421 operator<(const _Up& __lhs, const optional<_Tp>& __rhs)
1422 -> __optional_relop_t<decltype(declval<_Up>() < declval<_Tp>())>
1423 { return __rhs && __lhs < *__rhs; }
1424
1425 template<typename _Tp, typename _Up>
1426 constexpr auto
1427 operator>(const optional<_Tp>& __lhs, const _Up& __rhs)
1428 -> __optional_relop_t<decltype(declval<_Tp>() > declval<_Up>())>
1429 { return __lhs && *__lhs > __rhs; }
1430
1431 template<typename _Tp, typename _Up>
1432 constexpr auto
1433 operator>(const _Up& __lhs, const optional<_Tp>& __rhs)
1434 -> __optional_relop_t<decltype(declval<_Up>() > declval<_Tp>())>
1435 { return !__rhs || __lhs > *__rhs; }
1436
1437 template<typename _Tp, typename _Up>
1438 constexpr auto
1439 operator<=(const optional<_Tp>& __lhs, const _Up& __rhs)
1440 -> __optional_relop_t<decltype(declval<_Tp>() <= declval<_Up>())>
1441 { return !__lhs || *__lhs <= __rhs; }
1442
1443 template<typename _Tp, typename _Up>
1444 constexpr auto
1445 operator<=(const _Up& __lhs, const optional<_Tp>& __rhs)
1446 -> __optional_relop_t<decltype(declval<_Up>() <= declval<_Tp>())>
1447 { return __rhs && __lhs <= *__rhs; }
1448
1449 template<typename _Tp, typename _Up>
1450 constexpr auto
1451 operator>=(const optional<_Tp>& __lhs, const _Up& __rhs)
1452 -> __optional_relop_t<decltype(declval<_Tp>() >= declval<_Up>())>
1453 { return __lhs && *__lhs >= __rhs; }
1454
1455 template<typename _Tp, typename _Up>
1456 constexpr auto
1457 operator>=(const _Up& __lhs, const optional<_Tp>& __rhs)
1458 -> __optional_relop_t<decltype(declval<_Up>() >= declval<_Tp>())>
1459 { return !__rhs || __lhs >= *__rhs; }
1460
1461 // Swap and creation functions.
1462
1463 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1464 // 2748. swappable traits for optionals
1465 template<typename _Tp>
1466 inline enable_if_t<is_move_constructible_v<_Tp> && is_swappable_v<_Tp>>
1467 swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
1468 noexcept(noexcept(__lhs.swap(__rhs)))
1469 { __lhs.swap(__rhs); }
1470
1471 template<typename _Tp>
1472 enable_if_t<!(is_move_constructible_v<_Tp> && is_swappable_v<_Tp>)>
1473 swap(optional<_Tp>&, optional<_Tp>&) = delete;
1474
1475 template<typename _Tp>
1476 constexpr optional<decay_t<_Tp>>
1477 make_optional(_Tp&& __t)
1478 { return optional<decay_t<_Tp>> { std::forward<_Tp>(__t) }; }
1479
1480 template<typename _Tp, typename ..._Args>
1481 constexpr optional<_Tp>
1482 make_optional(_Args&&... __args)
1483 { return optional<_Tp> { in_place, std::forward<_Args>(__args)... }; }
1484
1485 template<typename _Tp, typename _Up, typename ..._Args>
1486 constexpr optional<_Tp>
1487 make_optional(initializer_list<_Up> __il, _Args&&... __args)
1488 { return optional<_Tp> { in_place, __il, std::forward<_Args>(__args)... }; }
1489
1490 // Hash.
1491
1492 template<typename _Tp, typename _Up = remove_const_t<_Tp>,
1493 bool = __poison_hash<_Up>::__enable_hash_call>
1494 struct __optional_hash_call_base
1495 {
1496 size_t
1497 operator()(const optional<_Tp>& __t) const
1498 noexcept(noexcept(hash<_Up>{}(*__t)))
1499 {
1500 // We pick an arbitrary hash for disengaged optionals which hopefully
1501 // usual values of _Tp won't typically hash to.
1502 constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333);
1503 return __t ? hash<_Up>{}(*__t) : __magic_disengaged_hash;
1504 }
1505 };
1506
1507 template<typename _Tp, typename _Up>
1508 struct __optional_hash_call_base<_Tp, _Up, false> {};
1509
1510 template<typename _Tp>
1511 struct hash<optional<_Tp>>
1512 : private __poison_hash<remove_const_t<_Tp>>,
1513 public __optional_hash_call_base<_Tp>
1514 {
1515 using result_type [[__deprecated__]] = size_t;
1516 using argument_type [[__deprecated__]] = optional<_Tp>;
1517 };
1518
1519 template<typename _Tp>
1520 struct __is_fast_hash<hash<optional<_Tp>>> : __is_fast_hash<hash<_Tp>>
1521 { };
1522
1523 /// @}
1524
1525#if __cpp_deduction_guides >= 201606
1526 template <typename _Tp> optional(_Tp) -> optional<_Tp>;
1527#endif
1528
1529_GLIBCXX_END_NAMESPACE_VERSION
1530} // namespace std
1531
1532#endif // C++17
1533
1534#endif // _GLIBCXX_OPTIONAL
1535