1// <optional> -*- C++ -*-
2
3// Copyright (C) 2013-2019 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 201606L
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 // This class template manages construction/destruction of
102 // the contained value for a std::optional.
103 template <typename _Tp>
104 struct _Optional_payload_base
105 {
106 using _Stored_type = remove_const_t<_Tp>;
107
108 _Optional_payload_base() = default;
109 ~_Optional_payload_base() = default;
110
111 template<typename... _Args>
112 constexpr
113 _Optional_payload_base(in_place_t __tag, _Args&&... __args)
114 : _M_payload(__tag, std::forward<_Args>(__args)...),
115 _M_engaged(true)
116 { }
117
118 template<typename _Up, typename... _Args>
119 constexpr
120 _Optional_payload_base(std::initializer_list<_Up> __il,
121 _Args&&... __args)
122 : _M_payload(__il, std::forward<_Args>(__args)...),
123 _M_engaged(true)
124 { }
125
126 // Constructor used by _Optional_base copy constructor when the
127 // contained value is not trivially copy constructible.
128 constexpr
129 _Optional_payload_base(bool __engaged,
130 const _Optional_payload_base& __other)
131 {
132 if (__other._M_engaged)
133 this->_M_construct(__other._M_get());
134 }
135
136 // Constructor used by _Optional_base move constructor when the
137 // contained value is not trivially move constructible.
138 constexpr
139 _Optional_payload_base(bool __engaged,
140 _Optional_payload_base&& __other)
141 {
142 if (__other._M_engaged)
143 this->_M_construct(std::move(__other._M_get()));
144 }
145
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;
149
150 // Move constructor is only used to when the contained value is
151 // trivially copy constructible.
152 _Optional_payload_base(_Optional_payload_base&&) = default;
153
154 _Optional_payload_base&
155 operator=(const _Optional_payload_base&) = default;
156
157 _Optional_payload_base&
158 operator=(_Optional_payload_base&&) = default;
159
160 // used to perform non-trivial copy assignment.
161 constexpr void
162 _M_copy_assign(const _Optional_payload_base& __other)
163 {
164 if (this->_M_engaged && __other._M_engaged)
165 this->_M_get() = __other._M_get();
166 else
167 {
168 if (__other._M_engaged)
169 this->_M_construct(__other._M_get());
170 else
171 this->_M_reset();
172 }
173 }
174
175 // used to perform non-trivial move assignment.
176 constexpr void
177 _M_move_assign(_Optional_payload_base&& __other)
178 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
179 is_nothrow_move_assignable<_Tp>>)
180 {
181 if (this->_M_engaged && __other._M_engaged)
182 this->_M_get() = std::move(__other._M_get());
183 else
184 {
185 if (__other._M_engaged)
186 this->_M_construct(std::move(__other._M_get()));
187 else
188 this->_M_reset();
189 }
190 }
191
192 struct _Empty_byte { };
193
194 template<typename _Up, bool = is_trivially_destructible_v<_Up>>
195 union _Storage
196 {
197 constexpr _Storage() noexcept : _M_empty() { }
198
199 template<typename... _Args>
200 constexpr
201 _Storage(in_place_t, _Args&&... __args)
202 : _M_value(std::forward<_Args>(__args)...)
203 { }
204
205 template<typename _Vp, typename... _Args>
206 constexpr
207 _Storage(std::initializer_list<_Vp> __il, _Args&&... __args)
208 : _M_value(__il, std::forward<_Args>(__args)...)
209 { }
210
211 _Empty_byte _M_empty;
212 _Up _M_value;
213 };
214
215 template<typename _Up>
216 union _Storage<_Up, false>
217 {
218 constexpr _Storage() noexcept : _M_empty() { }
219
220 template<typename... _Args>
221 constexpr
222 _Storage(in_place_t, _Args&&... __args)
223 : _M_value(std::forward<_Args>(__args)...)
224 { }
225
226 template<typename _Vp, typename... _Args>
227 constexpr
228 _Storage(std::initializer_list<_Vp> __il, _Args&&... __args)
229 : _M_value(__il, std::forward<_Args>(__args)...)
230 { }
231
232 // User-provided destructor is needed when _Up has non-trivial dtor.
233 ~_Storage() { }
234
235 _Empty_byte _M_empty;
236 _Up _M_value;
237 };
238
239 _Storage<_Stored_type> _M_payload;
240
241 bool _M_engaged = false;
242
243 template<typename... _Args>
244 void
245 _M_construct(_Args&&... __args)
246 noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
247 {
248 ::new ((void *) std::__addressof(this->_M_payload))
249 _Stored_type(std::forward<_Args>(__args)...);
250 this->_M_engaged = true;
251 }
252
253 constexpr void
254 _M_destroy() noexcept
255 {
256 _M_engaged = false;
257 _M_payload._M_value.~_Stored_type();
258 }
259
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.
263
264 constexpr _Tp&
265 _M_get() noexcept
266 { return this->_M_payload._M_value; }
267
268 constexpr const _Tp&
269 _M_get() const noexcept
270 { return this->_M_payload._M_value; }
271
272 // _M_reset is a 'safe' operation with no precondition.
273 constexpr void
274 _M_reset() noexcept
275 {
276 if (this->_M_engaged)
277 _M_destroy();
278 }
279 };
280
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;
292
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>
297 {
298 using _Optional_payload_base<_Tp>::_Optional_payload_base;
299
300 _Optional_payload() = default;
301 };
302
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>
307 {
308 using _Optional_payload_base<_Tp>::_Optional_payload_base;
309
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;
315
316 // Non-trivial copy assignment.
317 constexpr
318 _Optional_payload&
319 operator=(const _Optional_payload& __other)
320 {
321 this->_M_copy_assign(__other);
322 return *this;
323 }
324 };
325
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>
330 {
331 using _Optional_payload_base<_Tp>::_Optional_payload_base;
332
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;
338
339 // Non-trivial move assignment.
340 constexpr
341 _Optional_payload&
342 operator=(_Optional_payload&& __other)
343 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
344 is_nothrow_move_assignable<_Tp>>)
345 {
346 this->_M_move_assign(std::move(__other));
347 return *this;
348 }
349 };
350
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>
355 {
356 using _Optional_payload_base<_Tp>::_Optional_payload_base;
357
358 _Optional_payload() = default;
359 ~_Optional_payload() = default;
360 _Optional_payload(const _Optional_payload&) = default;
361 _Optional_payload(_Optional_payload&&) = default;
362
363 // Non-trivial copy assignment.
364 constexpr
365 _Optional_payload&
366 operator=(const _Optional_payload& __other)
367 {
368 this->_M_copy_assign(__other);
369 return *this;
370 }
371
372 // Non-trivial move assignment.
373 constexpr
374 _Optional_payload&
375 operator=(_Optional_payload&& __other)
376 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
377 is_nothrow_move_assignable<_Tp>>)
378 {
379 this->_M_move_assign(std::move(__other));
380 return *this;
381 }
382 };
383
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>
388 {
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;
396
397 // Destructor needs to destroy the contained value:
398 ~_Optional_payload() { this->_M_reset(); }
399 };
400
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
405 {
406 protected:
407 using _Stored_type = remove_const_t<_Tp>;
408
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>
412 void
413 _M_construct(_Args&&... __args)
414 noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
415 {
416 ::new
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;
420 }
421
422 void
423 _M_destruct() noexcept
424 { static_cast<_Dp*>(this)->_M_payload._M_destroy(); }
425
426 // _M_reset is a 'safe' operation with no precondition.
427 constexpr void
428 _M_reset() noexcept
429 { static_cast<_Dp*>(this)->_M_payload._M_reset(); }
430
431 constexpr bool _M_is_engaged() const noexcept
432 { return static_cast<const _Dp*>(this)->_M_payload._M_engaged; }
433
434 // The _M_get operations have _M_engaged as a precondition.
435 constexpr _Tp&
436 _M_get() noexcept
437 {
438 __glibcxx_assert(this->_M_is_engaged());
439 return static_cast<_Dp*>(this)->_M_payload._M_get();
440 }
441
442 constexpr const _Tp&
443 _M_get() const noexcept
444 {
445 __glibcxx_assert(this->_M_is_engaged());
446 return static_cast<const _Dp*>(this)->_M_payload._M_get();
447 }
448 };
449
450 /**
451 * @brief Class template that provides copy/move constructors of optional.
452 *
453 * Such a separate base class template is necessary in order to
454 * conditionally make copy/move constructors trivial.
455 *
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.
462 *
463 * Whether the other special members are trivial is determined by the
464 * _Optional_payload<_Tp> specialization used for the _M_payload member.
465 *
466 * @see optional, _Enable_special_members
467 */
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>>
473 {
474 // Constructors for disengaged optionals.
475 constexpr _Optional_base() = default;
476
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)...) { }
483
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,
490 _Args&&... __args)
491 : _M_payload(in_place,
492 __il, std::forward<_Args>(__args)...)
493 { }
494
495 // Copy and move constructors.
496 constexpr _Optional_base(const _Optional_base& __other)
497 : _M_payload(__other._M_payload._M_engaged,
498 __other._M_payload)
499 { }
500
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))
505 { }
506
507 // Assignment operators.
508 _Optional_base& operator=(const _Optional_base&) = default;
509 _Optional_base& operator=(_Optional_base&&) = default;
510
511 _Optional_payload<_Tp> _M_payload;
512 };
513
514 template<typename _Tp>
515 struct _Optional_base<_Tp, false, true>
516 : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
517 {
518 // Constructors for disengaged optionals.
519 constexpr _Optional_base() = default;
520
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)...) { }
527
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,
534 _Args&&... __args)
535 : _M_payload(in_place,
536 __il, std::forward<_Args>(__args)...)
537 { }
538
539 // Copy and move constructors.
540 constexpr _Optional_base(const _Optional_base& __other)
541 : _M_payload(__other._M_payload._M_engaged,
542 __other._M_payload)
543 { }
544
545 constexpr _Optional_base(_Optional_base&& __other) = default;
546
547 // Assignment operators.
548 _Optional_base& operator=(const _Optional_base&) = default;
549 _Optional_base& operator=(_Optional_base&&) = default;
550
551 _Optional_payload<_Tp> _M_payload;
552 };
553
554 template<typename _Tp>
555 struct _Optional_base<_Tp, true, false>
556 : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
557 {
558 // Constructors for disengaged optionals.
559 constexpr _Optional_base() = default;
560
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)...) { }
567
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,
574 _Args&&... __args)
575 : _M_payload(in_place,
576 __il, std::forward<_Args>(__args)...)
577 { }
578
579 // Copy and move constructors.
580 constexpr _Optional_base(const _Optional_base& __other) = default;
581
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))
586 { }
587
588 // Assignment operators.
589 _Optional_base& operator=(const _Optional_base&) = default;
590 _Optional_base& operator=(_Optional_base&&) = default;
591
592 _Optional_payload<_Tp> _M_payload;
593 };
594
595 template<typename _Tp>
596 struct _Optional_base<_Tp, true, true>
597 : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
598 {
599 // Constructors for disengaged optionals.
600 constexpr _Optional_base() = default;
601
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)...) { }
608
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,
615 _Args&&... __args)
616 : _M_payload(in_place,
617 __il, std::forward<_Args>(__args)...)
618 { }
619
620 // Copy and move constructors.
621 constexpr _Optional_base(const _Optional_base& __other) = default;
622 constexpr _Optional_base(_Optional_base&& __other) = default;
623
624 // Assignment operators.
625 _Optional_base& operator=(const _Optional_base&) = default;
626 _Optional_base& operator=(_Optional_base&&) = default;
627
628 _Optional_payload<_Tp> _M_payload;
629 };
630
631 template<typename _Tp>
632 class optional;
633
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>>;
644
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>&&>>;
651
652 /**
653 * @brief Class template for optional values.
654 */
655 template<typename _Tp>
656 class optional
657 : private _Optional_base<_Tp>,
658 private _Enable_copy_move<
659 // Copy constructor.
660 is_copy_constructible_v<_Tp>,
661 // Copy assignment.
662 __and_v<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>,
663 // Move constructor.
664 is_move_constructible_v<_Tp>,
665 // Move assignment.
666 __and_v<is_move_constructible<_Tp>, is_move_assignable<_Tp>>,
667 // Unique tag type.
668 optional<_Tp>>
669 {
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>);
673
674 private:
675 using _Base = _Optional_base<_Tp>;
676
677 // SFINAE helpers
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>;
684
685 public:
686 using value_type = _Tp;
687
688 constexpr optional() = default;
689
690 constexpr optional(nullopt_t) noexcept { }
691
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>
697 constexpr
698 optional(_Up&& __t)
699 : _Base(std::in_place, std::forward<_Up>(__t)) { }
700
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>
705 explicit constexpr
706 optional(_Up&& __t)
707 : _Base(std::in_place, std::forward<_Up>(__t)) { }
708
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>
714 constexpr
715 optional(const optional<_Up>& __t)
716 {
717 if (__t)
718 emplace(*__t);
719 }
720
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>
726 explicit constexpr
727 optional(const optional<_Up>& __t)
728 {
729 if (__t)
730 emplace(*__t);
731 }
732
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>
738 constexpr
739 optional(optional<_Up>&& __t)
740 {
741 if (__t)
742 emplace(std::move(*__t));
743 }
744
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>
750 explicit constexpr
751 optional(optional<_Up>&& __t)
752 {
753 if (__t)
754 emplace(std::move(*__t));
755 }
756
757 template<typename... _Args,
758 _Requires<is_constructible<_Tp, _Args&&...>> = false>
759 explicit constexpr
760 optional(in_place_t, _Args&&... __args)
761 : _Base(std::in_place, std::forward<_Args>(__args)...) { }
762
763 template<typename _Up, typename... _Args,
764 _Requires<is_constructible<_Tp,
765 initializer_list<_Up>&,
766 _Args&&...>> = false>
767 explicit constexpr
768 optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
769 : _Base(std::in_place, __il, std::forward<_Args>(__args)...) { }
770
771 // Assignment operators.
772 optional&
773 operator=(nullopt_t) noexcept
774 {
775 this->_M_reset();
776 return *this;
777 }
778
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>>,
785 optional&>
786 operator=(_Up&& __u)
787 {
788 if (this->_M_is_engaged())
789 this->_M_get() = std::forward<_Up>(__u);
790 else
791 this->_M_construct(std::forward<_Up>(__u));
792
793 return *this;
794 }
795
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>>>,
802 optional&>
803 operator=(const optional<_Up>& __u)
804 {
805 if (__u)
806 {
807 if (this->_M_is_engaged())
808 this->_M_get() = *__u;
809 else
810 this->_M_construct(*__u);
811 }
812 else
813 {
814 this->_M_reset();
815 }
816 return *this;
817 }
818
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>>>,
825 optional&>
826 operator=(optional<_Up>&& __u)
827 {
828 if (__u)
829 {
830 if (this->_M_is_engaged())
831 this->_M_get() = std::move(*__u);
832 else
833 this->_M_construct(std::move(*__u));
834 }
835 else
836 {
837 this->_M_reset();
838 }
839
840 return *this;
841 }
842
843 template<typename... _Args>
844 enable_if_t<is_constructible_v<_Tp, _Args&&...>, _Tp&>
845 emplace(_Args&&... __args)
846 {
847 this->_M_reset();
848 this->_M_construct(std::forward<_Args>(__args)...);
849 return this->_M_get();
850 }
851
852 template<typename _Up, typename... _Args>
853 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&,
854 _Args&&...>, _Tp&>
855 emplace(initializer_list<_Up> __il, _Args&&... __args)
856 {
857 this->_M_reset();
858 this->_M_construct(__il, std::forward<_Args>(__args)...);
859 return this->_M_get();
860 }
861
862 // Destructor is implicit, implemented in _Optional_base.
863
864 // Swap.
865 void
866 swap(optional& __other)
867 noexcept(is_nothrow_move_constructible_v<_Tp>
868 && is_nothrow_swappable_v<_Tp>)
869 {
870 using std::swap;
871
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())
875 {
876 __other._M_construct(std::move(this->_M_get()));
877 this->_M_destruct();
878 }
879 else if (__other._M_is_engaged())
880 {
881 this->_M_construct(std::move(__other._M_get()));
882 __other._M_destruct();
883 }
884 }
885
886 // Observers.
887 constexpr const _Tp*
888 operator->() const
889 { return std::__addressof(this->_M_get()); }
890
891 constexpr
892 _Tp*
893 operator->()
894 { return std::__addressof(this->_M_get()); }
895
896 constexpr const _Tp&
897 operator*() const&
898 { return this->_M_get(); }
899
900 constexpr _Tp&
901 operator*()&
902 { return this->_M_get(); }
903
904 constexpr _Tp&&
905 operator*()&&
906 { return std::move(this->_M_get()); }
907
908 constexpr const _Tp&&
909 operator*() const&&
910 { return std::move(this->_M_get()); }
911
912 constexpr explicit operator bool() const noexcept
913 { return this->_M_is_engaged(); }
914
915 constexpr bool has_value() const noexcept
916 { return this->_M_is_engaged(); }
917
918 constexpr const _Tp&
919 value() const&
920 {
921 return this->_M_is_engaged()
922 ? this->_M_get()
923 : (__throw_bad_optional_access(), this->_M_get());
924 }
925
926 constexpr _Tp&
927 value()&
928 {
929 return this->_M_is_engaged()
930 ? this->_M_get()
931 : (__throw_bad_optional_access(), this->_M_get());
932 }
933
934 constexpr _Tp&&
935 value()&&
936 {
937 return this->_M_is_engaged()
938 ? std::move(this->_M_get())
939 : (__throw_bad_optional_access(), std::move(this->_M_get()));
940 }
941
942 constexpr const _Tp&&
943 value() const&&
944 {
945 return this->_M_is_engaged()
946 ? std::move(this->_M_get())
947 : (__throw_bad_optional_access(), std::move(this->_M_get()));
948 }
949
950 template<typename _Up>
951 constexpr _Tp
952 value_or(_Up&& __u) const&
953 {
954 static_assert(is_copy_constructible_v<_Tp>);
955 static_assert(is_convertible_v<_Up&&, _Tp>);
956
957 return this->_M_is_engaged()
958 ? this->_M_get() : static_cast<_Tp>(std::forward<_Up>(__u));
959 }
960
961 template<typename _Up>
962 constexpr _Tp
963 value_or(_Up&& __u) &&
964 {
965 static_assert(is_move_constructible_v<_Tp>);
966 static_assert(is_convertible_v<_Up&&, _Tp>);
967
968 return this->_M_is_engaged()
969 ? std::move(this->_M_get())
970 : static_cast<_Tp>(std::forward<_Up>(__u));
971 }
972
973 void reset() noexcept { this->_M_reset(); }
974 };
975
976 template<typename _Tp>
977 using __optional_relop_t =
978 enable_if_t<is_convertible<_Tp, bool>::value, bool>;
979
980 // Comparisons between optional values.
981 template<typename _Tp, typename _Up>
982 constexpr auto
983 operator==(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
984 -> __optional_relop_t<decltype(declval<_Tp>() == declval<_Up>())>
985 {
986 return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
987 && (!__lhs || *__lhs == *__rhs);
988 }
989
990 template<typename _Tp, typename _Up>
991 constexpr auto
992 operator!=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
993 -> __optional_relop_t<decltype(declval<_Tp>() != declval<_Up>())>
994 {
995 return static_cast<bool>(__lhs) != static_cast<bool>(__rhs)
996 || (static_cast<bool>(__lhs) && *__lhs != *__rhs);
997 }
998
999 template<typename _Tp, typename _Up>
1000 constexpr auto
1001 operator<(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1002 -> __optional_relop_t<decltype(declval<_Tp>() < declval<_Up>())>
1003 {
1004 return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
1005 }
1006
1007 template<typename _Tp, typename _Up>
1008 constexpr auto
1009 operator>(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1010 -> __optional_relop_t<decltype(declval<_Tp>() > declval<_Up>())>
1011 {
1012 return static_cast<bool>(__lhs) && (!__rhs || *__lhs > *__rhs);
1013 }
1014
1015 template<typename _Tp, typename _Up>
1016 constexpr auto
1017 operator<=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1018 -> __optional_relop_t<decltype(declval<_Tp>() <= declval<_Up>())>
1019 {
1020 return !__lhs || (static_cast<bool>(__rhs) && *__lhs <= *__rhs);
1021 }
1022
1023 template<typename _Tp, typename _Up>
1024 constexpr auto
1025 operator>=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1026 -> __optional_relop_t<decltype(declval<_Tp>() >= declval<_Up>())>
1027 {
1028 return !__rhs || (static_cast<bool>(__lhs) && *__lhs >= *__rhs);
1029 }
1030
1031 // Comparisons with nullopt.
1032 template<typename _Tp>
1033 constexpr bool
1034 operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept
1035 { return !__lhs; }
1036
1037 template<typename _Tp>
1038 constexpr bool
1039 operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept
1040 { return !__rhs; }
1041
1042 template<typename _Tp>
1043 constexpr bool
1044 operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept
1045 { return static_cast<bool>(__lhs); }
1046
1047 template<typename _Tp>
1048 constexpr bool
1049 operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept
1050 { return static_cast<bool>(__rhs); }
1051
1052 template<typename _Tp>
1053 constexpr bool
1054 operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
1055 { return false; }
1056
1057 template<typename _Tp>
1058 constexpr bool
1059 operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
1060 { return static_cast<bool>(__rhs); }
1061
1062 template<typename _Tp>
1063 constexpr bool
1064 operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept
1065 { return static_cast<bool>(__lhs); }
1066
1067 template<typename _Tp>
1068 constexpr bool
1069 operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
1070 { return false; }
1071
1072 template<typename _Tp>
1073 constexpr bool
1074 operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept
1075 { return !__lhs; }
1076
1077 template<typename _Tp>
1078 constexpr bool
1079 operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
1080 { return true; }
1081
1082 template<typename _Tp>
1083 constexpr bool
1084 operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
1085 { return true; }
1086
1087 template<typename _Tp>
1088 constexpr bool
1089 operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept
1090 { return !__rhs; }
1091
1092 // Comparisons with value type.
1093 template<typename _Tp, typename _Up>
1094 constexpr auto
1095 operator==(const optional<_Tp>& __lhs, const _Up& __rhs)
1096 -> __optional_relop_t<decltype(declval<_Tp>() == declval<_Up>())>
1097 { return __lhs && *__lhs == __rhs; }
1098
1099 template<typename _Tp, typename _Up>
1100 constexpr auto
1101 operator==(const _Up& __lhs, const optional<_Tp>& __rhs)
1102 -> __optional_relop_t<decltype(declval<_Up>() == declval<_Tp>())>
1103 { return __rhs && __lhs == *__rhs; }
1104
1105 template<typename _Tp, typename _Up>
1106 constexpr auto
1107 operator!=(const optional<_Tp>& __lhs, const _Up& __rhs)
1108 -> __optional_relop_t<decltype(declval<_Tp>() != declval<_Up>())>
1109 { return !__lhs || *__lhs != __rhs; }
1110
1111 template<typename _Tp, typename _Up>
1112 constexpr auto
1113 operator!=(const _Up& __lhs, const optional<_Tp>& __rhs)
1114 -> __optional_relop_t<decltype(declval<_Up>() != declval<_Tp>())>
1115 { return !__rhs || __lhs != *__rhs; }
1116
1117 template<typename _Tp, typename _Up>
1118 constexpr auto
1119 operator<(const optional<_Tp>& __lhs, const _Up& __rhs)
1120 -> __optional_relop_t<decltype(declval<_Tp>() < declval<_Up>())>
1121 { return !__lhs || *__lhs < __rhs; }
1122
1123 template<typename _Tp, typename _Up>
1124 constexpr auto
1125 operator<(const _Up& __lhs, const optional<_Tp>& __rhs)
1126 -> __optional_relop_t<decltype(declval<_Up>() < declval<_Tp>())>
1127 { return __rhs && __lhs < *__rhs; }
1128
1129 template<typename _Tp, typename _Up>
1130 constexpr auto
1131 operator>(const optional<_Tp>& __lhs, const _Up& __rhs)
1132 -> __optional_relop_t<decltype(declval<_Tp>() > declval<_Up>())>
1133 { return __lhs && *__lhs > __rhs; }
1134
1135 template<typename _Tp, typename _Up>
1136 constexpr auto
1137 operator>(const _Up& __lhs, const optional<_Tp>& __rhs)
1138 -> __optional_relop_t<decltype(declval<_Up>() > declval<_Tp>())>
1139 { return !__rhs || __lhs > *__rhs; }
1140
1141 template<typename _Tp, typename _Up>
1142 constexpr auto
1143 operator<=(const optional<_Tp>& __lhs, const _Up& __rhs)
1144 -> __optional_relop_t<decltype(declval<_Tp>() <= declval<_Up>())>
1145 { return !__lhs || *__lhs <= __rhs; }
1146
1147 template<typename _Tp, typename _Up>
1148 constexpr auto
1149 operator<=(const _Up& __lhs, const optional<_Tp>& __rhs)
1150 -> __optional_relop_t<decltype(declval<_Up>() <= declval<_Tp>())>
1151 { return __rhs && __lhs <= *__rhs; }
1152
1153 template<typename _Tp, typename _Up>
1154 constexpr auto
1155 operator>=(const optional<_Tp>& __lhs, const _Up& __rhs)
1156 -> __optional_relop_t<decltype(declval<_Tp>() >= declval<_Up>())>
1157 { return __lhs && *__lhs >= __rhs; }
1158
1159 template<typename _Tp, typename _Up>
1160 constexpr auto
1161 operator>=(const _Up& __lhs, const optional<_Tp>& __rhs)
1162 -> __optional_relop_t<decltype(declval<_Up>() >= declval<_Tp>())>
1163 { return !__rhs || __lhs >= *__rhs; }
1164
1165 // Swap and creation functions.
1166
1167 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1168 // 2748. swappable traits for optionals
1169 template<typename _Tp>
1170 inline enable_if_t<is_move_constructible_v<_Tp> && is_swappable_v<_Tp>>
1171 swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
1172 noexcept(noexcept(__lhs.swap(__rhs)))
1173 { __lhs.swap(__rhs); }
1174
1175 template<typename _Tp>
1176 enable_if_t<!(is_move_constructible_v<_Tp> && is_swappable_v<_Tp>)>
1177 swap(optional<_Tp>&, optional<_Tp>&) = delete;
1178
1179 template<typename _Tp>
1180 constexpr optional<decay_t<_Tp>>
1181 make_optional(_Tp&& __t)
1182 { return optional<decay_t<_Tp>> { std::forward<_Tp>(__t) }; }
1183
1184 template<typename _Tp, typename ..._Args>
1185 constexpr optional<_Tp>
1186 make_optional(_Args&&... __args)
1187 { return optional<_Tp> { in_place, std::forward<_Args>(__args)... }; }
1188
1189 template<typename _Tp, typename _Up, typename ..._Args>
1190 constexpr optional<_Tp>
1191 make_optional(initializer_list<_Up> __il, _Args&&... __args)
1192 { return optional<_Tp> { in_place, __il, std::forward<_Args>(__args)... }; }
1193
1194 // Hash.
1195
1196 template<typename _Tp, typename _Up = remove_const_t<_Tp>,
1197 bool = __poison_hash<_Up>::__enable_hash_call>
1198 struct __optional_hash_call_base
1199 {
1200 size_t
1201 operator()(const optional<_Tp>& __t) const
1202 noexcept(noexcept(hash<_Up>{}(*__t)))
1203 {
1204 // We pick an arbitrary hash for disengaged optionals which hopefully
1205 // usual values of _Tp won't typically hash to.
1206 constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333);
1207 return __t ? hash<_Up>{}(*__t) : __magic_disengaged_hash;
1208 }
1209 };
1210
1211 template<typename _Tp, typename _Up>
1212 struct __optional_hash_call_base<_Tp, _Up, false> {};
1213
1214 template<typename _Tp>
1215 struct hash<optional<_Tp>>
1216 : private __poison_hash<remove_const_t<_Tp>>,
1217 public __optional_hash_call_base<_Tp>
1218 {
1219 using result_type [[__deprecated__]] = size_t;
1220 using argument_type [[__deprecated__]] = optional<_Tp>;
1221 };
1222
1223 template<typename _Tp>
1224 struct __is_fast_hash<hash<optional<_Tp>>> : __is_fast_hash<hash<_Tp>>
1225 { };
1226
1227 /// @}
1228
1229#if __cpp_deduction_guides >= 201606
1230 template <typename _Tp> optional(_Tp) -> optional<_Tp>;
1231#endif
1232
1233_GLIBCXX_END_NAMESPACE_VERSION
1234} // namespace std
1235
1236#endif // C++17
1237
1238#endif // _GLIBCXX_OPTIONAL
1239