annotate libstdc++-v3/include/std/optional @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 // <optional> -*- C++ -*-
kono
parents:
diff changeset
2
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3 // Copyright (C) 2013-2020 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
4 //
kono
parents:
diff changeset
5 // This file is part of the GNU ISO C++ Library. This library is free
kono
parents:
diff changeset
6 // software; you can redistribute it and/or modify it under the
kono
parents:
diff changeset
7 // terms of the GNU General Public License as published by the
kono
parents:
diff changeset
8 // Free Software Foundation; either version 3, or (at your option)
kono
parents:
diff changeset
9 // any later version.
kono
parents:
diff changeset
10
kono
parents:
diff changeset
11 // This library is distributed in the hope that it will be useful,
kono
parents:
diff changeset
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
kono
parents:
diff changeset
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
kono
parents:
diff changeset
14 // GNU General Public License for more details.
kono
parents:
diff changeset
15
kono
parents:
diff changeset
16 // Under Section 7 of GPL version 3, you are granted additional
kono
parents:
diff changeset
17 // permissions described in the GCC Runtime Library Exception, version
kono
parents:
diff changeset
18 // 3.1, as published by the Free Software Foundation.
kono
parents:
diff changeset
19
kono
parents:
diff changeset
20 // You should have received a copy of the GNU General Public License and
kono
parents:
diff changeset
21 // a copy of the GCC Runtime Library Exception along with this program;
kono
parents:
diff changeset
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
kono
parents:
diff changeset
23 // <http://www.gnu.org/licenses/>.
kono
parents:
diff changeset
24
kono
parents:
diff changeset
25 /** @file include/optional
kono
parents:
diff changeset
26 * This is a Standard C++ Library header.
kono
parents:
diff changeset
27 */
kono
parents:
diff changeset
28
kono
parents:
diff changeset
29 #ifndef _GLIBCXX_OPTIONAL
kono
parents:
diff changeset
30 #define _GLIBCXX_OPTIONAL 1
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 #pragma GCC system_header
kono
parents:
diff changeset
33
kono
parents:
diff changeset
34 #if __cplusplus >= 201703L
kono
parents:
diff changeset
35
kono
parents:
diff changeset
36 #include <utility>
kono
parents:
diff changeset
37 #include <type_traits>
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
38 #include <exception>
111
kono
parents:
diff changeset
39 #include <new>
kono
parents:
diff changeset
40 #include <initializer_list>
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
41 #include <bits/exception_defines.h>
111
kono
parents:
diff changeset
42 #include <bits/functional_hash.h>
kono
parents:
diff changeset
43 #include <bits/enable_special_members.h>
kono
parents:
diff changeset
44
kono
parents:
diff changeset
45 namespace std _GLIBCXX_VISIBILITY(default)
kono
parents:
diff changeset
46 {
kono
parents:
diff changeset
47 _GLIBCXX_BEGIN_NAMESPACE_VERSION
kono
parents:
diff changeset
48
kono
parents:
diff changeset
49 /**
kono
parents:
diff changeset
50 * @addtogroup utilities
kono
parents:
diff changeset
51 * @{
kono
parents:
diff changeset
52 */
kono
parents:
diff changeset
53
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
54 #define __cpp_lib_optional 201606L
111
kono
parents:
diff changeset
55
kono
parents:
diff changeset
56 template<typename _Tp>
kono
parents:
diff changeset
57 class optional;
kono
parents:
diff changeset
58
kono
parents:
diff changeset
59 /// Tag type to disengage optional objects.
kono
parents:
diff changeset
60 struct nullopt_t
kono
parents:
diff changeset
61 {
kono
parents:
diff changeset
62 // Do not user-declare default constructor at all for
kono
parents:
diff changeset
63 // optional_value = {} syntax to work.
kono
parents:
diff changeset
64 // nullopt_t() = delete;
kono
parents:
diff changeset
65
kono
parents:
diff changeset
66 // Used for constructing nullopt.
kono
parents:
diff changeset
67 enum class _Construct { _Token };
kono
parents:
diff changeset
68
kono
parents:
diff changeset
69 // Must be constexpr for nullopt_t to be literal.
kono
parents:
diff changeset
70 explicit constexpr nullopt_t(_Construct) { }
kono
parents:
diff changeset
71 };
kono
parents:
diff changeset
72
kono
parents:
diff changeset
73 /// Tag to disengage optional objects.
kono
parents:
diff changeset
74 inline constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token };
kono
parents:
diff changeset
75
kono
parents:
diff changeset
76 /**
kono
parents:
diff changeset
77 * @brief Exception class thrown when a disengaged optional object is
kono
parents:
diff changeset
78 * dereferenced.
kono
parents:
diff changeset
79 * @ingroup exceptions
kono
parents:
diff changeset
80 */
kono
parents:
diff changeset
81 class bad_optional_access : public exception
kono
parents:
diff changeset
82 {
kono
parents:
diff changeset
83 public:
kono
parents:
diff changeset
84 bad_optional_access() { }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
85
111
kono
parents:
diff changeset
86 virtual const char* what() const noexcept override
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
87 { return "bad optional access"; }
111
kono
parents:
diff changeset
88
kono
parents:
diff changeset
89 virtual ~bad_optional_access() noexcept = default;
kono
parents:
diff changeset
90 };
kono
parents:
diff changeset
91
kono
parents:
diff changeset
92 void
kono
parents:
diff changeset
93 __throw_bad_optional_access()
kono
parents:
diff changeset
94 __attribute__((__noreturn__));
kono
parents:
diff changeset
95
kono
parents:
diff changeset
96 // XXX Does not belong here.
kono
parents:
diff changeset
97 inline void
kono
parents:
diff changeset
98 __throw_bad_optional_access()
kono
parents:
diff changeset
99 { _GLIBCXX_THROW_OR_ABORT(bad_optional_access()); }
kono
parents:
diff changeset
100
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
101 // This class template manages construction/destruction of
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
102 // the contained value for a std::optional.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
103 template <typename _Tp>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
104 struct _Optional_payload_base
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
105 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
106 using _Stored_type = remove_const_t<_Tp>;
111
kono
parents:
diff changeset
107
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
108 _Optional_payload_base() = default;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
109 ~_Optional_payload_base() = default;
111
kono
parents:
diff changeset
110
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
111 template<typename... _Args>
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
112 constexpr
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
113 _Optional_payload_base(in_place_t __tag, _Args&&... __args)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
114 : _M_payload(__tag, std::forward<_Args>(__args)...),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
115 _M_engaged(true)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
116 { }
111
kono
parents:
diff changeset
117
kono
parents:
diff changeset
118 template<typename _Up, typename... _Args>
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
119 constexpr
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
120 _Optional_payload_base(std::initializer_list<_Up> __il,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
121 _Args&&... __args)
111
kono
parents:
diff changeset
122 : _M_payload(__il, std::forward<_Args>(__args)...),
kono
parents:
diff changeset
123 _M_engaged(true)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
124 { }
111
kono
parents:
diff changeset
125
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
126 // Constructor used by _Optional_base copy constructor when the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
127 // contained value is not trivially copy constructible.
111
kono
parents:
diff changeset
128 constexpr
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
129 _Optional_payload_base(bool __engaged,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
130 const _Optional_payload_base& __other)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
131 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
132 if (__other._M_engaged)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
133 this->_M_construct(__other._M_get());
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
134 }
111
kono
parents:
diff changeset
135
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
136 // Constructor used by _Optional_base move constructor when the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
137 // contained value is not trivially move constructible.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
138 constexpr
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
139 _Optional_payload_base(bool __engaged,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
140 _Optional_payload_base&& __other)
111
kono
parents:
diff changeset
141 {
kono
parents:
diff changeset
142 if (__other._M_engaged)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
143 this->_M_construct(std::move(__other._M_get()));
111
kono
parents:
diff changeset
144 }
kono
parents:
diff changeset
145
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
146 // Copy constructor is only used to when the contained value is
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
147 // trivially copy constructible.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
148 _Optional_payload_base(const _Optional_payload_base&) = default;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
149
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
150 // Move constructor is only used to when the contained value is
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
151 // trivially copy constructible.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
152 _Optional_payload_base(_Optional_payload_base&&) = default;
111
kono
parents:
diff changeset
153
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
154 _Optional_payload_base&
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
155 operator=(const _Optional_payload_base&) = default;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
156
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
157 _Optional_payload_base&
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
158 operator=(_Optional_payload_base&&) = default;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
159
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
160 // used to perform non-trivial copy assignment.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
161 constexpr void
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
162 _M_copy_assign(const _Optional_payload_base& __other)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
163 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
164 if (this->_M_engaged && __other._M_engaged)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
165 this->_M_get() = __other._M_get();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
166 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
167 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
168 if (__other._M_engaged)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
169 this->_M_construct(__other._M_get());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
170 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
171 this->_M_reset();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
172 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
173 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
174
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
175 // used to perform non-trivial move assignment.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
176 constexpr void
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
177 _M_move_assign(_Optional_payload_base&& __other)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
178 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
179 is_nothrow_move_assignable<_Tp>>)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
180 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
181 if (this->_M_engaged && __other._M_engaged)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
182 this->_M_get() = std::move(__other._M_get());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
183 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
184 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
185 if (__other._M_engaged)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
186 this->_M_construct(std::move(__other._M_get()));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
187 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
188 this->_M_reset();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
189 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
190 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
191
111
kono
parents:
diff changeset
192 struct _Empty_byte { };
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
193
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
194 template<typename _Up, bool = is_trivially_destructible_v<_Up>>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
195 union _Storage
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
196 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
197 constexpr _Storage() noexcept : _M_empty() { }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
198
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
199 template<typename... _Args>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
200 constexpr
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
201 _Storage(in_place_t, _Args&&... __args)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
202 : _M_value(std::forward<_Args>(__args)...)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
203 { }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
204
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
205 template<typename _Vp, typename... _Args>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
206 constexpr
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
207 _Storage(std::initializer_list<_Vp> __il, _Args&&... __args)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
208 : _M_value(__il, std::forward<_Args>(__args)...)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
209 { }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
210
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
211 _Empty_byte _M_empty;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
212 _Up _M_value;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
213 };
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
214
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
215 template<typename _Up>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
216 union _Storage<_Up, false>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
217 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
218 constexpr _Storage() noexcept : _M_empty() { }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
219
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
220 template<typename... _Args>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
221 constexpr
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
222 _Storage(in_place_t, _Args&&... __args)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
223 : _M_value(std::forward<_Args>(__args)...)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
224 { }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
225
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
226 template<typename _Vp, typename... _Args>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
227 constexpr
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
228 _Storage(std::initializer_list<_Vp> __il, _Args&&... __args)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
229 : _M_value(__il, std::forward<_Args>(__args)...)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
230 { }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
231
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
232 // User-provided destructor is needed when _Up has non-trivial dtor.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
233 ~_Storage() { }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
234
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
235 _Empty_byte _M_empty;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
236 _Up _M_value;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
237 };
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
238
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
239 _Storage<_Stored_type> _M_payload;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
240
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
241 bool _M_engaged = false;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
242
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
243 template<typename... _Args>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
244 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
245 _M_construct(_Args&&... __args)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
246 noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
111
kono
parents:
diff changeset
247 {
kono
parents:
diff changeset
248 ::new ((void *) std::__addressof(this->_M_payload))
kono
parents:
diff changeset
249 _Stored_type(std::forward<_Args>(__args)...);
kono
parents:
diff changeset
250 this->_M_engaged = true;
kono
parents:
diff changeset
251 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
252
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
253 constexpr void
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
254 _M_destroy() noexcept
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
255 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
256 _M_engaged = false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
257 _M_payload._M_value.~_Stored_type();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
258 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
259
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
260 // The _M_get() operations have _M_engaged as a precondition.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
261 // They exist to access the contained value with the appropriate
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
262 // const-qualification, because _M_payload has had the const removed.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
263
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
264 constexpr _Tp&
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
265 _M_get() noexcept
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
266 { return this->_M_payload._M_value; }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
267
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
268 constexpr const _Tp&
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
269 _M_get() const noexcept
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
270 { return this->_M_payload._M_value; }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
271
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
272 // _M_reset is a 'safe' operation with no precondition.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
273 constexpr void
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
274 _M_reset() noexcept
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
275 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
276 if (this->_M_engaged)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
277 _M_destroy();
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
278 }
111
kono
parents:
diff changeset
279 };
kono
parents:
diff changeset
280
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
281 // Class template that manages the payload for optionals.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
282 template <typename _Tp,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
283 bool /*_HasTrivialDestructor*/ =
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
284 is_trivially_destructible_v<_Tp>,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
285 bool /*_HasTrivialCopy */ =
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
286 is_trivially_copy_assignable_v<_Tp>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
287 && is_trivially_copy_constructible_v<_Tp>,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
288 bool /*_HasTrivialMove */ =
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
289 is_trivially_move_assignable_v<_Tp>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
290 && is_trivially_move_constructible_v<_Tp>>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
291 struct _Optional_payload;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
292
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
293 // Payload for potentially-constexpr optionals (trivial copy/move/destroy).
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
294 template <typename _Tp>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
295 struct _Optional_payload<_Tp, true, true, true>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
296 : _Optional_payload_base<_Tp>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
297 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
298 using _Optional_payload_base<_Tp>::_Optional_payload_base;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
299
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
300 _Optional_payload() = default;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
301 };
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
302
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
303 // Payload for optionals with non-trivial copy construction/assignment.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
304 template <typename _Tp>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
305 struct _Optional_payload<_Tp, true, false, true>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
306 : _Optional_payload_base<_Tp>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
307 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
308 using _Optional_payload_base<_Tp>::_Optional_payload_base;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
309
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
310 _Optional_payload() = default;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
311 ~_Optional_payload() = default;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
312 _Optional_payload(const _Optional_payload&) = default;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
313 _Optional_payload(_Optional_payload&&) = default;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
314 _Optional_payload& operator=(_Optional_payload&&) = default;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
315
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
316 // Non-trivial copy assignment.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
317 constexpr
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
318 _Optional_payload&
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
319 operator=(const _Optional_payload& __other)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
320 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
321 this->_M_copy_assign(__other);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
322 return *this;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
323 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
324 };
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
325
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
326 // Payload for optionals with non-trivial move construction/assignment.
111
kono
parents:
diff changeset
327 template <typename _Tp>
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
328 struct _Optional_payload<_Tp, true, true, false>
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
329 : _Optional_payload_base<_Tp>
111
kono
parents:
diff changeset
330 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
331 using _Optional_payload_base<_Tp>::_Optional_payload_base;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
332
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
333 _Optional_payload() = default;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
334 ~_Optional_payload() = default;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
335 _Optional_payload(const _Optional_payload&) = default;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
336 _Optional_payload(_Optional_payload&&) = default;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
337 _Optional_payload& operator=(const _Optional_payload&) = default;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
338
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
339 // Non-trivial move assignment.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
340 constexpr
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
341 _Optional_payload&
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
342 operator=(_Optional_payload&& __other)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
343 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
344 is_nothrow_move_assignable<_Tp>>)
111
kono
parents:
diff changeset
345 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
346 this->_M_move_assign(std::move(__other));
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
347 return *this;
111
kono
parents:
diff changeset
348 }
kono
parents:
diff changeset
349 };
kono
parents:
diff changeset
350
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
351 // Payload for optionals with non-trivial copy and move assignment.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
352 template <typename _Tp>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
353 struct _Optional_payload<_Tp, true, false, false>
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
354 : _Optional_payload_base<_Tp>
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
355 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
356 using _Optional_payload_base<_Tp>::_Optional_payload_base;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
357
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
358 _Optional_payload() = default;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
359 ~_Optional_payload() = default;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
360 _Optional_payload(const _Optional_payload&) = default;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
361 _Optional_payload(_Optional_payload&&) = default;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
362
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
363 // Non-trivial copy assignment.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
364 constexpr
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
365 _Optional_payload&
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
366 operator=(const _Optional_payload& __other)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
367 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
368 this->_M_copy_assign(__other);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
369 return *this;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
370 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
371
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
372 // Non-trivial move assignment.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
373 constexpr
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
374 _Optional_payload&
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
375 operator=(_Optional_payload&& __other)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
376 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
377 is_nothrow_move_assignable<_Tp>>)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
378 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
379 this->_M_move_assign(std::move(__other));
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
380 return *this;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
381 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
382 };
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
383
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
384 // Payload for optionals with non-trivial destructors.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
385 template <typename _Tp, bool _Copy, bool _Move>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
386 struct _Optional_payload<_Tp, false, _Copy, _Move>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
387 : _Optional_payload<_Tp, true, false, false>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
388 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
389 // Base class implements all the constructors and assignment operators:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
390 using _Optional_payload<_Tp, true, false, false>::_Optional_payload;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
391 _Optional_payload() = default;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
392 _Optional_payload(const _Optional_payload&) = default;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
393 _Optional_payload(_Optional_payload&&) = default;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
394 _Optional_payload& operator=(const _Optional_payload&) = default;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
395 _Optional_payload& operator=(_Optional_payload&&) = default;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
396
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
397 // Destructor needs to destroy the contained value:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
398 ~_Optional_payload() { this->_M_reset(); }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
399 };
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
400
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
401 // Common base class for _Optional_base<T> to avoid repeating these
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
402 // member functions in each specialization.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
403 template<typename _Tp, typename _Dp>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
404 class _Optional_base_impl
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
405 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
406 protected:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
407 using _Stored_type = remove_const_t<_Tp>;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
408
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
409 // The _M_construct operation has !_M_engaged as a precondition
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
410 // while _M_destruct has _M_engaged as a precondition.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
411 template<typename... _Args>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
412 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
413 _M_construct(_Args&&... __args)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
414 noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
415 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
416 ::new
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
417 (std::__addressof(static_cast<_Dp*>(this)->_M_payload._M_payload))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
418 _Stored_type(std::forward<_Args>(__args)...);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
419 static_cast<_Dp*>(this)->_M_payload._M_engaged = true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
420 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
421
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
422 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
423 _M_destruct() noexcept
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
424 { static_cast<_Dp*>(this)->_M_payload._M_destroy(); }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
425
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
426 // _M_reset is a 'safe' operation with no precondition.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
427 constexpr void
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
428 _M_reset() noexcept
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
429 { static_cast<_Dp*>(this)->_M_payload._M_reset(); }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
430
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
431 constexpr bool _M_is_engaged() const noexcept
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
432 { return static_cast<const _Dp*>(this)->_M_payload._M_engaged; }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
433
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
434 // The _M_get operations have _M_engaged as a precondition.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
435 constexpr _Tp&
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
436 _M_get() noexcept
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
437 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
438 __glibcxx_assert(this->_M_is_engaged());
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
439 return static_cast<_Dp*>(this)->_M_payload._M_get();
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
440 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
441
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
442 constexpr const _Tp&
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
443 _M_get() const noexcept
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
444 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
445 __glibcxx_assert(this->_M_is_engaged());
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
446 return static_cast<const _Dp*>(this)->_M_payload._M_get();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
447 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
448 };
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
449
111
kono
parents:
diff changeset
450 /**
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
451 * @brief Class template that provides copy/move constructors of optional.
111
kono
parents:
diff changeset
452 *
kono
parents:
diff changeset
453 * Such a separate base class template is necessary in order to
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
454 * conditionally make copy/move constructors trivial.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
455 *
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
456 * When the contained value is trivially copy/move constructible,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
457 * the copy/move constructors of _Optional_base will invoke the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
458 * trivial copy/move constructor of _Optional_payload. Otherwise,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
459 * they will invoke _Optional_payload(bool, const _Optional_payload&)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
460 * or _Optional_payload(bool, _Optional_payload&&) to initialize
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
461 * the contained value, if copying/moving an engaged optional.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
462 *
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
463 * Whether the other special members are trivial is determined by the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
464 * _Optional_payload<_Tp> specialization used for the _M_payload member.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
465 *
111
kono
parents:
diff changeset
466 * @see optional, _Enable_special_members
kono
parents:
diff changeset
467 */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
468 template<typename _Tp,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
469 bool = is_trivially_copy_constructible_v<_Tp>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
470 bool = is_trivially_move_constructible_v<_Tp>>
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
471 struct _Optional_base
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
472 : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
111
kono
parents:
diff changeset
473 {
kono
parents:
diff changeset
474 // Constructors for disengaged optionals.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
475 constexpr _Optional_base() = default;
111
kono
parents:
diff changeset
476
kono
parents:
diff changeset
477 // Constructors for engaged optionals.
kono
parents:
diff changeset
478 template<typename... _Args,
kono
parents:
diff changeset
479 enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
kono
parents:
diff changeset
480 constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
kono
parents:
diff changeset
481 : _M_payload(in_place,
kono
parents:
diff changeset
482 std::forward<_Args>(__args)...) { }
kono
parents:
diff changeset
483
kono
parents:
diff changeset
484 template<typename _Up, typename... _Args,
kono
parents:
diff changeset
485 enable_if_t<is_constructible_v<_Tp,
kono
parents:
diff changeset
486 initializer_list<_Up>&,
kono
parents:
diff changeset
487 _Args&&...>, bool> = false>
kono
parents:
diff changeset
488 constexpr explicit _Optional_base(in_place_t,
kono
parents:
diff changeset
489 initializer_list<_Up> __il,
kono
parents:
diff changeset
490 _Args&&... __args)
kono
parents:
diff changeset
491 : _M_payload(in_place,
kono
parents:
diff changeset
492 __il, std::forward<_Args>(__args)...)
kono
parents:
diff changeset
493 { }
kono
parents:
diff changeset
494
kono
parents:
diff changeset
495 // Copy and move constructors.
kono
parents:
diff changeset
496 constexpr _Optional_base(const _Optional_base& __other)
kono
parents:
diff changeset
497 : _M_payload(__other._M_payload._M_engaged,
kono
parents:
diff changeset
498 __other._M_payload)
kono
parents:
diff changeset
499 { }
kono
parents:
diff changeset
500
kono
parents:
diff changeset
501 constexpr _Optional_base(_Optional_base&& __other)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
502 noexcept(is_nothrow_move_constructible_v<_Tp>)
111
kono
parents:
diff changeset
503 : _M_payload(__other._M_payload._M_engaged,
kono
parents:
diff changeset
504 std::move(__other._M_payload))
kono
parents:
diff changeset
505 { }
kono
parents:
diff changeset
506
kono
parents:
diff changeset
507 // Assignment operators.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
508 _Optional_base& operator=(const _Optional_base&) = default;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
509 _Optional_base& operator=(_Optional_base&&) = default;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
510
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
511 _Optional_payload<_Tp> _M_payload;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
512 };
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
513
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
514 template<typename _Tp>
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
515 struct _Optional_base<_Tp, false, true>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
516 : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
517 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
518 // Constructors for disengaged optionals.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
519 constexpr _Optional_base() = default;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
520
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
521 // Constructors for engaged optionals.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
522 template<typename... _Args,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
523 enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
524 constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
525 : _M_payload(in_place,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
526 std::forward<_Args>(__args)...) { }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
527
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
528 template<typename _Up, typename... _Args,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
529 enable_if_t<is_constructible_v<_Tp,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
530 initializer_list<_Up>&,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
531 _Args&&...>, bool> = false>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
532 constexpr explicit _Optional_base(in_place_t,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
533 initializer_list<_Up> __il,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
534 _Args&&... __args)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
535 : _M_payload(in_place,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
536 __il, std::forward<_Args>(__args)...)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
537 { }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
538
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
539 // Copy and move constructors.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
540 constexpr _Optional_base(const _Optional_base& __other)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
541 : _M_payload(__other._M_payload._M_engaged,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
542 __other._M_payload)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
543 { }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
544
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
545 constexpr _Optional_base(_Optional_base&& __other) = default;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
546
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
547 // Assignment operators.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
548 _Optional_base& operator=(const _Optional_base&) = default;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
549 _Optional_base& operator=(_Optional_base&&) = default;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
550
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
551 _Optional_payload<_Tp> _M_payload;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
552 };
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
553
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
554 template<typename _Tp>
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
555 struct _Optional_base<_Tp, true, false>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
556 : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
557 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
558 // Constructors for disengaged optionals.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
559 constexpr _Optional_base() = default;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
560
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
561 // Constructors for engaged optionals.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
562 template<typename... _Args,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
563 enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
564 constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
565 : _M_payload(in_place,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
566 std::forward<_Args>(__args)...) { }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
567
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
568 template<typename _Up, typename... _Args,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
569 enable_if_t<is_constructible_v<_Tp,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
570 initializer_list<_Up>&,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
571 _Args&&...>, bool> = false>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
572 constexpr explicit _Optional_base(in_place_t,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
573 initializer_list<_Up> __il,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
574 _Args&&... __args)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
575 : _M_payload(in_place,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
576 __il, std::forward<_Args>(__args)...)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
577 { }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
578
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
579 // Copy and move constructors.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
580 constexpr _Optional_base(const _Optional_base& __other) = default;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
581
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
582 constexpr _Optional_base(_Optional_base&& __other)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
583 noexcept(is_nothrow_move_constructible_v<_Tp>)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
584 : _M_payload(__other._M_payload._M_engaged,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
585 std::move(__other._M_payload))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
586 { }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
587
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
588 // Assignment operators.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
589 _Optional_base& operator=(const _Optional_base&) = default;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
590 _Optional_base& operator=(_Optional_base&&) = default;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
591
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
592 _Optional_payload<_Tp> _M_payload;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
593 };
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
594
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
595 template<typename _Tp>
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
596 struct _Optional_base<_Tp, true, true>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
597 : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
598 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
599 // Constructors for disengaged optionals.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
600 constexpr _Optional_base() = default;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
601
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
602 // Constructors for engaged optionals.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
603 template<typename... _Args,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
604 enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
605 constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
606 : _M_payload(in_place,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
607 std::forward<_Args>(__args)...) { }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
608
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
609 template<typename _Up, typename... _Args,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
610 enable_if_t<is_constructible_v<_Tp,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
611 initializer_list<_Up>&,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
612 _Args&&...>, bool> = false>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
613 constexpr explicit _Optional_base(in_place_t,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
614 initializer_list<_Up> __il,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
615 _Args&&... __args)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
616 : _M_payload(in_place,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
617 __il, std::forward<_Args>(__args)...)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
618 { }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
619
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
620 // Copy and move constructors.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
621 constexpr _Optional_base(const _Optional_base& __other) = default;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
622 constexpr _Optional_base(_Optional_base&& __other) = default;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
623
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
624 // Assignment operators.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
625 _Optional_base& operator=(const _Optional_base&) = default;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
626 _Optional_base& operator=(_Optional_base&&) = default;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
627
111
kono
parents:
diff changeset
628 _Optional_payload<_Tp> _M_payload;
kono
parents:
diff changeset
629 };
kono
parents:
diff changeset
630
kono
parents:
diff changeset
631 template<typename _Tp>
kono
parents:
diff changeset
632 class optional;
kono
parents:
diff changeset
633
kono
parents:
diff changeset
634 template<typename _Tp, typename _Up>
kono
parents:
diff changeset
635 using __converts_from_optional =
kono
parents:
diff changeset
636 __or_<is_constructible<_Tp, const optional<_Up>&>,
kono
parents:
diff changeset
637 is_constructible<_Tp, optional<_Up>&>,
kono
parents:
diff changeset
638 is_constructible<_Tp, const optional<_Up>&&>,
kono
parents:
diff changeset
639 is_constructible<_Tp, optional<_Up>&&>,
kono
parents:
diff changeset
640 is_convertible<const optional<_Up>&, _Tp>,
kono
parents:
diff changeset
641 is_convertible<optional<_Up>&, _Tp>,
kono
parents:
diff changeset
642 is_convertible<const optional<_Up>&&, _Tp>,
kono
parents:
diff changeset
643 is_convertible<optional<_Up>&&, _Tp>>;
kono
parents:
diff changeset
644
kono
parents:
diff changeset
645 template<typename _Tp, typename _Up>
kono
parents:
diff changeset
646 using __assigns_from_optional =
kono
parents:
diff changeset
647 __or_<is_assignable<_Tp&, const optional<_Up>&>,
kono
parents:
diff changeset
648 is_assignable<_Tp&, optional<_Up>&>,
kono
parents:
diff changeset
649 is_assignable<_Tp&, const optional<_Up>&&>,
kono
parents:
diff changeset
650 is_assignable<_Tp&, optional<_Up>&&>>;
kono
parents:
diff changeset
651
kono
parents:
diff changeset
652 /**
kono
parents:
diff changeset
653 * @brief Class template for optional values.
kono
parents:
diff changeset
654 */
kono
parents:
diff changeset
655 template<typename _Tp>
kono
parents:
diff changeset
656 class optional
kono
parents:
diff changeset
657 : private _Optional_base<_Tp>,
kono
parents:
diff changeset
658 private _Enable_copy_move<
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
659 // Copy constructor.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
660 is_copy_constructible_v<_Tp>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
661 // Copy assignment.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
662 __and_v<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
663 // Move constructor.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
664 is_move_constructible_v<_Tp>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
665 // Move assignment.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
666 __and_v<is_move_constructible<_Tp>, is_move_assignable<_Tp>>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
667 // Unique tag type.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
668 optional<_Tp>>
111
kono
parents:
diff changeset
669 {
kono
parents:
diff changeset
670 static_assert(!is_same_v<remove_cv_t<_Tp>, nullopt_t>);
kono
parents:
diff changeset
671 static_assert(!is_same_v<remove_cv_t<_Tp>, in_place_t>);
kono
parents:
diff changeset
672 static_assert(!is_reference_v<_Tp>);
kono
parents:
diff changeset
673
kono
parents:
diff changeset
674 private:
kono
parents:
diff changeset
675 using _Base = _Optional_base<_Tp>;
kono
parents:
diff changeset
676
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
677 // SFINAE helpers
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
678 template<typename _Up>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
679 using __not_self = __not_<is_same<optional, __remove_cvref_t<_Up>>>;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
680 template<typename _Up>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
681 using __not_tag = __not_<is_same<in_place_t, __remove_cvref_t<_Up>>>;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
682 template<typename... _Cond>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
683 using _Requires = enable_if_t<__and_v<_Cond...>, bool>;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
684
111
kono
parents:
diff changeset
685 public:
kono
parents:
diff changeset
686 using value_type = _Tp;
kono
parents:
diff changeset
687
kono
parents:
diff changeset
688 constexpr optional() = default;
kono
parents:
diff changeset
689
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
690 constexpr optional(nullopt_t) noexcept { }
111
kono
parents:
diff changeset
691
kono
parents:
diff changeset
692 // Converting constructors for engaged optionals.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
693 template<typename _Up = _Tp,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
694 _Requires<__not_self<_Up>, __not_tag<_Up>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
695 is_constructible<_Tp, _Up&&>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
696 is_convertible<_Up&&, _Tp>> = true>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
697 constexpr
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
698 optional(_Up&& __t)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
699 : _Base(std::in_place, std::forward<_Up>(__t)) { }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
700
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
701 template<typename _Up = _Tp,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
702 _Requires<__not_self<_Up>, __not_tag<_Up>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
703 is_constructible<_Tp, _Up&&>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
704 __not_<is_convertible<_Up&&, _Tp>>> = false>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
705 explicit constexpr
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
706 optional(_Up&& __t)
111
kono
parents:
diff changeset
707 : _Base(std::in_place, std::forward<_Up>(__t)) { }
kono
parents:
diff changeset
708
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
709 template<typename _Up,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
710 _Requires<__not_<is_same<_Tp, _Up>>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
711 is_constructible<_Tp, const _Up&>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
712 is_convertible<const _Up&, _Tp>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
713 __not_<__converts_from_optional<_Tp, _Up>>> = true>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
714 constexpr
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
715 optional(const optional<_Up>& __t)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
716 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
717 if (__t)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
718 emplace(*__t);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
719 }
111
kono
parents:
diff changeset
720
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
721 template<typename _Up,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
722 _Requires<__not_<is_same<_Tp, _Up>>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
723 is_constructible<_Tp, const _Up&>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
724 __not_<is_convertible<const _Up&, _Tp>>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
725 __not_<__converts_from_optional<_Tp, _Up>>> = false>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
726 explicit constexpr
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
727 optional(const optional<_Up>& __t)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
728 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
729 if (__t)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
730 emplace(*__t);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
731 }
111
kono
parents:
diff changeset
732
kono
parents:
diff changeset
733 template <typename _Up,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
734 _Requires<__not_<is_same<_Tp, _Up>>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
735 is_constructible<_Tp, _Up&&>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
736 is_convertible<_Up&&, _Tp>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
737 __not_<__converts_from_optional<_Tp, _Up>>> = true>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
738 constexpr
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
739 optional(optional<_Up>&& __t)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
740 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
741 if (__t)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
742 emplace(std::move(*__t));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
743 }
111
kono
parents:
diff changeset
744
kono
parents:
diff changeset
745 template <typename _Up,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
746 _Requires<__not_<is_same<_Tp, _Up>>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
747 is_constructible<_Tp, _Up&&>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
748 __not_<is_convertible<_Up&&, _Tp>>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
749 __not_<__converts_from_optional<_Tp, _Up>>> = false>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
750 explicit constexpr
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
751 optional(optional<_Up>&& __t)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
752 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
753 if (__t)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
754 emplace(std::move(*__t));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
755 }
111
kono
parents:
diff changeset
756
kono
parents:
diff changeset
757 template<typename... _Args,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
758 _Requires<is_constructible<_Tp, _Args&&...>> = false>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
759 explicit constexpr
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
760 optional(in_place_t, _Args&&... __args)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
761 : _Base(std::in_place, std::forward<_Args>(__args)...) { }
111
kono
parents:
diff changeset
762
kono
parents:
diff changeset
763 template<typename _Up, typename... _Args,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
764 _Requires<is_constructible<_Tp,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
765 initializer_list<_Up>&,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
766 _Args&&...>> = false>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
767 explicit constexpr
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
768 optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
769 : _Base(std::in_place, __il, std::forward<_Args>(__args)...) { }
111
kono
parents:
diff changeset
770
kono
parents:
diff changeset
771 // Assignment operators.
kono
parents:
diff changeset
772 optional&
kono
parents:
diff changeset
773 operator=(nullopt_t) noexcept
kono
parents:
diff changeset
774 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
775 this->_M_reset();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
776 return *this;
111
kono
parents:
diff changeset
777 }
kono
parents:
diff changeset
778
kono
parents:
diff changeset
779 template<typename _Up = _Tp>
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
780 enable_if_t<__and_v<__not_self<_Up>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
781 __not_<__and_<is_scalar<_Tp>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
782 is_same<_Tp, decay_t<_Up>>>>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
783 is_constructible<_Tp, _Up>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
784 is_assignable<_Tp&, _Up>>,
111
kono
parents:
diff changeset
785 optional&>
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
786 operator=(_Up&& __u)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
787 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
788 if (this->_M_is_engaged())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
789 this->_M_get() = std::forward<_Up>(__u);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
790 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
791 this->_M_construct(std::forward<_Up>(__u));
111
kono
parents:
diff changeset
792
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
793 return *this;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
794 }
111
kono
parents:
diff changeset
795
kono
parents:
diff changeset
796 template<typename _Up>
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
797 enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
798 is_constructible<_Tp, const _Up&>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
799 is_assignable<_Tp&, _Up>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
800 __not_<__converts_from_optional<_Tp, _Up>>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
801 __not_<__assigns_from_optional<_Tp, _Up>>>,
111
kono
parents:
diff changeset
802 optional&>
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
803 operator=(const optional<_Up>& __u)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
804 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
805 if (__u)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
806 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
807 if (this->_M_is_engaged())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
808 this->_M_get() = *__u;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
809 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
810 this->_M_construct(*__u);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
811 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
812 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
813 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
814 this->_M_reset();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
815 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
816 return *this;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
817 }
111
kono
parents:
diff changeset
818
kono
parents:
diff changeset
819 template<typename _Up>
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
820 enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
821 is_constructible<_Tp, _Up>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
822 is_assignable<_Tp&, _Up>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
823 __not_<__converts_from_optional<_Tp, _Up>>,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
824 __not_<__assigns_from_optional<_Tp, _Up>>>,
111
kono
parents:
diff changeset
825 optional&>
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
826 operator=(optional<_Up>&& __u)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
827 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
828 if (__u)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
829 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
830 if (this->_M_is_engaged())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
831 this->_M_get() = std::move(*__u);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
832 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
833 this->_M_construct(std::move(*__u));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
834 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
835 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
836 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
837 this->_M_reset();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
838 }
111
kono
parents:
diff changeset
839
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
840 return *this;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
841 }
111
kono
parents:
diff changeset
842
kono
parents:
diff changeset
843 template<typename... _Args>
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
844 enable_if_t<is_constructible_v<_Tp, _Args&&...>, _Tp&>
111
kono
parents:
diff changeset
845 emplace(_Args&&... __args)
kono
parents:
diff changeset
846 {
kono
parents:
diff changeset
847 this->_M_reset();
kono
parents:
diff changeset
848 this->_M_construct(std::forward<_Args>(__args)...);
kono
parents:
diff changeset
849 return this->_M_get();
kono
parents:
diff changeset
850 }
kono
parents:
diff changeset
851
kono
parents:
diff changeset
852 template<typename _Up, typename... _Args>
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
853 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
854 _Args&&...>, _Tp&>
111
kono
parents:
diff changeset
855 emplace(initializer_list<_Up> __il, _Args&&... __args)
kono
parents:
diff changeset
856 {
kono
parents:
diff changeset
857 this->_M_reset();
kono
parents:
diff changeset
858 this->_M_construct(__il, std::forward<_Args>(__args)...);
kono
parents:
diff changeset
859 return this->_M_get();
kono
parents:
diff changeset
860 }
kono
parents:
diff changeset
861
kono
parents:
diff changeset
862 // Destructor is implicit, implemented in _Optional_base.
kono
parents:
diff changeset
863
kono
parents:
diff changeset
864 // Swap.
kono
parents:
diff changeset
865 void
kono
parents:
diff changeset
866 swap(optional& __other)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
867 noexcept(is_nothrow_move_constructible_v<_Tp>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
868 && is_nothrow_swappable_v<_Tp>)
111
kono
parents:
diff changeset
869 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
870 using std::swap;
111
kono
parents:
diff changeset
871
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
872 if (this->_M_is_engaged() && __other._M_is_engaged())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
873 swap(this->_M_get(), __other._M_get());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
874 else if (this->_M_is_engaged())
111
kono
parents:
diff changeset
875 {
kono
parents:
diff changeset
876 __other._M_construct(std::move(this->_M_get()));
kono
parents:
diff changeset
877 this->_M_destruct();
kono
parents:
diff changeset
878 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
879 else if (__other._M_is_engaged())
111
kono
parents:
diff changeset
880 {
kono
parents:
diff changeset
881 this->_M_construct(std::move(__other._M_get()));
kono
parents:
diff changeset
882 __other._M_destruct();
kono
parents:
diff changeset
883 }
kono
parents:
diff changeset
884 }
kono
parents:
diff changeset
885
kono
parents:
diff changeset
886 // Observers.
kono
parents:
diff changeset
887 constexpr const _Tp*
kono
parents:
diff changeset
888 operator->() const
kono
parents:
diff changeset
889 { return std::__addressof(this->_M_get()); }
kono
parents:
diff changeset
890
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
891 constexpr _Tp*
111
kono
parents:
diff changeset
892 operator->()
kono
parents:
diff changeset
893 { return std::__addressof(this->_M_get()); }
kono
parents:
diff changeset
894
kono
parents:
diff changeset
895 constexpr const _Tp&
kono
parents:
diff changeset
896 operator*() const&
kono
parents:
diff changeset
897 { return this->_M_get(); }
kono
parents:
diff changeset
898
kono
parents:
diff changeset
899 constexpr _Tp&
kono
parents:
diff changeset
900 operator*()&
kono
parents:
diff changeset
901 { return this->_M_get(); }
kono
parents:
diff changeset
902
kono
parents:
diff changeset
903 constexpr _Tp&&
kono
parents:
diff changeset
904 operator*()&&
kono
parents:
diff changeset
905 { return std::move(this->_M_get()); }
kono
parents:
diff changeset
906
kono
parents:
diff changeset
907 constexpr const _Tp&&
kono
parents:
diff changeset
908 operator*() const&&
kono
parents:
diff changeset
909 { return std::move(this->_M_get()); }
kono
parents:
diff changeset
910
kono
parents:
diff changeset
911 constexpr explicit operator bool() const noexcept
kono
parents:
diff changeset
912 { return this->_M_is_engaged(); }
kono
parents:
diff changeset
913
kono
parents:
diff changeset
914 constexpr bool has_value() const noexcept
kono
parents:
diff changeset
915 { return this->_M_is_engaged(); }
kono
parents:
diff changeset
916
kono
parents:
diff changeset
917 constexpr const _Tp&
kono
parents:
diff changeset
918 value() const&
kono
parents:
diff changeset
919 {
kono
parents:
diff changeset
920 return this->_M_is_engaged()
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
921 ? this->_M_get()
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
922 : (__throw_bad_optional_access(), this->_M_get());
111
kono
parents:
diff changeset
923 }
kono
parents:
diff changeset
924
kono
parents:
diff changeset
925 constexpr _Tp&
kono
parents:
diff changeset
926 value()&
kono
parents:
diff changeset
927 {
kono
parents:
diff changeset
928 return this->_M_is_engaged()
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
929 ? this->_M_get()
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
930 : (__throw_bad_optional_access(), this->_M_get());
111
kono
parents:
diff changeset
931 }
kono
parents:
diff changeset
932
kono
parents:
diff changeset
933 constexpr _Tp&&
kono
parents:
diff changeset
934 value()&&
kono
parents:
diff changeset
935 {
kono
parents:
diff changeset
936 return this->_M_is_engaged()
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
937 ? std::move(this->_M_get())
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
938 : (__throw_bad_optional_access(), std::move(this->_M_get()));
111
kono
parents:
diff changeset
939 }
kono
parents:
diff changeset
940
kono
parents:
diff changeset
941 constexpr const _Tp&&
kono
parents:
diff changeset
942 value() const&&
kono
parents:
diff changeset
943 {
kono
parents:
diff changeset
944 return this->_M_is_engaged()
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
945 ? std::move(this->_M_get())
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
946 : (__throw_bad_optional_access(), std::move(this->_M_get()));
111
kono
parents:
diff changeset
947 }
kono
parents:
diff changeset
948
kono
parents:
diff changeset
949 template<typename _Up>
kono
parents:
diff changeset
950 constexpr _Tp
kono
parents:
diff changeset
951 value_or(_Up&& __u) const&
kono
parents:
diff changeset
952 {
kono
parents:
diff changeset
953 static_assert(is_copy_constructible_v<_Tp>);
kono
parents:
diff changeset
954 static_assert(is_convertible_v<_Up&&, _Tp>);
kono
parents:
diff changeset
955
kono
parents:
diff changeset
956 return this->_M_is_engaged()
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
957 ? this->_M_get() : static_cast<_Tp>(std::forward<_Up>(__u));
111
kono
parents:
diff changeset
958 }
kono
parents:
diff changeset
959
kono
parents:
diff changeset
960 template<typename _Up>
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
961 constexpr _Tp
111
kono
parents:
diff changeset
962 value_or(_Up&& __u) &&
kono
parents:
diff changeset
963 {
kono
parents:
diff changeset
964 static_assert(is_move_constructible_v<_Tp>);
kono
parents:
diff changeset
965 static_assert(is_convertible_v<_Up&&, _Tp>);
kono
parents:
diff changeset
966
kono
parents:
diff changeset
967 return this->_M_is_engaged()
kono
parents:
diff changeset
968 ? std::move(this->_M_get())
kono
parents:
diff changeset
969 : static_cast<_Tp>(std::forward<_Up>(__u));
kono
parents:
diff changeset
970 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
971
111
kono
parents:
diff changeset
972 void reset() noexcept { this->_M_reset(); }
kono
parents:
diff changeset
973 };
kono
parents:
diff changeset
974
kono
parents:
diff changeset
975 template<typename _Tp>
kono
parents:
diff changeset
976 using __optional_relop_t =
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
977 enable_if_t<is_convertible<_Tp, bool>::value, bool>;
111
kono
parents:
diff changeset
978
kono
parents:
diff changeset
979 // Comparisons between optional values.
kono
parents:
diff changeset
980 template<typename _Tp, typename _Up>
kono
parents:
diff changeset
981 constexpr auto
kono
parents:
diff changeset
982 operator==(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
kono
parents:
diff changeset
983 -> __optional_relop_t<decltype(declval<_Tp>() == declval<_Up>())>
kono
parents:
diff changeset
984 {
kono
parents:
diff changeset
985 return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
kono
parents:
diff changeset
986 && (!__lhs || *__lhs == *__rhs);
kono
parents:
diff changeset
987 }
kono
parents:
diff changeset
988
kono
parents:
diff changeset
989 template<typename _Tp, typename _Up>
kono
parents:
diff changeset
990 constexpr auto
kono
parents:
diff changeset
991 operator!=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
kono
parents:
diff changeset
992 -> __optional_relop_t<decltype(declval<_Tp>() != declval<_Up>())>
kono
parents:
diff changeset
993 {
kono
parents:
diff changeset
994 return static_cast<bool>(__lhs) != static_cast<bool>(__rhs)
kono
parents:
diff changeset
995 || (static_cast<bool>(__lhs) && *__lhs != *__rhs);
kono
parents:
diff changeset
996 }
kono
parents:
diff changeset
997
kono
parents:
diff changeset
998 template<typename _Tp, typename _Up>
kono
parents:
diff changeset
999 constexpr auto
kono
parents:
diff changeset
1000 operator<(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
kono
parents:
diff changeset
1001 -> __optional_relop_t<decltype(declval<_Tp>() < declval<_Up>())>
kono
parents:
diff changeset
1002 {
kono
parents:
diff changeset
1003 return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
kono
parents:
diff changeset
1004 }
kono
parents:
diff changeset
1005
kono
parents:
diff changeset
1006 template<typename _Tp, typename _Up>
kono
parents:
diff changeset
1007 constexpr auto
kono
parents:
diff changeset
1008 operator>(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
kono
parents:
diff changeset
1009 -> __optional_relop_t<decltype(declval<_Tp>() > declval<_Up>())>
kono
parents:
diff changeset
1010 {
kono
parents:
diff changeset
1011 return static_cast<bool>(__lhs) && (!__rhs || *__lhs > *__rhs);
kono
parents:
diff changeset
1012 }
kono
parents:
diff changeset
1013
kono
parents:
diff changeset
1014 template<typename _Tp, typename _Up>
kono
parents:
diff changeset
1015 constexpr auto
kono
parents:
diff changeset
1016 operator<=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
kono
parents:
diff changeset
1017 -> __optional_relop_t<decltype(declval<_Tp>() <= declval<_Up>())>
kono
parents:
diff changeset
1018 {
kono
parents:
diff changeset
1019 return !__lhs || (static_cast<bool>(__rhs) && *__lhs <= *__rhs);
kono
parents:
diff changeset
1020 }
kono
parents:
diff changeset
1021
kono
parents:
diff changeset
1022 template<typename _Tp, typename _Up>
kono
parents:
diff changeset
1023 constexpr auto
kono
parents:
diff changeset
1024 operator>=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
kono
parents:
diff changeset
1025 -> __optional_relop_t<decltype(declval<_Tp>() >= declval<_Up>())>
kono
parents:
diff changeset
1026 {
kono
parents:
diff changeset
1027 return !__rhs || (static_cast<bool>(__lhs) && *__lhs >= *__rhs);
kono
parents:
diff changeset
1028 }
kono
parents:
diff changeset
1029
kono
parents:
diff changeset
1030 // Comparisons with nullopt.
kono
parents:
diff changeset
1031 template<typename _Tp>
kono
parents:
diff changeset
1032 constexpr bool
kono
parents:
diff changeset
1033 operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept
kono
parents:
diff changeset
1034 { return !__lhs; }
kono
parents:
diff changeset
1035
kono
parents:
diff changeset
1036 template<typename _Tp>
kono
parents:
diff changeset
1037 constexpr bool
kono
parents:
diff changeset
1038 operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept
kono
parents:
diff changeset
1039 { return !__rhs; }
kono
parents:
diff changeset
1040
kono
parents:
diff changeset
1041 template<typename _Tp>
kono
parents:
diff changeset
1042 constexpr bool
kono
parents:
diff changeset
1043 operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept
kono
parents:
diff changeset
1044 { return static_cast<bool>(__lhs); }
kono
parents:
diff changeset
1045
kono
parents:
diff changeset
1046 template<typename _Tp>
kono
parents:
diff changeset
1047 constexpr bool
kono
parents:
diff changeset
1048 operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept
kono
parents:
diff changeset
1049 { return static_cast<bool>(__rhs); }
kono
parents:
diff changeset
1050
kono
parents:
diff changeset
1051 template<typename _Tp>
kono
parents:
diff changeset
1052 constexpr bool
kono
parents:
diff changeset
1053 operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
kono
parents:
diff changeset
1054 { return false; }
kono
parents:
diff changeset
1055
kono
parents:
diff changeset
1056 template<typename _Tp>
kono
parents:
diff changeset
1057 constexpr bool
kono
parents:
diff changeset
1058 operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
kono
parents:
diff changeset
1059 { return static_cast<bool>(__rhs); }
kono
parents:
diff changeset
1060
kono
parents:
diff changeset
1061 template<typename _Tp>
kono
parents:
diff changeset
1062 constexpr bool
kono
parents:
diff changeset
1063 operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept
kono
parents:
diff changeset
1064 { return static_cast<bool>(__lhs); }
kono
parents:
diff changeset
1065
kono
parents:
diff changeset
1066 template<typename _Tp>
kono
parents:
diff changeset
1067 constexpr bool
kono
parents:
diff changeset
1068 operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
kono
parents:
diff changeset
1069 { return false; }
kono
parents:
diff changeset
1070
kono
parents:
diff changeset
1071 template<typename _Tp>
kono
parents:
diff changeset
1072 constexpr bool
kono
parents:
diff changeset
1073 operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept
kono
parents:
diff changeset
1074 { return !__lhs; }
kono
parents:
diff changeset
1075
kono
parents:
diff changeset
1076 template<typename _Tp>
kono
parents:
diff changeset
1077 constexpr bool
kono
parents:
diff changeset
1078 operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
kono
parents:
diff changeset
1079 { return true; }
kono
parents:
diff changeset
1080
kono
parents:
diff changeset
1081 template<typename _Tp>
kono
parents:
diff changeset
1082 constexpr bool
kono
parents:
diff changeset
1083 operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
kono
parents:
diff changeset
1084 { return true; }
kono
parents:
diff changeset
1085
kono
parents:
diff changeset
1086 template<typename _Tp>
kono
parents:
diff changeset
1087 constexpr bool
kono
parents:
diff changeset
1088 operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept
kono
parents:
diff changeset
1089 { return !__rhs; }
kono
parents:
diff changeset
1090
kono
parents:
diff changeset
1091 // Comparisons with value type.
kono
parents:
diff changeset
1092 template<typename _Tp, typename _Up>
kono
parents:
diff changeset
1093 constexpr auto
kono
parents:
diff changeset
1094 operator==(const optional<_Tp>& __lhs, const _Up& __rhs)
kono
parents:
diff changeset
1095 -> __optional_relop_t<decltype(declval<_Tp>() == declval<_Up>())>
kono
parents:
diff changeset
1096 { return __lhs && *__lhs == __rhs; }
kono
parents:
diff changeset
1097
kono
parents:
diff changeset
1098 template<typename _Tp, typename _Up>
kono
parents:
diff changeset
1099 constexpr auto
kono
parents:
diff changeset
1100 operator==(const _Up& __lhs, const optional<_Tp>& __rhs)
kono
parents:
diff changeset
1101 -> __optional_relop_t<decltype(declval<_Up>() == declval<_Tp>())>
kono
parents:
diff changeset
1102 { return __rhs && __lhs == *__rhs; }
kono
parents:
diff changeset
1103
kono
parents:
diff changeset
1104 template<typename _Tp, typename _Up>
kono
parents:
diff changeset
1105 constexpr auto
kono
parents:
diff changeset
1106 operator!=(const optional<_Tp>& __lhs, const _Up& __rhs)
kono
parents:
diff changeset
1107 -> __optional_relop_t<decltype(declval<_Tp>() != declval<_Up>())>
kono
parents:
diff changeset
1108 { return !__lhs || *__lhs != __rhs; }
kono
parents:
diff changeset
1109
kono
parents:
diff changeset
1110 template<typename _Tp, typename _Up>
kono
parents:
diff changeset
1111 constexpr auto
kono
parents:
diff changeset
1112 operator!=(const _Up& __lhs, const optional<_Tp>& __rhs)
kono
parents:
diff changeset
1113 -> __optional_relop_t<decltype(declval<_Up>() != declval<_Tp>())>
kono
parents:
diff changeset
1114 { return !__rhs || __lhs != *__rhs; }
kono
parents:
diff changeset
1115
kono
parents:
diff changeset
1116 template<typename _Tp, typename _Up>
kono
parents:
diff changeset
1117 constexpr auto
kono
parents:
diff changeset
1118 operator<(const optional<_Tp>& __lhs, const _Up& __rhs)
kono
parents:
diff changeset
1119 -> __optional_relop_t<decltype(declval<_Tp>() < declval<_Up>())>
kono
parents:
diff changeset
1120 { return !__lhs || *__lhs < __rhs; }
kono
parents:
diff changeset
1121
kono
parents:
diff changeset
1122 template<typename _Tp, typename _Up>
kono
parents:
diff changeset
1123 constexpr auto
kono
parents:
diff changeset
1124 operator<(const _Up& __lhs, const optional<_Tp>& __rhs)
kono
parents:
diff changeset
1125 -> __optional_relop_t<decltype(declval<_Up>() < declval<_Tp>())>
kono
parents:
diff changeset
1126 { return __rhs && __lhs < *__rhs; }
kono
parents:
diff changeset
1127
kono
parents:
diff changeset
1128 template<typename _Tp, typename _Up>
kono
parents:
diff changeset
1129 constexpr auto
kono
parents:
diff changeset
1130 operator>(const optional<_Tp>& __lhs, const _Up& __rhs)
kono
parents:
diff changeset
1131 -> __optional_relop_t<decltype(declval<_Tp>() > declval<_Up>())>
kono
parents:
diff changeset
1132 { return __lhs && *__lhs > __rhs; }
kono
parents:
diff changeset
1133
kono
parents:
diff changeset
1134 template<typename _Tp, typename _Up>
kono
parents:
diff changeset
1135 constexpr auto
kono
parents:
diff changeset
1136 operator>(const _Up& __lhs, const optional<_Tp>& __rhs)
kono
parents:
diff changeset
1137 -> __optional_relop_t<decltype(declval<_Up>() > declval<_Tp>())>
kono
parents:
diff changeset
1138 { return !__rhs || __lhs > *__rhs; }
kono
parents:
diff changeset
1139
kono
parents:
diff changeset
1140 template<typename _Tp, typename _Up>
kono
parents:
diff changeset
1141 constexpr auto
kono
parents:
diff changeset
1142 operator<=(const optional<_Tp>& __lhs, const _Up& __rhs)
kono
parents:
diff changeset
1143 -> __optional_relop_t<decltype(declval<_Tp>() <= declval<_Up>())>
kono
parents:
diff changeset
1144 { return !__lhs || *__lhs <= __rhs; }
kono
parents:
diff changeset
1145
kono
parents:
diff changeset
1146 template<typename _Tp, typename _Up>
kono
parents:
diff changeset
1147 constexpr auto
kono
parents:
diff changeset
1148 operator<=(const _Up& __lhs, const optional<_Tp>& __rhs)
kono
parents:
diff changeset
1149 -> __optional_relop_t<decltype(declval<_Up>() <= declval<_Tp>())>
kono
parents:
diff changeset
1150 { return __rhs && __lhs <= *__rhs; }
kono
parents:
diff changeset
1151
kono
parents:
diff changeset
1152 template<typename _Tp, typename _Up>
kono
parents:
diff changeset
1153 constexpr auto
kono
parents:
diff changeset
1154 operator>=(const optional<_Tp>& __lhs, const _Up& __rhs)
kono
parents:
diff changeset
1155 -> __optional_relop_t<decltype(declval<_Tp>() >= declval<_Up>())>
kono
parents:
diff changeset
1156 { return __lhs && *__lhs >= __rhs; }
kono
parents:
diff changeset
1157
kono
parents:
diff changeset
1158 template<typename _Tp, typename _Up>
kono
parents:
diff changeset
1159 constexpr auto
kono
parents:
diff changeset
1160 operator>=(const _Up& __lhs, const optional<_Tp>& __rhs)
kono
parents:
diff changeset
1161 -> __optional_relop_t<decltype(declval<_Up>() >= declval<_Tp>())>
kono
parents:
diff changeset
1162 { return !__rhs || __lhs >= *__rhs; }
kono
parents:
diff changeset
1163
kono
parents:
diff changeset
1164 // Swap and creation functions.
kono
parents:
diff changeset
1165
kono
parents:
diff changeset
1166 // _GLIBCXX_RESOLVE_LIB_DEFECTS
kono
parents:
diff changeset
1167 // 2748. swappable traits for optionals
kono
parents:
diff changeset
1168 template<typename _Tp>
kono
parents:
diff changeset
1169 inline enable_if_t<is_move_constructible_v<_Tp> && is_swappable_v<_Tp>>
kono
parents:
diff changeset
1170 swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
kono
parents:
diff changeset
1171 noexcept(noexcept(__lhs.swap(__rhs)))
kono
parents:
diff changeset
1172 { __lhs.swap(__rhs); }
kono
parents:
diff changeset
1173
kono
parents:
diff changeset
1174 template<typename _Tp>
kono
parents:
diff changeset
1175 enable_if_t<!(is_move_constructible_v<_Tp> && is_swappable_v<_Tp>)>
kono
parents:
diff changeset
1176 swap(optional<_Tp>&, optional<_Tp>&) = delete;
kono
parents:
diff changeset
1177
kono
parents:
diff changeset
1178 template<typename _Tp>
kono
parents:
diff changeset
1179 constexpr optional<decay_t<_Tp>>
kono
parents:
diff changeset
1180 make_optional(_Tp&& __t)
kono
parents:
diff changeset
1181 { return optional<decay_t<_Tp>> { std::forward<_Tp>(__t) }; }
kono
parents:
diff changeset
1182
kono
parents:
diff changeset
1183 template<typename _Tp, typename ..._Args>
kono
parents:
diff changeset
1184 constexpr optional<_Tp>
kono
parents:
diff changeset
1185 make_optional(_Args&&... __args)
kono
parents:
diff changeset
1186 { return optional<_Tp> { in_place, std::forward<_Args>(__args)... }; }
kono
parents:
diff changeset
1187
kono
parents:
diff changeset
1188 template<typename _Tp, typename _Up, typename ..._Args>
kono
parents:
diff changeset
1189 constexpr optional<_Tp>
kono
parents:
diff changeset
1190 make_optional(initializer_list<_Up> __il, _Args&&... __args)
kono
parents:
diff changeset
1191 { return optional<_Tp> { in_place, __il, std::forward<_Args>(__args)... }; }
kono
parents:
diff changeset
1192
kono
parents:
diff changeset
1193 // Hash.
kono
parents:
diff changeset
1194
kono
parents:
diff changeset
1195 template<typename _Tp, typename _Up = remove_const_t<_Tp>,
kono
parents:
diff changeset
1196 bool = __poison_hash<_Up>::__enable_hash_call>
kono
parents:
diff changeset
1197 struct __optional_hash_call_base
kono
parents:
diff changeset
1198 {
kono
parents:
diff changeset
1199 size_t
kono
parents:
diff changeset
1200 operator()(const optional<_Tp>& __t) const
kono
parents:
diff changeset
1201 noexcept(noexcept(hash<_Up>{}(*__t)))
kono
parents:
diff changeset
1202 {
kono
parents:
diff changeset
1203 // We pick an arbitrary hash for disengaged optionals which hopefully
kono
parents:
diff changeset
1204 // usual values of _Tp won't typically hash to.
kono
parents:
diff changeset
1205 constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333);
kono
parents:
diff changeset
1206 return __t ? hash<_Up>{}(*__t) : __magic_disengaged_hash;
kono
parents:
diff changeset
1207 }
kono
parents:
diff changeset
1208 };
kono
parents:
diff changeset
1209
kono
parents:
diff changeset
1210 template<typename _Tp, typename _Up>
kono
parents:
diff changeset
1211 struct __optional_hash_call_base<_Tp, _Up, false> {};
kono
parents:
diff changeset
1212
kono
parents:
diff changeset
1213 template<typename _Tp>
kono
parents:
diff changeset
1214 struct hash<optional<_Tp>>
kono
parents:
diff changeset
1215 : private __poison_hash<remove_const_t<_Tp>>,
kono
parents:
diff changeset
1216 public __optional_hash_call_base<_Tp>
kono
parents:
diff changeset
1217 {
kono
parents:
diff changeset
1218 using result_type [[__deprecated__]] = size_t;
kono
parents:
diff changeset
1219 using argument_type [[__deprecated__]] = optional<_Tp>;
kono
parents:
diff changeset
1220 };
kono
parents:
diff changeset
1221
kono
parents:
diff changeset
1222 template<typename _Tp>
kono
parents:
diff changeset
1223 struct __is_fast_hash<hash<optional<_Tp>>> : __is_fast_hash<hash<_Tp>>
kono
parents:
diff changeset
1224 { };
kono
parents:
diff changeset
1225
kono
parents:
diff changeset
1226 /// @}
kono
parents:
diff changeset
1227
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1228 #if __cpp_deduction_guides >= 201606
111
kono
parents:
diff changeset
1229 template <typename _Tp> optional(_Tp) -> optional<_Tp>;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1230 #endif
111
kono
parents:
diff changeset
1231
kono
parents:
diff changeset
1232 _GLIBCXX_END_NAMESPACE_VERSION
kono
parents:
diff changeset
1233 } // namespace std
kono
parents:
diff changeset
1234
kono
parents:
diff changeset
1235 #endif // C++17
kono
parents:
diff changeset
1236
kono
parents:
diff changeset
1237 #endif // _GLIBCXX_OPTIONAL