1 // <optional> -*- C++ -*-
3 // Copyright (C) 2013-2020 Free Software Foundation, Inc.
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)
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.
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.
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/>.
25 /** @file include/optional
26 * This is a Standard C++ Library header.
29 #ifndef _GLIBCXX_OPTIONAL
30 #define _GLIBCXX_OPTIONAL 1
32 #pragma GCC system_header
34 #if __cplusplus >= 201703L
37 #include <type_traits>
40 #include <initializer_list>
41 #include <bits/exception_defines.h>
42 #include <bits/functional_hash.h>
43 #include <bits/enable_special_members.h>
45 namespace std _GLIBCXX_VISIBILITY(default)
47 _GLIBCXX_BEGIN_NAMESPACE_VERSION
50 * @addtogroup utilities
54 #define __cpp_lib_optional 201606L
56 template<typename _Tp>
59 /// Tag type to disengage optional objects.
62 // Do not user-declare default constructor at all for
63 // optional_value = {} syntax to work.
64 // nullopt_t() = delete;
66 // Used for constructing nullopt.
67 enum class _Construct { _Token };
69 // Must be constexpr for nullopt_t to be literal.
70 explicit constexpr nullopt_t(_Construct) { }
73 /// Tag to disengage optional objects.
74 inline constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token };
77 * @brief Exception class thrown when a disengaged optional object is
81 class bad_optional_access : public exception
84 bad_optional_access() { }
86 virtual const char* what() const noexcept override
87 { return "bad optional access"; }
89 virtual ~bad_optional_access() noexcept = default;
93 __throw_bad_optional_access()
94 __attribute__((__noreturn__));
96 // XXX Does not belong here.
98 __throw_bad_optional_access()
99 { _GLIBCXX_THROW_OR_ABORT(bad_optional_access()); }
101 // This class template manages construction/destruction of
102 // the contained value for a std::optional.
103 template <typename _Tp>
104 struct _Optional_payload_base
106 using _Stored_type = remove_const_t<_Tp>;
108 _Optional_payload_base() = default;
109 ~_Optional_payload_base() = default;
111 template<typename... _Args>
113 _Optional_payload_base(in_place_t __tag, _Args&&... __args)
114 : _M_payload(__tag, std::forward<_Args>(__args)...),
118 template<typename _Up, typename... _Args>
120 _Optional_payload_base(std::initializer_list<_Up> __il,
122 : _M_payload(__il, std::forward<_Args>(__args)...),
126 // Constructor used by _Optional_base copy constructor when the
127 // contained value is not trivially copy constructible.
129 _Optional_payload_base(bool __engaged,
130 const _Optional_payload_base& __other)
132 if (__other._M_engaged)
133 this->_M_construct(__other._M_get());
136 // Constructor used by _Optional_base move constructor when the
137 // contained value is not trivially move constructible.
139 _Optional_payload_base(bool __engaged,
140 _Optional_payload_base&& __other)
142 if (__other._M_engaged)
143 this->_M_construct(std::move(__other._M_get()));
146 // Copy constructor is only used to when the contained value is
147 // trivially copy constructible.
148 _Optional_payload_base(const _Optional_payload_base&) = default;
150 // Move constructor is only used to when the contained value is
151 // trivially copy constructible.
152 _Optional_payload_base(_Optional_payload_base&&) = default;
154 _Optional_payload_base&
155 operator=(const _Optional_payload_base&) = default;
157 _Optional_payload_base&
158 operator=(_Optional_payload_base&&) = default;
160 // used to perform non-trivial copy assignment.
162 _M_copy_assign(const _Optional_payload_base& __other)
164 if (this->_M_engaged && __other._M_engaged)
165 this->_M_get() = __other._M_get();
168 if (__other._M_engaged)
169 this->_M_construct(__other._M_get());
175 // used to perform non-trivial move assignment.
177 _M_move_assign(_Optional_payload_base&& __other)
178 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
179 is_nothrow_move_assignable<_Tp>>)
181 if (this->_M_engaged && __other._M_engaged)
182 this->_M_get() = std::move(__other._M_get());
185 if (__other._M_engaged)
186 this->_M_construct(std::move(__other._M_get()));
192 struct _Empty_byte { };
194 template<typename _Up, bool = is_trivially_destructible_v<_Up>>
197 constexpr _Storage() noexcept : _M_empty() { }
199 template<typename... _Args>
201 _Storage(in_place_t, _Args&&... __args)
202 : _M_value(std::forward<_Args>(__args)...)
205 template<typename _Vp, typename... _Args>
207 _Storage(std::initializer_list<_Vp> __il, _Args&&... __args)
208 : _M_value(__il, std::forward<_Args>(__args)...)
211 _Empty_byte _M_empty;
215 template<typename _Up>
216 union _Storage<_Up, false>
218 constexpr _Storage() noexcept : _M_empty() { }
220 template<typename... _Args>
222 _Storage(in_place_t, _Args&&... __args)
223 : _M_value(std::forward<_Args>(__args)...)
226 template<typename _Vp, typename... _Args>
228 _Storage(std::initializer_list<_Vp> __il, _Args&&... __args)
229 : _M_value(__il, std::forward<_Args>(__args)...)
232 // User-provided destructor is needed when _Up has non-trivial dtor.
235 _Empty_byte _M_empty;
239 _Storage<_Stored_type> _M_payload;
241 bool _M_engaged = false;
243 template<typename... _Args>
245 _M_construct(_Args&&... __args)
246 noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
248 ::new ((void *) std::__addressof(this->_M_payload))
249 _Stored_type(std::forward<_Args>(__args)...);
250 this->_M_engaged = true;
254 _M_destroy() noexcept
257 _M_payload._M_value.~_Stored_type();
260 // The _M_get() operations have _M_engaged as a precondition.
261 // They exist to access the contained value with the appropriate
262 // const-qualification, because _M_payload has had the const removed.
266 { return this->_M_payload._M_value; }
269 _M_get() const noexcept
270 { return this->_M_payload._M_value; }
272 // _M_reset is a 'safe' operation with no precondition.
276 if (this->_M_engaged)
281 // Class template that manages the payload for optionals.
282 template <typename _Tp,
283 bool /*_HasTrivialDestructor*/ =
284 is_trivially_destructible_v<_Tp>,
285 bool /*_HasTrivialCopy */ =
286 is_trivially_copy_assignable_v<_Tp>
287 && is_trivially_copy_constructible_v<_Tp>,
288 bool /*_HasTrivialMove */ =
289 is_trivially_move_assignable_v<_Tp>
290 && is_trivially_move_constructible_v<_Tp>>
291 struct _Optional_payload;
293 // Payload for potentially-constexpr optionals (trivial copy/move/destroy).
294 template <typename _Tp>
295 struct _Optional_payload<_Tp, true, true, true>
296 : _Optional_payload_base<_Tp>
298 using _Optional_payload_base<_Tp>::_Optional_payload_base;
300 _Optional_payload() = default;
303 // Payload for optionals with non-trivial copy construction/assignment.
304 template <typename _Tp>
305 struct _Optional_payload<_Tp, true, false, true>
306 : _Optional_payload_base<_Tp>
308 using _Optional_payload_base<_Tp>::_Optional_payload_base;
310 _Optional_payload() = default;
311 ~_Optional_payload() = default;
312 _Optional_payload(const _Optional_payload&) = default;
313 _Optional_payload(_Optional_payload&&) = default;
314 _Optional_payload& operator=(_Optional_payload&&) = default;
316 // Non-trivial copy assignment.
319 operator=(const _Optional_payload& __other)
321 this->_M_copy_assign(__other);
326 // Payload for optionals with non-trivial move construction/assignment.
327 template <typename _Tp>
328 struct _Optional_payload<_Tp, true, true, false>
329 : _Optional_payload_base<_Tp>
331 using _Optional_payload_base<_Tp>::_Optional_payload_base;
333 _Optional_payload() = default;
334 ~_Optional_payload() = default;
335 _Optional_payload(const _Optional_payload&) = default;
336 _Optional_payload(_Optional_payload&&) = default;
337 _Optional_payload& operator=(const _Optional_payload&) = default;
339 // Non-trivial move assignment.
342 operator=(_Optional_payload&& __other)
343 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
344 is_nothrow_move_assignable<_Tp>>)
346 this->_M_move_assign(std::move(__other));
351 // Payload for optionals with non-trivial copy and move assignment.
352 template <typename _Tp>
353 struct _Optional_payload<_Tp, true, false, false>
354 : _Optional_payload_base<_Tp>
356 using _Optional_payload_base<_Tp>::_Optional_payload_base;
358 _Optional_payload() = default;
359 ~_Optional_payload() = default;
360 _Optional_payload(const _Optional_payload&) = default;
361 _Optional_payload(_Optional_payload&&) = default;
363 // Non-trivial copy assignment.
366 operator=(const _Optional_payload& __other)
368 this->_M_copy_assign(__other);
372 // Non-trivial move assignment.
375 operator=(_Optional_payload&& __other)
376 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
377 is_nothrow_move_assignable<_Tp>>)
379 this->_M_move_assign(std::move(__other));
384 // Payload for optionals with non-trivial destructors.
385 template <typename _Tp, bool _Copy, bool _Move>
386 struct _Optional_payload<_Tp, false, _Copy, _Move>
387 : _Optional_payload<_Tp, true, false, false>
389 // Base class implements all the constructors and assignment operators:
390 using _Optional_payload<_Tp, true, false, false>::_Optional_payload;
391 _Optional_payload() = default;
392 _Optional_payload(const _Optional_payload&) = default;
393 _Optional_payload(_Optional_payload&&) = default;
394 _Optional_payload& operator=(const _Optional_payload&) = default;
395 _Optional_payload& operator=(_Optional_payload&&) = default;
397 // Destructor needs to destroy the contained value:
398 ~_Optional_payload() { this->_M_reset(); }
401 // Common base class for _Optional_base<T> to avoid repeating these
402 // member functions in each specialization.
403 template<typename _Tp, typename _Dp>
404 class _Optional_base_impl
407 using _Stored_type = remove_const_t<_Tp>;
409 // The _M_construct operation has !_M_engaged as a precondition
410 // while _M_destruct has _M_engaged as a precondition.
411 template<typename... _Args>
413 _M_construct(_Args&&... __args)
414 noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
417 (std::__addressof(static_cast<_Dp*>(this)->_M_payload._M_payload))
418 _Stored_type(std::forward<_Args>(__args)...);
419 static_cast<_Dp*>(this)->_M_payload._M_engaged = true;
423 _M_destruct() noexcept
424 { static_cast<_Dp*>(this)->_M_payload._M_destroy(); }
426 // _M_reset is a 'safe' operation with no precondition.
429 { static_cast<_Dp*>(this)->_M_payload._M_reset(); }
431 constexpr bool _M_is_engaged() const noexcept
432 { return static_cast<const _Dp*>(this)->_M_payload._M_engaged; }
434 // The _M_get operations have _M_engaged as a precondition.
438 __glibcxx_assert(this->_M_is_engaged());
439 return static_cast<_Dp*>(this)->_M_payload._M_get();
443 _M_get() const noexcept
445 __glibcxx_assert(this->_M_is_engaged());
446 return static_cast<const _Dp*>(this)->_M_payload._M_get();
451 * @brief Class template that provides copy/move constructors of optional.
453 * Such a separate base class template is necessary in order to
454 * conditionally make copy/move constructors trivial.
456 * When the contained value is trivally copy/move constructible,
457 * the copy/move constructors of _Optional_base will invoke the
458 * trivial copy/move constructor of _Optional_payload. Otherwise,
459 * they will invoke _Optional_payload(bool, const _Optional_payload&)
460 * or _Optional_payload(bool, _Optional_payload&&) to initialize
461 * the contained value, if copying/moving an engaged optional.
463 * Whether the other special members are trivial is determined by the
464 * _Optional_payload<_Tp> specialization used for the _M_payload member.
466 * @see optional, _Enable_special_members
468 template<typename _Tp,
469 bool = is_trivially_copy_constructible_v<_Tp>,
470 bool = is_trivially_move_constructible_v<_Tp>>
471 struct _Optional_base
472 : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
474 // Constructors for disengaged optionals.
475 constexpr _Optional_base() = default;
477 // Constructors for engaged optionals.
478 template<typename... _Args,
479 enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
480 constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
481 : _M_payload(in_place,
482 std::forward<_Args>(__args)...) { }
484 template<typename _Up, typename... _Args,
485 enable_if_t<is_constructible_v<_Tp,
486 initializer_list<_Up>&,
487 _Args&&...>, bool> = false>
488 constexpr explicit _Optional_base(in_place_t,
489 initializer_list<_Up> __il,
491 : _M_payload(in_place,
492 __il, std::forward<_Args>(__args)...)
495 // Copy and move constructors.
496 constexpr _Optional_base(const _Optional_base& __other)
497 : _M_payload(__other._M_payload._M_engaged,
501 constexpr _Optional_base(_Optional_base&& __other)
502 noexcept(is_nothrow_move_constructible_v<_Tp>)
503 : _M_payload(__other._M_payload._M_engaged,
504 std::move(__other._M_payload))
507 // Assignment operators.
508 _Optional_base& operator=(const _Optional_base&) = default;
509 _Optional_base& operator=(_Optional_base&&) = default;
511 _Optional_payload<_Tp> _M_payload;
514 template<typename _Tp>
515 struct _Optional_base<_Tp, false, true>
516 : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
518 // Constructors for disengaged optionals.
519 constexpr _Optional_base() = default;
521 // Constructors for engaged optionals.
522 template<typename... _Args,
523 enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
524 constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
525 : _M_payload(in_place,
526 std::forward<_Args>(__args)...) { }
528 template<typename _Up, typename... _Args,
529 enable_if_t<is_constructible_v<_Tp,
530 initializer_list<_Up>&,
531 _Args&&...>, bool> = false>
532 constexpr explicit _Optional_base(in_place_t,
533 initializer_list<_Up> __il,
535 : _M_payload(in_place,
536 __il, std::forward<_Args>(__args)...)
539 // Copy and move constructors.
540 constexpr _Optional_base(const _Optional_base& __other)
541 : _M_payload(__other._M_payload._M_engaged,
545 constexpr _Optional_base(_Optional_base&& __other) = default;
547 // Assignment operators.
548 _Optional_base& operator=(const _Optional_base&) = default;
549 _Optional_base& operator=(_Optional_base&&) = default;
551 _Optional_payload<_Tp> _M_payload;
554 template<typename _Tp>
555 struct _Optional_base<_Tp, true, false>
556 : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
558 // Constructors for disengaged optionals.
559 constexpr _Optional_base() = default;
561 // Constructors for engaged optionals.
562 template<typename... _Args,
563 enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
564 constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
565 : _M_payload(in_place,
566 std::forward<_Args>(__args)...) { }
568 template<typename _Up, typename... _Args,
569 enable_if_t<is_constructible_v<_Tp,
570 initializer_list<_Up>&,
571 _Args&&...>, bool> = false>
572 constexpr explicit _Optional_base(in_place_t,
573 initializer_list<_Up> __il,
575 : _M_payload(in_place,
576 __il, std::forward<_Args>(__args)...)
579 // Copy and move constructors.
580 constexpr _Optional_base(const _Optional_base& __other) = default;
582 constexpr _Optional_base(_Optional_base&& __other)
583 noexcept(is_nothrow_move_constructible_v<_Tp>)
584 : _M_payload(__other._M_payload._M_engaged,
585 std::move(__other._M_payload))
588 // Assignment operators.
589 _Optional_base& operator=(const _Optional_base&) = default;
590 _Optional_base& operator=(_Optional_base&&) = default;
592 _Optional_payload<_Tp> _M_payload;
595 template<typename _Tp>
596 struct _Optional_base<_Tp, true, true>
597 : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
599 // Constructors for disengaged optionals.
600 constexpr _Optional_base() = default;
602 // Constructors for engaged optionals.
603 template<typename... _Args,
604 enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
605 constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
606 : _M_payload(in_place,
607 std::forward<_Args>(__args)...) { }
609 template<typename _Up, typename... _Args,
610 enable_if_t<is_constructible_v<_Tp,
611 initializer_list<_Up>&,
612 _Args&&...>, bool> = false>
613 constexpr explicit _Optional_base(in_place_t,
614 initializer_list<_Up> __il,
616 : _M_payload(in_place,
617 __il, std::forward<_Args>(__args)...)
620 // Copy and move constructors.
621 constexpr _Optional_base(const _Optional_base& __other) = default;
622 constexpr _Optional_base(_Optional_base&& __other) = default;
624 // Assignment operators.
625 _Optional_base& operator=(const _Optional_base&) = default;
626 _Optional_base& operator=(_Optional_base&&) = default;
628 _Optional_payload<_Tp> _M_payload;
631 template<typename _Tp>
634 template<typename _Tp, typename _Up>
635 using __converts_from_optional =
636 __or_<is_constructible<_Tp, const optional<_Up>&>,
637 is_constructible<_Tp, optional<_Up>&>,
638 is_constructible<_Tp, const optional<_Up>&&>,
639 is_constructible<_Tp, optional<_Up>&&>,
640 is_convertible<const optional<_Up>&, _Tp>,
641 is_convertible<optional<_Up>&, _Tp>,
642 is_convertible<const optional<_Up>&&, _Tp>,
643 is_convertible<optional<_Up>&&, _Tp>>;
645 template<typename _Tp, typename _Up>
646 using __assigns_from_optional =
647 __or_<is_assignable<_Tp&, const optional<_Up>&>,
648 is_assignable<_Tp&, optional<_Up>&>,
649 is_assignable<_Tp&, const optional<_Up>&&>,
650 is_assignable<_Tp&, optional<_Up>&&>>;
653 * @brief Class template for optional values.
655 template<typename _Tp>
657 : private _Optional_base<_Tp>,
658 private _Enable_copy_move<
660 is_copy_constructible_v<_Tp>,
662 __and_v<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>,
664 is_move_constructible_v<_Tp>,
666 __and_v<is_move_constructible<_Tp>, is_move_assignable<_Tp>>,
670 static_assert(!is_same_v<remove_cv_t<_Tp>, nullopt_t>);
671 static_assert(!is_same_v<remove_cv_t<_Tp>, in_place_t>);
672 static_assert(!is_reference_v<_Tp>);
675 using _Base = _Optional_base<_Tp>;
678 template<typename _Up>
679 using __not_self = __not_<is_same<optional, __remove_cvref_t<_Up>>>;
680 template<typename _Up>
681 using __not_tag = __not_<is_same<in_place_t, __remove_cvref_t<_Up>>>;
682 template<typename... _Cond>
683 using _Requires = enable_if_t<__and_v<_Cond...>, bool>;
686 using value_type = _Tp;
688 constexpr optional() = default;
690 constexpr optional(nullopt_t) noexcept { }
692 // Converting constructors for engaged optionals.
693 template<typename _Up = _Tp,
694 _Requires<__not_self<_Up>, __not_tag<_Up>,
695 is_constructible<_Tp, _Up&&>,
696 is_convertible<_Up&&, _Tp>> = true>
699 : _Base(std::in_place, std::forward<_Up>(__t)) { }
701 template<typename _Up = _Tp,
702 _Requires<__not_self<_Up>, __not_tag<_Up>,
703 is_constructible<_Tp, _Up&&>,
704 __not_<is_convertible<_Up&&, _Tp>>> = false>
707 : _Base(std::in_place, std::forward<_Up>(__t)) { }
709 template<typename _Up,
710 _Requires<__not_<is_same<_Tp, _Up>>,
711 is_constructible<_Tp, const _Up&>,
712 is_convertible<const _Up&, _Tp>,
713 __not_<__converts_from_optional<_Tp, _Up>>> = true>
715 optional(const optional<_Up>& __t)
721 template<typename _Up,
722 _Requires<__not_<is_same<_Tp, _Up>>,
723 is_constructible<_Tp, const _Up&>,
724 __not_<is_convertible<const _Up&, _Tp>>,
725 __not_<__converts_from_optional<_Tp, _Up>>> = false>
727 optional(const optional<_Up>& __t)
733 template <typename _Up,
734 _Requires<__not_<is_same<_Tp, _Up>>,
735 is_constructible<_Tp, _Up&&>,
736 is_convertible<_Up&&, _Tp>,
737 __not_<__converts_from_optional<_Tp, _Up>>> = true>
739 optional(optional<_Up>&& __t)
742 emplace(std::move(*__t));
745 template <typename _Up,
746 _Requires<__not_<is_same<_Tp, _Up>>,
747 is_constructible<_Tp, _Up&&>,
748 __not_<is_convertible<_Up&&, _Tp>>,
749 __not_<__converts_from_optional<_Tp, _Up>>> = false>
751 optional(optional<_Up>&& __t)
754 emplace(std::move(*__t));
757 template<typename... _Args,
758 _Requires<is_constructible<_Tp, _Args&&...>> = false>
760 optional(in_place_t, _Args&&... __args)
761 : _Base(std::in_place, std::forward<_Args>(__args)...) { }
763 template<typename _Up, typename... _Args,
764 _Requires<is_constructible<_Tp,
765 initializer_list<_Up>&,
766 _Args&&...>> = false>
768 optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
769 : _Base(std::in_place, __il, std::forward<_Args>(__args)...) { }
771 // Assignment operators.
773 operator=(nullopt_t) noexcept
779 template<typename _Up = _Tp>
780 enable_if_t<__and_v<__not_self<_Up>,
781 __not_<__and_<is_scalar<_Tp>,
782 is_same<_Tp, decay_t<_Up>>>>,
783 is_constructible<_Tp, _Up>,
784 is_assignable<_Tp&, _Up>>,
788 if (this->_M_is_engaged())
789 this->_M_get() = std::forward<_Up>(__u);
791 this->_M_construct(std::forward<_Up>(__u));
796 template<typename _Up>
797 enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
798 is_constructible<_Tp, const _Up&>,
799 is_assignable<_Tp&, _Up>,
800 __not_<__converts_from_optional<_Tp, _Up>>,
801 __not_<__assigns_from_optional<_Tp, _Up>>>,
803 operator=(const optional<_Up>& __u)
807 if (this->_M_is_engaged())
808 this->_M_get() = *__u;
810 this->_M_construct(*__u);
819 template<typename _Up>
820 enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
821 is_constructible<_Tp, _Up>,
822 is_assignable<_Tp&, _Up>,
823 __not_<__converts_from_optional<_Tp, _Up>>,
824 __not_<__assigns_from_optional<_Tp, _Up>>>,
826 operator=(optional<_Up>&& __u)
830 if (this->_M_is_engaged())
831 this->_M_get() = std::move(*__u);
833 this->_M_construct(std::move(*__u));
843 template<typename... _Args>
844 enable_if_t<is_constructible_v<_Tp, _Args&&...>, _Tp&>
845 emplace(_Args&&... __args)
848 this->_M_construct(std::forward<_Args>(__args)...);
849 return this->_M_get();
852 template<typename _Up, typename... _Args>
853 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&,
855 emplace(initializer_list<_Up> __il, _Args&&... __args)
858 this->_M_construct(__il, std::forward<_Args>(__args)...);
859 return this->_M_get();
862 // Destructor is implicit, implemented in _Optional_base.
866 swap(optional& __other)
867 noexcept(is_nothrow_move_constructible_v<_Tp>
868 && is_nothrow_swappable_v<_Tp>)
872 if (this->_M_is_engaged() && __other._M_is_engaged())
873 swap(this->_M_get(), __other._M_get());
874 else if (this->_M_is_engaged())
876 __other._M_construct(std::move(this->_M_get()));
879 else if (__other._M_is_engaged())
881 this->_M_construct(std::move(__other._M_get()));
882 __other._M_destruct();
889 { return std::__addressof(this->_M_get()); }
893 { return std::__addressof(this->_M_get()); }
897 { return this->_M_get(); }
901 { return this->_M_get(); }
905 { return std::move(this->_M_get()); }
907 constexpr const _Tp&&
909 { return std::move(this->_M_get()); }
911 constexpr explicit operator bool() const noexcept
912 { return this->_M_is_engaged(); }
914 constexpr bool has_value() const noexcept
915 { return this->_M_is_engaged(); }
920 return this->_M_is_engaged()
922 : (__throw_bad_optional_access(), this->_M_get());
928 return this->_M_is_engaged()
930 : (__throw_bad_optional_access(), this->_M_get());
936 return this->_M_is_engaged()
937 ? std::move(this->_M_get())
938 : (__throw_bad_optional_access(), std::move(this->_M_get()));
941 constexpr const _Tp&&
944 return this->_M_is_engaged()
945 ? std::move(this->_M_get())
946 : (__throw_bad_optional_access(), std::move(this->_M_get()));
949 template<typename _Up>
951 value_or(_Up&& __u) const&
953 static_assert(is_copy_constructible_v<_Tp>);
954 static_assert(is_convertible_v<_Up&&, _Tp>);
956 return this->_M_is_engaged()
957 ? this->_M_get() : static_cast<_Tp>(std::forward<_Up>(__u));
960 template<typename _Up>
962 value_or(_Up&& __u) &&
964 static_assert(is_move_constructible_v<_Tp>);
965 static_assert(is_convertible_v<_Up&&, _Tp>);
967 return this->_M_is_engaged()
968 ? std::move(this->_M_get())
969 : static_cast<_Tp>(std::forward<_Up>(__u));
972 void reset() noexcept { this->_M_reset(); }
975 template<typename _Tp>
976 using __optional_relop_t =
977 enable_if_t<is_convertible<_Tp, bool>::value, bool>;
979 // Comparisons between optional values.
980 template<typename _Tp, typename _Up>
982 operator==(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
983 -> __optional_relop_t<decltype(declval<_Tp>() == declval<_Up>())>
985 return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
986 && (!__lhs || *__lhs == *__rhs);
989 template<typename _Tp, typename _Up>
991 operator!=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
992 -> __optional_relop_t<decltype(declval<_Tp>() != declval<_Up>())>
994 return static_cast<bool>(__lhs) != static_cast<bool>(__rhs)
995 || (static_cast<bool>(__lhs) && *__lhs != *__rhs);
998 template<typename _Tp, typename _Up>
1000 operator<(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1001 -> __optional_relop_t<decltype(declval<_Tp>() < declval<_Up>())>
1003 return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
1006 template<typename _Tp, typename _Up>
1008 operator>(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1009 -> __optional_relop_t<decltype(declval<_Tp>() > declval<_Up>())>
1011 return static_cast<bool>(__lhs) && (!__rhs || *__lhs > *__rhs);
1014 template<typename _Tp, typename _Up>
1016 operator<=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1017 -> __optional_relop_t<decltype(declval<_Tp>() <= declval<_Up>())>
1019 return !__lhs || (static_cast<bool>(__rhs) && *__lhs <= *__rhs);
1022 template<typename _Tp, typename _Up>
1024 operator>=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1025 -> __optional_relop_t<decltype(declval<_Tp>() >= declval<_Up>())>
1027 return !__rhs || (static_cast<bool>(__lhs) && *__lhs >= *__rhs);
1030 // Comparisons with nullopt.
1031 template<typename _Tp>
1033 operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept
1036 template<typename _Tp>
1038 operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept
1041 template<typename _Tp>
1043 operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept
1044 { return static_cast<bool>(__lhs); }
1046 template<typename _Tp>
1048 operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept
1049 { return static_cast<bool>(__rhs); }
1051 template<typename _Tp>
1053 operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
1056 template<typename _Tp>
1058 operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
1059 { return static_cast<bool>(__rhs); }
1061 template<typename _Tp>
1063 operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept
1064 { return static_cast<bool>(__lhs); }
1066 template<typename _Tp>
1068 operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
1071 template<typename _Tp>
1073 operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept
1076 template<typename _Tp>
1078 operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
1081 template<typename _Tp>
1083 operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
1086 template<typename _Tp>
1088 operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept
1091 // Comparisons with value type.
1092 template<typename _Tp, typename _Up>
1094 operator==(const optional<_Tp>& __lhs, const _Up& __rhs)
1095 -> __optional_relop_t<decltype(declval<_Tp>() == declval<_Up>())>
1096 { return __lhs && *__lhs == __rhs; }
1098 template<typename _Tp, typename _Up>
1100 operator==(const _Up& __lhs, const optional<_Tp>& __rhs)
1101 -> __optional_relop_t<decltype(declval<_Up>() == declval<_Tp>())>
1102 { return __rhs && __lhs == *__rhs; }
1104 template<typename _Tp, typename _Up>
1106 operator!=(const optional<_Tp>& __lhs, const _Up& __rhs)
1107 -> __optional_relop_t<decltype(declval<_Tp>() != declval<_Up>())>
1108 { return !__lhs || *__lhs != __rhs; }
1110 template<typename _Tp, typename _Up>
1112 operator!=(const _Up& __lhs, const optional<_Tp>& __rhs)
1113 -> __optional_relop_t<decltype(declval<_Up>() != declval<_Tp>())>
1114 { return !__rhs || __lhs != *__rhs; }
1116 template<typename _Tp, typename _Up>
1118 operator<(const optional<_Tp>& __lhs, const _Up& __rhs)
1119 -> __optional_relop_t<decltype(declval<_Tp>() < declval<_Up>())>
1120 { return !__lhs || *__lhs < __rhs; }
1122 template<typename _Tp, typename _Up>
1124 operator<(const _Up& __lhs, const optional<_Tp>& __rhs)
1125 -> __optional_relop_t<decltype(declval<_Up>() < declval<_Tp>())>
1126 { return __rhs && __lhs < *__rhs; }
1128 template<typename _Tp, typename _Up>
1130 operator>(const optional<_Tp>& __lhs, const _Up& __rhs)
1131 -> __optional_relop_t<decltype(declval<_Tp>() > declval<_Up>())>
1132 { return __lhs && *__lhs > __rhs; }
1134 template<typename _Tp, typename _Up>
1136 operator>(const _Up& __lhs, const optional<_Tp>& __rhs)
1137 -> __optional_relop_t<decltype(declval<_Up>() > declval<_Tp>())>
1138 { return !__rhs || __lhs > *__rhs; }
1140 template<typename _Tp, typename _Up>
1142 operator<=(const optional<_Tp>& __lhs, const _Up& __rhs)
1143 -> __optional_relop_t<decltype(declval<_Tp>() <= declval<_Up>())>
1144 { return !__lhs || *__lhs <= __rhs; }
1146 template<typename _Tp, typename _Up>
1148 operator<=(const _Up& __lhs, const optional<_Tp>& __rhs)
1149 -> __optional_relop_t<decltype(declval<_Up>() <= declval<_Tp>())>
1150 { return __rhs && __lhs <= *__rhs; }
1152 template<typename _Tp, typename _Up>
1154 operator>=(const optional<_Tp>& __lhs, const _Up& __rhs)
1155 -> __optional_relop_t<decltype(declval<_Tp>() >= declval<_Up>())>
1156 { return __lhs && *__lhs >= __rhs; }
1158 template<typename _Tp, typename _Up>
1160 operator>=(const _Up& __lhs, const optional<_Tp>& __rhs)
1161 -> __optional_relop_t<decltype(declval<_Up>() >= declval<_Tp>())>
1162 { return !__rhs || __lhs >= *__rhs; }
1164 // Swap and creation functions.
1166 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1167 // 2748. swappable traits for optionals
1168 template<typename _Tp>
1169 inline enable_if_t<is_move_constructible_v<_Tp> && is_swappable_v<_Tp>>
1170 swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
1171 noexcept(noexcept(__lhs.swap(__rhs)))
1172 { __lhs.swap(__rhs); }
1174 template<typename _Tp>
1175 enable_if_t<!(is_move_constructible_v<_Tp> && is_swappable_v<_Tp>)>
1176 swap(optional<_Tp>&, optional<_Tp>&) = delete;
1178 template<typename _Tp>
1179 constexpr optional<decay_t<_Tp>>
1180 make_optional(_Tp&& __t)
1181 { return optional<decay_t<_Tp>> { std::forward<_Tp>(__t) }; }
1183 template<typename _Tp, typename ..._Args>
1184 constexpr optional<_Tp>
1185 make_optional(_Args&&... __args)
1186 { return optional<_Tp> { in_place, std::forward<_Args>(__args)... }; }
1188 template<typename _Tp, typename _Up, typename ..._Args>
1189 constexpr optional<_Tp>
1190 make_optional(initializer_list<_Up> __il, _Args&&... __args)
1191 { return optional<_Tp> { in_place, __il, std::forward<_Args>(__args)... }; }
1195 template<typename _Tp, typename _Up = remove_const_t<_Tp>,
1196 bool = __poison_hash<_Up>::__enable_hash_call>
1197 struct __optional_hash_call_base
1200 operator()(const optional<_Tp>& __t) const
1201 noexcept(noexcept(hash<_Up>{}(*__t)))
1203 // We pick an arbitrary hash for disengaged optionals which hopefully
1204 // usual values of _Tp won't typically hash to.
1205 constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333);
1206 return __t ? hash<_Up>{}(*__t) : __magic_disengaged_hash;
1210 template<typename _Tp, typename _Up>
1211 struct __optional_hash_call_base<_Tp, _Up, false> {};
1213 template<typename _Tp>
1214 struct hash<optional<_Tp>>
1215 : private __poison_hash<remove_const_t<_Tp>>,
1216 public __optional_hash_call_base<_Tp>
1218 using result_type [[__deprecated__]] = size_t;
1219 using argument_type [[__deprecated__]] = optional<_Tp>;
1222 template<typename _Tp>
1223 struct __is_fast_hash<hash<optional<_Tp>>> : __is_fast_hash<hash<_Tp>>
1228 #if __cpp_deduction_guides >= 201606
1229 template <typename _Tp> optional(_Tp) -> optional<_Tp>;
1232 _GLIBCXX_END_NAMESPACE_VERSION
1237 #endif // _GLIBCXX_OPTIONAL