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