Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Side by Side Diff: third_party/WebKit/Source/wtf/Variant.h

Issue 2591803002: NOT FOR LANDING: Thread the needle through all webmodules.
Patch Set: AddEventListener sketched out. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2015, Just Software Solutions Ltd
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or
5 // without modification, are permitted provided that the
6 // following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer.
11 //
12 // 2. Redistributions in binary form must reproduce the above
13 // copyright notice, this list of conditions and the following
14 // disclaimer in the documentation and/or other materials
15 // provided with the distribution.
16 //
17 // 3. Neither the name of the copyright holder nor the names of
18 // its contributors may be used to endorse or promote products
19 // derived from this software without specific prior written
20 // permission.
21 //
22 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
23 // CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
27 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
33 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
34 // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
36 // Copied from https://bitbucket.org/anthonyw/variant/src
37 // (5bce47fa788648f79e5ea1d77b0eef2e8f0b2999)
38
39 // Modified to make it compile with exceptions disabled.
40
41 #ifndef WTF_VARIANT_H
42 #define WTF_VARIANT_H
43
44 #include <limits.h>
45 #include <stddef.h>
46 #include <wtf/Compiler.h>
47 #include <wtf/StdLibExtras.h>
48 #include <functional>
49 #include <new>
50 #include <stdexcept>
51 #include <string>
52 #include <type_traits>
53 #include <utility>
54
55 #if COMPILER(MSVC)
56 #pragma warning(push)
57 #pragma warning(disable : 4245)
58 #pragma warning(disable : 4521)
59 #pragma warning(disable : 4522)
60 #pragma warning(disable : 4814)
61 #endif
62
63 namespace std {
64
65 template <class T>
66 using add_const_t = typename std::add_const<T>::type;
67
68 template <class T>
69 using add_pointer_t = typename std::add_pointer<T>::type;
70
71 template <class T>
72 using add_volatile_t = typename std::add_volatile<T>::type;
73 }
74
75 namespace WTF {
76
77 #define __THROW_EXCEPTION(__exception) \
78 do { \
79 (void)__exception; \
80 CRASH(); \
81 } while (0);
82 #define __NOEXCEPT
83 #define __NOEXCEPT_(...)
84
85 struct __variant_in_place_private {
86 template <typename>
87 struct __type_holder;
88
89 template <size_t>
90 struct __value_holder;
91 };
92
93 struct variant_in_place_tag {
94 variant_in_place_tag() = delete;
95 };
96
97 using variant_in_place_t =
98 variant_in_place_tag (&)(__variant_in_place_private&);
99
100 template <class _Type>
101 using variant_in_place_type_t =
102 variant_in_place_tag (&)(__variant_in_place_private::__type_holder<_Type>&);
103
104 template <size_t _Index>
105 using variant_in_place_index_t = variant_in_place_tag (&)(
106 __variant_in_place_private::__value_holder<_Index>&);
107
108 variant_in_place_tag variant_in_place(__variant_in_place_private&);
109
110 template <class _Type>
111 variant_in_place_tag variant_in_place(
112 __variant_in_place_private::__type_holder<_Type>&) {
113 __THROW_EXCEPTION(__variant_in_place_private());
114 }
115
116 template <size_t _Index>
117 variant_in_place_tag variant_in_place(
118 __variant_in_place_private::__value_holder<_Index>&) {
119 __THROW_EXCEPTION(__variant_in_place_private());
120 }
121
122 class bad_variant_access : public std::logic_error {
123 public:
124 explicit bad_variant_access(const std::string& what_arg)
125 : std::logic_error(what_arg) {}
126 explicit bad_variant_access(const char* what_arg)
127 : std::logic_error(what_arg) {}
128 };
129
130 template <typename T>
131 inline T __throw_bad_variant_access(const char* what_arg) {
132 __THROW_EXCEPTION(bad_variant_access(what_arg))
133 }
134
135 template <ptrdiff_t _Offset, typename _Type, typename... _Types>
136 struct __type_index_helper;
137
138 template <ptrdiff_t _Offset, typename _Type, typename _Head, typename... _Rest>
139 struct __type_index_helper<_Offset, _Type, _Head, _Rest...> {
140 static constexpr ptrdiff_t __value =
141 __type_index_helper<_Offset + 1, _Type, _Rest...>::__value;
142 };
143
144 template <ptrdiff_t _Offset, typename _Type, typename... _Rest>
145 struct __type_index_helper<_Offset, _Type, _Type, _Rest...> {
146 static constexpr ptrdiff_t __value = _Offset;
147 };
148
149 template <typename _Type, typename... _Types>
150 struct __type_index {
151 static constexpr ptrdiff_t __value =
152 __type_index_helper<0, _Type, _Types...>::__value;
153 };
154
155 template <ptrdiff_t _Index, typename... _Types>
156 struct __indexed_type;
157
158 template <typename _Head, typename... _Rest>
159 struct __indexed_type<0, _Head, _Rest...> {
160 typedef _Head __type;
161 };
162
163 template <typename _Head, typename... _Rest>
164 struct __indexed_type<-1, _Head, _Rest...> {
165 typedef void __type;
166 };
167
168 template <ptrdiff_t _Index, typename _Head, typename... _Rest>
169 struct __indexed_type<_Index, _Head, _Rest...> {
170 typedef typename __indexed_type<_Index - 1, _Rest...>::__type __type;
171 };
172
173 template <ptrdiff_t _Index, typename... _Types>
174 struct __next_index {
175 static constexpr ptrdiff_t __value =
176 (_Index >= ptrdiff_t(sizeof...(_Types) - 1)) ? -1 : _Index + 1;
177 };
178
179 template <typename... _Types>
180 class Variant;
181
182 template <typename>
183 struct variant_size;
184
185 template <typename _Type>
186 struct variant_size<const _Type> : variant_size<_Type> {};
187
188 template <typename _Type>
189 struct variant_size<volatile _Type> : variant_size<_Type> {};
190
191 template <typename _Type>
192 struct variant_size<const volatile _Type> : variant_size<_Type> {};
193
194 template <typename... _Types>
195 struct variant_size<Variant<_Types...>>
196 : std::integral_constant<size_t, sizeof...(_Types)> {};
197
198 template <size_t _Index, typename _Type>
199 struct variant_alternative;
200
201 template <size_t _Index, typename _Type>
202 using variant_alternative_t = typename variant_alternative<_Index, _Type>::type;
203
204 template <size_t _Index, typename _Type>
205 struct variant_alternative<_Index, const _Type> {
206 using type = std::add_const_t<variant_alternative_t<_Index, _Type>>;
207 };
208
209 template <size_t _Index, typename _Type>
210 struct variant_alternative<_Index, volatile _Type> {
211 using type = std::add_volatile_t<variant_alternative_t<_Index, _Type>>;
212 };
213
214 template <size_t _Index, typename _Type>
215 struct variant_alternative<_Index, volatile const _Type> {
216 using type = std::add_volatile_t<
217 std::add_const_t<variant_alternative_t<_Index, _Type>>>;
218 };
219
220 template <size_t _Index, typename... _Types>
221 struct variant_alternative<_Index, Variant<_Types...>> {
222 using type = typename __indexed_type<_Index, _Types...>::__type;
223 };
224
225 constexpr size_t variant_npos = -1;
226
227 template <typename _Type, typename... _Types>
228 constexpr _Type& get(Variant<_Types...>&);
229
230 template <typename _Type, typename... _Types>
231 constexpr _Type const& get(Variant<_Types...> const&);
232
233 template <typename _Type, typename... _Types>
234 constexpr _Type&& get(Variant<_Types...>&&);
235
236 template <typename _Type, typename... _Types>
237 constexpr const _Type&& get(Variant<_Types...> const&&);
238
239 template <ptrdiff_t _Index, typename... _Types>
240 constexpr typename __indexed_type<_Index, _Types...>::__type& get(
241 Variant<_Types...>&);
242
243 template <ptrdiff_t _Index, typename... _Types>
244 constexpr typename __indexed_type<_Index, _Types...>::__type&& get(
245 Variant<_Types...>&&);
246
247 template <ptrdiff_t _Index, typename... _Types>
248 constexpr typename __indexed_type<_Index, _Types...>::__type const& get(
249 Variant<_Types...> const&);
250
251 template <ptrdiff_t _Index, typename... _Types>
252 constexpr const typename __indexed_type<_Index, _Types...>::__type&& get(
253 Variant<_Types...> const&&);
254
255 template <typename _Type, typename... _Types>
256 constexpr std::add_pointer_t<_Type> get_if(Variant<_Types...>&);
257
258 template <typename _Type, typename... _Types>
259 constexpr std::add_pointer_t<_Type const> get_if(Variant<_Types...> const&);
260
261 template <ptrdiff_t _Index, typename... _Types>
262 constexpr std::add_pointer_t<typename __indexed_type<_Index, _Types...>::__type>
263 get_if(Variant<_Types...>&);
264
265 template <ptrdiff_t _Index, typename... _Types>
266 constexpr std::add_pointer_t<
267 typename __indexed_type<_Index, _Types...>::__type const>
268 get_if(Variant<_Types...> const&);
269
270 template <ptrdiff_t _Index, typename... _Types>
271 struct __variant_accessor;
272
273 template <size_t __count,
274 bool __larger_than_char = (__count > SCHAR_MAX),
275 bool __larger_than_short = (__count > SHRT_MAX),
276 bool __larger_than_int = (__count > INT_MAX)>
277 struct __discriminator_type {
278 typedef signed char __type;
279 };
280
281 template <size_t __count>
282 struct __discriminator_type<__count, true, false, false> {
283 typedef signed short __type;
284 };
285
286 template <size_t __count>
287 struct __discriminator_type<__count, true, true, false> {
288 typedef int __type;
289 };
290 template <size_t __count>
291 struct __discriminator_type<__count, true, true, true> {
292 typedef signed long __type;
293 };
294
295 template <typename _Type>
296 struct __stored_type {
297 typedef _Type __type;
298 };
299
300 template <typename _Type>
301 struct __stored_type<_Type&> {
302 typedef _Type* __type;
303 };
304
305 template <typename... _Types>
306 struct __all_trivially_destructible;
307
308 template <>
309 struct __all_trivially_destructible<> {
310 static constexpr bool __value = true;
311 };
312
313 template <typename _Type>
314 struct __all_trivially_destructible<_Type> {
315 static constexpr bool __value = std::is_trivially_destructible<
316 typename __stored_type<_Type>::__type>::value;
317 };
318
319 template <typename _Head, typename... _Rest>
320 struct __all_trivially_destructible<_Head, _Rest...> {
321 static constexpr bool __value =
322 __all_trivially_destructible<_Head>::__value &&
323 __all_trivially_destructible<_Rest...>::__value;
324 };
325
326 template <typename _Target, typename... _Args>
327 struct __storage_nothrow_constructible {
328 static const bool __value =
329 std::is_nothrow_constructible<_Target, _Args...>::value;
330 };
331
332 template <typename... _Types>
333 struct __storage_nothrow_move_constructible;
334
335 template <>
336 struct __storage_nothrow_move_constructible<> {
337 static constexpr bool __value = true;
338 };
339
340 template <typename _Type>
341 struct __storage_nothrow_move_constructible<_Type> {
342 static constexpr bool __value = std::is_nothrow_move_constructible<
343 typename __stored_type<_Type>::__type>::value;
344 };
345
346 template <typename _Head, typename... _Rest>
347 struct __storage_nothrow_move_constructible<_Head, _Rest...> {
348 static constexpr bool __value =
349 __storage_nothrow_move_constructible<_Head>::__value &&
350 __storage_nothrow_move_constructible<_Rest...>::__value;
351 };
352
353 template <ptrdiff_t _Index, typename... _Types>
354 struct __other_storage_nothrow_move_constructible;
355
356 template <typename _Head, typename... _Rest>
357 struct __other_storage_nothrow_move_constructible<0, _Head, _Rest...> {
358 static const bool __value =
359 __storage_nothrow_move_constructible<_Rest...>::__value;
360 };
361
362 template <typename _Head, typename... _Rest>
363 struct __other_storage_nothrow_move_constructible<-1, _Head, _Rest...> {
364 static const bool __value =
365 __storage_nothrow_move_constructible<_Head, _Rest...>::__value;
366 };
367
368 template <ptrdiff_t _Index, typename _Head, typename... _Rest>
369 struct __other_storage_nothrow_move_constructible<_Index, _Head, _Rest...> {
370 static const bool __value =
371 __storage_nothrow_move_constructible<_Head>::__value &&
372 __other_storage_nothrow_move_constructible<_Index - 1, _Rest...>::__value;
373 };
374
375 template <ptrdiff_t _Index, typename... _Types>
376 struct __backup_storage_required {
377 static const bool __value =
378 !__storage_nothrow_move_constructible<
379 typename __indexed_type<_Index, _Types...>::__type>::__value &&
380 !__other_storage_nothrow_move_constructible<_Index, _Types...>::__value;
381 };
382
383 template <ptrdiff_t _Index, ptrdiff_t _Count, typename... _Types>
384 struct __any_backup_storage_required_impl {
385 static const bool __value =
386 __backup_storage_required<_Index, _Types...>::__value ||
387 __any_backup_storage_required_impl<_Index + 1, _Count - 1, _Types...>::
388 __value;
389 };
390
391 template <ptrdiff_t _Index, typename... _Types>
392 struct __any_backup_storage_required_impl<_Index, 0, _Types...> {
393 static const bool __value = false;
394 };
395
396 template <typename _Variant>
397 struct __any_backup_storage_required;
398
399 template <typename... _Types>
400 struct __any_backup_storage_required<Variant<_Types...>> {
401 static const bool __value =
402 __any_backup_storage_required_impl<0, sizeof...(_Types), _Types...>::
403 __value;
404 };
405
406 template <typename... _Types>
407 union __variant_data;
408
409 template <typename _Type, bool = std::is_literal_type<_Type>::value>
410 struct __variant_storage {
411 typedef _Type __type;
412
413 static constexpr _Type& __get(__type& __val) { return __val; }
414 static constexpr _Type&& __get_rref(__type& __val) {
415 return std::move(__val);
416 }
417 static constexpr const _Type& __get(__type const& __val) { return __val; }
418 static constexpr const _Type&& __get_rref(__type const& __val) {
419 return std::move(__val);
420 }
421 static void __destroy(__type&) {}
422 };
423
424 template <typename _Type>
425 struct __storage_wrapper {
426 typename std::aligned_storage<sizeof(_Type), alignof(_Type)>::type __storage;
427
428 template <typename... _Args>
429 static constexpr void* __construct(void* __p, _Args&&... __args) {
430 return new (__p) _Type(std::forward<_Args>(__args)...);
431 }
432
433 template <typename _Dummy = _Type>
434 __storage_wrapper(
435 typename std::enable_if<std::is_default_constructible<_Dummy>::value,
436 void (__storage_wrapper::*)()>::type = nullptr) {
437 __construct(&__storage);
438 }
439
440 template <typename _Dummy = _Type>
441 __storage_wrapper(
442 typename std::enable_if<!std::is_default_constructible<_Dummy>::value,
443 void (__storage_wrapper::*)()>::type = nullptr) {}
444
445 template <typename _First, typename... _Args>
446 __storage_wrapper(_First&& __first, _Args&&... __args) {
447 __construct(&__storage, std::forward<_First>(__first),
448 std::forward<_Args>(__args)...);
449 }
450
451 _Type& __get() {
452 return *static_cast<_Type*>(static_cast<void*>(&__storage));
453 }
454 constexpr _Type const& __get() const {
455 return *static_cast<_Type const*>(static_cast<void const*>(&__storage));
456 }
457 void __destroy() { __get().~_Type(); }
458 };
459
460 template <typename _Type>
461 struct __storage_wrapper<_Type&> {
462 _Type* __storage;
463
464 template <typename _Arg>
465 constexpr __storage_wrapper(_Arg& __arg) : __storage(&__arg) {}
466
467 _Type& __get() { return *__storage; }
468 constexpr _Type const& __get() const { return *__storage; }
469 };
470
471 template <typename _Type>
472 struct __variant_storage<_Type, false> {
473 typedef __storage_wrapper<_Type> __type;
474
475 static constexpr _Type& __get(__type& __val) { return __val.__get(); }
476 static constexpr _Type&& __get_rref(__type& __val) {
477 return std::move(__val.__get());
478 }
479 static constexpr const _Type& __get(__type const& __val) {
480 return __val.__get();
481 }
482 static constexpr const _Type&& __get_rref(__type const& __val) {
483 return std::move(__val.__get());
484 }
485 static void __destroy(__type& __val) { __val.__destroy(); }
486 };
487
488 template <typename _Type, bool __b>
489 struct __variant_storage<_Type&, __b> {
490 typedef _Type* __type;
491
492 static constexpr _Type& __get(__type& __val) { return *__val; }
493 static constexpr _Type& __get_rref(__type& __val) { return *__val; }
494 static constexpr _Type& __get(__type const& __val) { return *__val; }
495 static constexpr _Type& __get_rref(__type const& __val) { return *__val; }
496 static void __destroy(__type&) {}
497 };
498
499 template <typename _Type, bool __b>
500 struct __variant_storage<_Type&&, __b> {
501 typedef _Type* __type;
502
503 static constexpr _Type&& __get(__type& __val) {
504 return static_cast<_Type&&>(*__val);
505 }
506 static constexpr _Type&& __get_rref(__type& __val) {
507 return static_cast<_Type&&>(*__val);
508 }
509 static constexpr _Type&& __get(__type const& __val) {
510 return static_cast<_Type&&>(*__val);
511 }
512 static constexpr _Type&& __get_rref(__type const& __val) {
513 return static_cast<_Type&&>(*__val);
514 }
515 static void __destroy(__type&) {}
516 };
517
518 template <>
519 union __variant_data<> {
520 constexpr __variant_data() {}
521 };
522
523 template <typename _Type>
524 union __variant_data<_Type> {
525 typename __variant_storage<_Type>::__type __val;
526 struct __dummy_type {
527 } __dummy;
528
529 constexpr __variant_data() : __dummy() {}
530
531 template <typename... _Args>
532 constexpr __variant_data(variant_in_place_index_t<0>, _Args&&... __args)
533 : __val(std::forward<_Args>(__args)...) {}
534
535 _Type& __get(variant_in_place_index_t<0>) {
536 return __variant_storage<_Type>::__get(__val);
537 }
538 /*constexpr*/ _Type&& __get_rref(variant_in_place_index_t<0>) {
539 return __variant_storage<_Type>::__get_rref(__val);
540 }
541 constexpr const _Type& __get(variant_in_place_index_t<0>) const {
542 return __variant_storage<_Type>::__get(__val);
543 }
544 constexpr const _Type&& __get_rref(variant_in_place_index_t<0>) const {
545 return __variant_storage<_Type>::__get_rref(__val);
546 }
547 void __destroy(variant_in_place_index_t<0>) {
548 __variant_storage<_Type>::__destroy(__val);
549 }
550 };
551
552 template <typename _Type>
553 union __variant_data<_Type&> {
554 typename __variant_storage<_Type&>::__type __val;
555 struct __dummy_type {
556 } __dummy;
557
558 constexpr __variant_data() : __dummy() {}
559
560 template <typename... _Args>
561 constexpr __variant_data(variant_in_place_index_t<0>, _Args&&... __args)
562 : __val(&std::forward<_Args>(__args)...) {}
563
564 _Type& __get(variant_in_place_index_t<0>) {
565 return __variant_storage<_Type&>::__get(__val);
566 }
567 constexpr _Type& __get(variant_in_place_index_t<0>) const {
568 return __variant_storage<_Type&>::__get(__val);
569 }
570
571 _Type& __get_rref(variant_in_place_index_t<0>) {
572 return __variant_storage<_Type&>::__get_rref(__val);
573 }
574 constexpr _Type& __get_rref(variant_in_place_index_t<0>) const {
575 return __variant_storage<_Type&>::__get_rref(__val);
576 }
577
578 void __destroy(variant_in_place_index_t<0>) {
579 __variant_storage<_Type&>::__destroy(__val);
580 }
581 };
582
583 template <typename _Type>
584 union __variant_data<_Type&&> {
585 typename __variant_storage<_Type&&>::__type __val;
586 struct __dummy_type {
587 } __dummy;
588
589 constexpr __variant_data() : __dummy() {}
590
591 template <typename _Arg>
592 __variant_data(variant_in_place_index_t<0>, _Arg&& __arg) : __val(&__arg) {}
593
594 _Type&& __get(variant_in_place_index_t<0>) {
595 return __variant_storage<_Type&&>::__get(__val);
596 }
597 constexpr _Type&& __get(variant_in_place_index_t<0>) const {
598 return __variant_storage<_Type&&>::__get(__val);
599 }
600 _Type&& __get_rref(variant_in_place_index_t<0>) {
601 return __variant_storage<_Type&&>::__get_rref(__val);
602 }
603 constexpr _Type&& __get_rref(variant_in_place_index_t<0>) const {
604 return __variant_storage<_Type&&>::__get_rref(__val);
605 }
606 void __destroy(variant_in_place_index_t<0>) {
607 __variant_storage<_Type&&>::__destroy(__val);
608 }
609 };
610
611 template <typename _Head, typename... _Rest>
612 union __variant_data<_Head, _Rest...> {
613 __variant_data<_Head> __head;
614 __variant_data<_Rest...> __rest;
615
616 constexpr __variant_data() : __head() {}
617
618 template <typename... _Args>
619 constexpr __variant_data(variant_in_place_index_t<0>, _Args&&... __args)
620 : __head(variant_in_place<0>, std::forward<_Args>(__args)...) {}
621 template <size_t _Index, typename... _Args>
622 constexpr __variant_data(variant_in_place_index_t<_Index>, _Args&&... __args)
623 : __rest(variant_in_place<_Index - 1>, std::forward<_Args>(__args)...) {}
624
625 _Head& __get(variant_in_place_index_t<0>) {
626 return __head.__get(variant_in_place<0>);
627 }
628
629 /*constexpr*/ _Head&& __get_rref(variant_in_place_index_t<0>) {
630 return __head.__get_rref(variant_in_place<0>);
631 }
632
633 constexpr const _Head& __get(variant_in_place_index_t<0>) const {
634 return __head.__get(variant_in_place<0>);
635 }
636
637 constexpr const _Head&& __get_rref(variant_in_place_index_t<0>) const {
638 return __head.__get_rref(variant_in_place<0>);
639 }
640
641 template <size_t _Index>
642 typename __indexed_type<_Index - 1, _Rest...>::__type& __get(
643 variant_in_place_index_t<_Index>) {
644 return __rest.__get(variant_in_place<_Index - 1>);
645 }
646
647 template <size_t _Index>
648 /*constexpr*/ typename __indexed_type<_Index - 1, _Rest...>::__type&&
649 __get_rref(variant_in_place_index_t<_Index>) {
650 return __rest.__get_rref(variant_in_place<_Index - 1>);
651 }
652
653 template <size_t _Index>
654 constexpr const typename __indexed_type<_Index - 1, _Rest...>::__type& __get(
655 variant_in_place_index_t<_Index>) const {
656 return __rest.__get(variant_in_place<_Index - 1>);
657 }
658
659 template <size_t _Index>
660 constexpr const typename __indexed_type<_Index - 1, _Rest...>::__type&&
661 __get_rref(variant_in_place_index_t<_Index>) const {
662 return __rest.__get_rref(variant_in_place<_Index - 1>);
663 }
664
665 void __destroy(variant_in_place_index_t<0>) {
666 __head.__destroy(variant_in_place<0>);
667 }
668 template <size_t _Index>
669 void __destroy(variant_in_place_index_t<_Index>) {
670 __rest.__destroy(variant_in_place<_Index - 1>);
671 }
672 };
673
674 template <ptrdiff_t... _Indices>
675 struct __index_sequence {
676 typedef __index_sequence<_Indices..., sizeof...(_Indices)> __next;
677 static constexpr size_t __length = sizeof...(_Indices);
678 };
679
680 template <typename... _Types>
681 struct __type_indices;
682
683 template <>
684 struct __type_indices<> {
685 typedef __index_sequence<> __type;
686 };
687
688 template <typename _Type>
689 struct __type_indices<_Type> {
690 typedef __index_sequence<0> __type;
691 };
692
693 template <typename _Type, typename... _Rest>
694 struct __type_indices<_Type, _Rest...> {
695 typedef typename __type_indices<_Rest...>::__type::__next __type;
696 };
697
698 template <typename _Variant>
699 struct __variant_indices;
700
701 template <typename... _Types>
702 struct __variant_indices<Variant<_Types...>> {
703 typedef typename __type_indices<_Types...>::__type __type;
704 };
705
706 template <typename _Variant,
707 typename _Indices = typename __variant_indices<_Variant>::__type>
708 struct __move_construct_op_table;
709
710 template <typename _Variant, ptrdiff_t... _Indices>
711 struct __move_construct_op_table<_Variant, __index_sequence<_Indices...>> {
712 typedef void (*const __func_type)(_Variant*, _Variant&);
713
714 template <ptrdiff_t _Index>
715 static void __move_construct_func(_Variant* __lhs, _Variant& __rhs) {
716 __lhs->template __emplace_construct<_Index>(std::move(get<_Index>(__rhs)));
717 }
718
719 static const __func_type __apply[sizeof...(_Indices)];
720 };
721
722 template <typename _Variant, ptrdiff_t... _Indices>
723 const typename __move_construct_op_table<
724 _Variant,
725 __index_sequence<_Indices...>>::__func_type
726 __move_construct_op_table<_Variant, __index_sequence<_Indices...>>::__apply
727 [sizeof...(_Indices)] = {&__move_construct_func<_Indices>...};
728
729 template <typename _Variant,
730 typename _Indices = typename __variant_indices<_Variant>::__type>
731 struct __move_assign_op_table;
732
733 template <typename _Variant, ptrdiff_t... _Indices>
734 struct __move_assign_op_table<_Variant, __index_sequence<_Indices...>> {
735 typedef void (*const __func_type)(_Variant*, _Variant&);
736
737 template <ptrdiff_t _Index>
738 static void __move_assign_func(_Variant* __lhs, _Variant& __rhs) {
739 get<_Index>(*__lhs) = std::move(get<_Index>(__rhs));
740 }
741
742 static const __func_type __apply[sizeof...(_Indices)];
743 };
744
745 template <typename _Variant, ptrdiff_t... _Indices>
746 const typename __move_assign_op_table<_Variant, __index_sequence<_Indices...>>::
747 __func_type __move_assign_op_table<
748 _Variant,
749 __index_sequence<_Indices...>>::__apply[sizeof...(_Indices)] = {
750 &__move_assign_func<_Indices>...};
751
752 template <typename _Variant,
753 typename _Indices = typename __variant_indices<_Variant>::__type>
754 struct __copy_construct_op_table;
755
756 template <typename _Variant, ptrdiff_t... _Indices>
757 struct __copy_construct_op_table<_Variant, __index_sequence<_Indices...>> {
758 typedef void (*const __func_type)(_Variant*, _Variant const&);
759
760 template <ptrdiff_t _Index>
761 static void __copy_construct_func(_Variant* __lhs, _Variant const& __rhs) {
762 __lhs->template __emplace_construct<_Index>(get<_Index>(__rhs));
763 }
764
765 static const __func_type __apply[sizeof...(_Indices)];
766 };
767
768 template <typename _Variant, ptrdiff_t... _Indices>
769 const typename __copy_construct_op_table<
770 _Variant,
771 __index_sequence<_Indices...>>::__func_type
772 __copy_construct_op_table<_Variant, __index_sequence<_Indices...>>::__apply
773 [sizeof...(_Indices)] = {&__copy_construct_func<_Indices>...};
774
775 template <typename _Variant,
776 typename _Indices = typename __variant_indices<_Variant>::__type>
777 struct __copy_assign_op_table;
778
779 template <typename _Variant, ptrdiff_t... _Indices>
780 struct __copy_assign_op_table<_Variant, __index_sequence<_Indices...>> {
781 typedef void (*const __func_type)(_Variant*, _Variant const&);
782
783 template <ptrdiff_t _Index>
784 static void __copy_assign_func(_Variant* __lhs, _Variant const& __rhs) {
785 get<_Index>(*__lhs) = get<_Index>(__rhs);
786 }
787
788 static const __func_type __apply[sizeof...(_Indices)];
789 };
790
791 template <typename _Variant, ptrdiff_t... _Indices>
792 const typename __copy_assign_op_table<_Variant, __index_sequence<_Indices...>>::
793 __func_type __copy_assign_op_table<
794 _Variant,
795 __index_sequence<_Indices...>>::__apply[sizeof...(_Indices)] = {
796 &__copy_assign_func<_Indices>...};
797
798 template <typename _Variant,
799 typename _Indices = typename __variant_indices<_Variant>::__type>
800 struct __destroy_op_table;
801
802 template <typename _Variant, ptrdiff_t... _Indices>
803 struct __destroy_op_table<_Variant, __index_sequence<_Indices...>> {
804 typedef void (*const __func_type)(_Variant*);
805
806 template <ptrdiff_t _Index>
807 static void __destroy_func(_Variant* __self) {
808 if (__self->__index >= 0) {
809 __self->__storage.__destroy(variant_in_place<_Index>);
810 }
811 }
812
813 static const __func_type __apply[sizeof...(_Indices)];
814 };
815
816 template <typename _Variant, ptrdiff_t... _Indices>
817 const typename __destroy_op_table<_Variant,
818 __index_sequence<_Indices...>>::__func_type
819 __destroy_op_table<_Variant, __index_sequence<_Indices...>>::__apply
820 [sizeof...(_Indices)] = {&__destroy_func<_Indices>...};
821
822 template <typename _Variant,
823 typename _Indices = typename __variant_indices<_Variant>::__type>
824 struct __swap_op_table;
825
826 template <typename _Variant, ptrdiff_t... _Indices>
827 struct __swap_op_table<_Variant, __index_sequence<_Indices...>> {
828 typedef void (*const __func_type)(_Variant&, _Variant&);
829
830 template <ptrdiff_t _Index>
831 static void __swap_func(_Variant& __lhs, _Variant& __rhs) {
832 swap(get<_Index>(__lhs), get<_Index>(__rhs));
833 }
834
835 static const __func_type __apply[sizeof...(_Indices)];
836 };
837
838 template <typename _Variant, ptrdiff_t... _Indices>
839 const typename __swap_op_table<_Variant,
840 __index_sequence<_Indices...>>::__func_type
841 __swap_op_table<_Variant, __index_sequence<_Indices...>>::__apply[sizeof...(
842 _Indices)] = {&__swap_func<_Indices>...};
843
844 template <typename _Variant,
845 typename _Indices = typename __variant_indices<_Variant>::__type>
846 struct __equality_op_table;
847
848 template <typename _Variant, ptrdiff_t... _Indices>
849 struct __equality_op_table<_Variant, __index_sequence<_Indices...>> {
850 typedef bool (*const __compare_func_type)(_Variant const&, _Variant const&);
851
852 template <ptrdiff_t _Index>
853 static constexpr bool __equality_compare_func(_Variant const& __lhs,
854 _Variant const& __rhs) {
855 return get<_Index>(__lhs) == get<_Index>(__rhs);
856 }
857
858 static constexpr __compare_func_type __equality_compare[sizeof...(_Indices)] =
859 {&__equality_compare_func<_Indices>...};
860 };
861
862 template <typename _Variant, ptrdiff_t... _Indices>
863 constexpr
864 typename __equality_op_table<_Variant, __index_sequence<_Indices...>>::
865 __compare_func_type
866 __equality_op_table<_Variant, __index_sequence<_Indices...>>::
867 __equality_compare[sizeof...(_Indices)];
868
869 template <typename _Variant,
870 typename _Indices = typename __variant_indices<_Variant>::__type>
871 struct __less_than_op_table;
872
873 template <typename _Variant, ptrdiff_t... _Indices>
874 struct __less_than_op_table<_Variant, __index_sequence<_Indices...>> {
875 typedef bool (*const __compare_func_type)(_Variant const&, _Variant const&);
876
877 template <ptrdiff_t _Index>
878 static constexpr bool __less_than_compare_func(_Variant const& __lhs,
879 _Variant const& __rhs) {
880 return get<_Index>(__lhs) < get<_Index>(__rhs);
881 }
882
883 static constexpr __compare_func_type __less_than_compare[sizeof...(
884 _Indices)] = {&__less_than_compare_func<_Indices>...};
885 };
886
887 template <typename _Variant, ptrdiff_t... _Indices>
888 constexpr
889 typename __less_than_op_table<_Variant, __index_sequence<_Indices...>>::
890 __compare_func_type
891 __less_than_op_table<_Variant, __index_sequence<_Indices...>>::
892 __less_than_compare[sizeof...(_Indices)];
893
894 template <typename _Derived, bool __trivial_destructor>
895 struct __variant_base {
896 ~__variant_base() { static_cast<_Derived*>(this)->__destroy_self(); }
897 };
898
899 template <typename _Derived>
900 struct __variant_base<_Derived, true> {};
901
902 template <ptrdiff_t _Offset,
903 typename _CurrentSequence,
904 typename _Type,
905 typename... _Types>
906 struct __all_indices_helper;
907
908 template <ptrdiff_t _Offset,
909 ptrdiff_t... _Indices,
910 typename _Type,
911 typename... _Rest>
912 struct __all_indices_helper<_Offset,
913 __index_sequence<_Indices...>,
914 _Type,
915 _Type,
916 _Rest...> {
917 typedef typename __all_indices_helper<_Offset + 1,
918 __index_sequence<_Indices..., _Offset>,
919 _Type,
920 _Rest...>::__type __type;
921 };
922
923 template <ptrdiff_t _Offset,
924 typename _CurrentSequence,
925 typename _Type,
926 typename _Head,
927 typename... _Rest>
928 struct __all_indices_helper<_Offset, _CurrentSequence, _Type, _Head, _Rest...> {
929 typedef typename __all_indices_helper<_Offset + 1,
930 _CurrentSequence,
931 _Type,
932 _Rest...>::__type __type;
933 };
934
935 template <ptrdiff_t _Offset, typename _CurrentSequence, typename _Type>
936 struct __all_indices_helper<_Offset, _CurrentSequence, _Type> {
937 typedef _CurrentSequence __type;
938 };
939
940 template <typename _Type, typename... _Types>
941 struct __all_indices {
942 typedef
943 typename __all_indices_helper<0, __index_sequence<>, _Type, _Types...>::
944 __type __type;
945 };
946
947 template <typename... _Sequences>
948 struct __combine_sequences;
949
950 template <ptrdiff_t... _Indices1, ptrdiff_t... _Indices2>
951 struct __combine_sequences<__index_sequence<_Indices1...>,
952 __index_sequence<_Indices2...>> {
953 typedef __index_sequence<_Indices1..., _Indices2...> __type;
954 };
955
956 template <typename _Sequence, typename... _Rest>
957 struct __combine_sequences<_Sequence, _Rest...> {
958 typedef typename __combine_sequences<
959 _Sequence,
960 typename __combine_sequences<_Rest...>::__type>::__type __type;
961 };
962
963 template <typename _Indices>
964 struct __first_index;
965
966 template <ptrdiff_t _FirstIndex, ptrdiff_t... _Rest>
967 struct __first_index<__index_sequence<_FirstIndex, _Rest...>> {
968 static constexpr ptrdiff_t __value = _FirstIndex;
969 };
970
971 template <ptrdiff_t _Offset,
972 typename _CurrentSequence,
973 typename _Type,
974 typename... _Types>
975 struct __constructible_matches_helper;
976
977 template <ptrdiff_t _Offset, typename _Sequence, typename _Type>
978 struct __constructible_matches_helper<_Offset, _Sequence, _Type> {
979 typedef _Sequence __type;
980 };
981
982 template <bool _Accept, ptrdiff_t _Entry>
983 struct __sequence_or_empty {
984 typedef __index_sequence<> __type;
985 };
986
987 template <ptrdiff_t _Entry>
988 struct __sequence_or_empty<true, _Entry> {
989 typedef __index_sequence<_Entry> __type;
990 };
991
992 template <ptrdiff_t _Offset,
993 typename _CurrentSequence,
994 typename _Type,
995 typename _Head,
996 typename... _Rest>
997 struct __constructible_matches_helper<_Offset,
998 _CurrentSequence,
999 _Type,
1000 _Head,
1001 _Rest...> {
1002 typedef typename __constructible_matches_helper<
1003 _Offset + 1,
1004 typename __combine_sequences<
1005 _CurrentSequence,
1006 typename __sequence_or_empty<
1007 std::is_constructible<_Head, _Type>::value,
1008 _Offset>::__type>::__type,
1009 _Type,
1010 _Rest...>::__type __type;
1011 };
1012
1013 template <typename _Type, typename... _Types>
1014 struct __constructible_matches {
1015 typedef typename __constructible_matches_helper<0,
1016 __index_sequence<>,
1017 _Type,
1018 _Types...>::__type __type;
1019 };
1020
1021 template <typename _Type, typename... _Types>
1022 struct __type_index_to_construct {
1023 typedef typename __all_indices<_Type, _Types...>::__type __direct_matches;
1024 typedef typename __all_indices<
1025 typename std::remove_const<
1026 typename std::remove_reference<_Type>::type>::type,
1027 _Types...>::__type __value_matches;
1028 typedef typename __all_indices<
1029 _Type,
1030 typename std::remove_const<typename std::remove_reference<_Types>::type>::
1031 type...>::__type __rref_matches;
1032
1033 typedef typename __constructible_matches<_Type, _Types...>::__type
1034 __constructibles;
1035
1036 static_assert((__direct_matches::__length > 0) ||
1037 (__value_matches::__length > 0) ||
1038 (__rref_matches::__length > 0) ||
1039 (__constructibles::__length == 1),
1040 "For conversion construction of variants, exactly one type "
1041 "must be constructible");
1042
1043 typedef typename __combine_sequences<__direct_matches,
1044 __value_matches,
1045 __rref_matches,
1046 __constructibles>::__type __all_matches;
1047
1048 static constexpr ptrdiff_t __value = __first_index<__all_matches>::__value;
1049 };
1050
1051 struct __replace_construct_helper {
1052 template <ptrdiff_t _Index,
1053 bool __construct_directly,
1054 bool __indexed_type_has_nothrow_move,
1055 bool __other_types_have_nothrow_move>
1056 struct __helper;
1057
1058 template <typename _Variant,
1059 typename _Indices = typename __variant_indices<_Variant>::__type>
1060 struct __op_table;
1061 };
1062
1063 template <ptrdiff_t _Index, bool __other_types_have_nothrow_move>
1064 struct __replace_construct_helper::
1065 __helper<_Index, false, true, __other_types_have_nothrow_move> {
1066 template <typename _Variant, typename... _Args>
1067 static void __trampoline(_Variant& __v, _Args&&... __args) {
1068 __v.template __two_stage_replace<_Index>(__args...);
1069 }
1070 };
1071
1072 template <ptrdiff_t _Index,
1073 bool __indexed_type_has_nothrow_move,
1074 bool __other_types_have_nothrow_move>
1075 struct __replace_construct_helper::__helper<_Index,
1076 true,
1077 __indexed_type_has_nothrow_move,
1078 __other_types_have_nothrow_move> {
1079 template <typename _Variant, typename... _Args>
1080 static void __trampoline(_Variant& __v, _Args&&... __args) {
1081 __v.template __direct_replace<_Index>(std::forward<_Args>(__args)...);
1082 }
1083 };
1084
1085 template <ptrdiff_t _Index>
1086 struct __replace_construct_helper::__helper<_Index, false, false, true> {
1087 template <typename _Variant, typename... _Args>
1088 static void __trampoline(_Variant& __v, _Args&&... __args) {
1089 __v.template __local_backup_replace<_Index>(std::forward<_Args>(__args)...);
1090 }
1091 };
1092
1093 template <ptrdiff_t _Index>
1094 struct __replace_construct_helper::__helper<_Index, false, false, false> {
1095 template <typename _Variant, typename... _Args>
1096 static void __trampoline(_Variant& __v, _Args&&... __args) {
1097 __v.template __direct_replace<_Index>(std::forward<_Args>(__args)...);
1098 }
1099 };
1100
1101 template <typename _Variant, ptrdiff_t... _Indices>
1102 struct __replace_construct_helper::__op_table<_Variant,
1103 __index_sequence<_Indices...>> {
1104 typedef void (*const __move_func_type)(_Variant*, _Variant&);
1105 typedef void (*const __copy_func_type)(_Variant*, _Variant const&);
1106
1107 template <ptrdiff_t _Index>
1108 static void __move_assign_func(_Variant* __lhs, _Variant& __rhs) {
1109 __lhs->template __replace_construct<_Index>(std::move(get<_Index>(__rhs)));
1110 __rhs.__destroy_self();
1111 }
1112
1113 template <ptrdiff_t _Index>
1114 static void __copy_assign_func(_Variant* __lhs, _Variant const& __rhs) {
1115 __lhs->template __replace_construct<_Index>(get<_Index>(__rhs));
1116 }
1117
1118 static const __move_func_type __move_assign[sizeof...(_Indices)];
1119 static const __copy_func_type __copy_assign[sizeof...(_Indices)];
1120 };
1121
1122 template <typename _Variant, ptrdiff_t... _Indices>
1123 const typename __replace_construct_helper::
1124 __op_table<_Variant, __index_sequence<_Indices...>>::__move_func_type
1125 __replace_construct_helper::__op_table<
1126 _Variant,
1127 __index_sequence<_Indices...>>::__move_assign[sizeof...(_Indices)] =
1128 {&__move_assign_func<_Indices>...};
1129
1130 template <typename _Variant, ptrdiff_t... _Indices>
1131 const typename __replace_construct_helper::
1132 __op_table<_Variant, __index_sequence<_Indices...>>::__copy_func_type
1133 __replace_construct_helper::__op_table<
1134 _Variant,
1135 __index_sequence<_Indices...>>::__copy_assign[sizeof...(_Indices)] =
1136 {&__copy_assign_func<_Indices>...};
1137
1138 template <ptrdiff_t _Index, ptrdiff_t _MaskIndex, typename _Storage>
1139 struct __backup_storage_ops {
1140 static void __move_construct_func(_Storage* __dest, _Storage& __source) {
1141 new (__dest) _Storage(variant_in_place<_Index>,
1142 std::move(__source.__get(variant_in_place<_Index>)));
1143 }
1144 static void __destroy_func(_Storage* __obj) {
1145 __obj->__destroy(variant_in_place<_Index>);
1146 };
1147 };
1148
1149 template <ptrdiff_t _Index, typename _Storage>
1150 struct __backup_storage_ops<_Index, _Index, _Storage> {
1151 static void __move_construct_func(_Storage*, _Storage&) {
1152 __THROW_EXCEPTION(std::bad_alloc());
1153 };
1154 static void __destroy_func(_Storage*) {
1155 __THROW_EXCEPTION(std::bad_alloc());
1156 };
1157 };
1158
1159 template <ptrdiff_t _MaskIndex, typename _Storage, typename _Indices>
1160 struct __backup_storage_op_table;
1161
1162 template <ptrdiff_t _MaskIndex, typename _Storage, ptrdiff_t... _Indices>
1163 struct __backup_storage_op_table<_MaskIndex,
1164 _Storage,
1165 __index_sequence<_Indices...>> {
1166 typedef void (*__move_func_type)(_Storage* __dest, _Storage& __source);
1167 typedef void (*__destroy_func_type)(_Storage* __obj);
1168
1169 template <size_t _Index>
1170 struct __helper {
1171 typedef __backup_storage_ops<_Index, _MaskIndex, _Storage> __ops;
1172 };
1173
1174 static const __move_func_type __move_ops[sizeof...(_Indices)];
1175 static const __destroy_func_type __destroy_ops[sizeof...(_Indices)];
1176 };
1177
1178 template <ptrdiff_t _MaskIndex, typename _Storage, ptrdiff_t... _Indices>
1179 const typename __backup_storage_op_table<_MaskIndex,
1180 _Storage,
1181 __index_sequence<_Indices...>>::
1182 __move_func_type __backup_storage_op_table<
1183 _MaskIndex,
1184 _Storage,
1185 __index_sequence<_Indices...>>::__move_ops[sizeof...(_Indices)] = {
1186 &__helper<_Indices>::__ops::__move_construct_func...};
1187
1188 template <ptrdiff_t _MaskIndex, typename _Storage, ptrdiff_t... _Indices>
1189 const typename __backup_storage_op_table<_MaskIndex,
1190 _Storage,
1191 __index_sequence<_Indices...>>::
1192 __destroy_func_type __backup_storage_op_table<
1193 _MaskIndex,
1194 _Storage,
1195 __index_sequence<_Indices...>>::__destroy_ops[sizeof...(_Indices)] = {
1196 &__helper<_Indices>::__ops::__destroy_func...};
1197
1198 template <ptrdiff_t _Index, typename... _Types>
1199 struct __backup_storage {
1200 typedef __variant_data<_Types...> __storage_type;
1201
1202 typedef __backup_storage_op_table<_Index,
1203 __storage_type,
1204 typename __type_indices<_Types...>::__type>
1205 __op_table_type;
1206
1207 ptrdiff_t __backup_index;
1208 __storage_type& __live_storage;
1209 __storage_type __backup;
1210
1211 __backup_storage(ptrdiff_t __live_index_, __storage_type& __live_storage_)
1212 : __backup_index(__live_index_), __live_storage(__live_storage_) {
1213 if (__backup_index >= 0) {
1214 __op_table_type::__move_ops[__backup_index](&__backup, __live_storage);
1215 __op_table_type::__destroy_ops[__backup_index](&__live_storage);
1216 }
1217 }
1218 void __destroy() {
1219 if (__backup_index >= 0)
1220 __op_table_type::__destroy_ops[__backup_index](&__backup);
1221 __backup_index = -1;
1222 }
1223
1224 ~__backup_storage() {
1225 if (__backup_index >= 0) {
1226 __op_table_type::__move_ops[__backup_index](&__live_storage, __backup);
1227 __destroy();
1228 }
1229 }
1230 };
1231
1232 template <typename... _Types>
1233 struct __all_move_constructible;
1234
1235 template <typename _Head, typename... _Rest>
1236 struct __all_move_constructible<_Head, _Rest...> {
1237 static constexpr bool value = std::is_move_constructible<_Head>::value &&
1238 __all_move_constructible<_Rest...>::value;
1239 };
1240
1241 template <>
1242 struct __all_move_constructible<> : std::true_type {};
1243
1244 template <typename... _Types>
1245 struct __all_move_assignable;
1246
1247 template <typename _Head, typename... _Rest>
1248 struct __all_move_assignable<_Head, _Rest...> {
1249 static constexpr bool value = std::is_move_assignable<_Head>::value &&
1250 __all_move_assignable<_Rest...>::value;
1251 };
1252
1253 template <>
1254 struct __all_move_assignable<> : std::true_type {};
1255
1256 template <typename... _Types>
1257 struct __all_copy_assignable;
1258
1259 template <typename _Head, typename... _Rest>
1260 struct __all_copy_assignable<_Head, _Rest...> {
1261 static constexpr bool value = std::is_copy_assignable<_Head>::value &&
1262 __all_copy_assignable<_Rest...>::value;
1263 };
1264
1265 template <>
1266 struct __all_copy_assignable<> : std::true_type {};
1267
1268 namespace __swap_test_detail {
1269 using std::swap;
1270
1271 template <typename _Other>
1272 struct __swap_result {};
1273
1274 template <typename>
1275 static char __test(...);
1276 template <typename _Other>
1277 static std::pair<
1278 char,
1279 std::pair<char,
1280 __swap_result<decltype(swap(std::declval<_Other&>(),
1281 std::declval<_Other&>()))>>>
1282 __test(_Other*);
1283 }
1284
1285 template <typename _Type>
1286 struct __is_swappable {
1287 static constexpr bool value =
1288 sizeof(__swap_test_detail::__test<_Type>(0)) != 1;
1289 };
1290
1291 template <typename... _Types>
1292 struct __all_swappable;
1293
1294 template <typename _Head, typename... _Rest>
1295 struct __all_swappable<_Head, _Rest...> {
1296 static constexpr bool value =
1297 __is_swappable<_Head>::value && __all_swappable<_Rest...>::value;
1298 };
1299
1300 template <>
1301 struct __all_swappable<> : std::true_type {};
1302
1303 template <bool _MoveConstructible, typename... _Types>
1304 struct __noexcept_variant_move_construct_impl {};
1305
1306 template <typename _Head, typename... _Rest>
1307 struct __noexcept_variant_move_construct_impl<true, _Head, _Rest...> {
1308 static constexpr bool value =
1309 noexcept(_Head(std::declval<_Head&&>())) &&
1310 __noexcept_variant_move_construct_impl<true, _Rest...>::value;
1311 };
1312
1313 template <>
1314 struct __noexcept_variant_move_construct_impl<true> {
1315 static constexpr bool value = true;
1316 };
1317
1318 template <typename... _Types>
1319 struct __noexcept_variant_move_construct
1320 : __noexcept_variant_move_construct_impl<
1321 __all_move_constructible<_Types...>::value,
1322 _Types...> {};
1323
1324 template <bool _MoveAssignable, typename... _Types>
1325 struct __noexcept_variant_move_assign_impl {};
1326
1327 template <typename _Head, typename... _Rest>
1328 struct __noexcept_variant_move_assign_impl<true, _Head, _Rest...> {
1329 static constexpr bool value =
1330 std::is_nothrow_move_assignable<_Head>::value &&
1331 std::is_nothrow_move_constructible<_Head>::value &&
1332 __noexcept_variant_move_assign_impl<true, _Rest...>::value;
1333 };
1334
1335 template <>
1336 struct __noexcept_variant_move_assign_impl<true> {
1337 static constexpr bool value = true;
1338 };
1339
1340 template <typename... _Types>
1341 struct __noexcept_variant_move_assign
1342 : __noexcept_variant_move_assign_impl<
1343 __all_move_assignable<_Types...>::value &&
1344 __all_move_constructible<_Types...>::value,
1345 _Types...> {};
1346
1347 template <typename... _Types>
1348 struct __all_copy_constructible;
1349
1350 template <typename _Head, typename... _Rest>
1351 struct __all_copy_constructible<_Head, _Rest...> {
1352 static constexpr bool value = std::is_copy_constructible<_Head>::value &&
1353 __all_copy_constructible<_Rest...>::value;
1354 };
1355
1356 template <>
1357 struct __all_copy_constructible<> : std::true_type {};
1358
1359 template <bool _CopyConstructible, typename... _Types>
1360 struct __noexcept_variant_const_copy_construct_impl {};
1361
1362 template <typename _Head, typename... _Rest>
1363 struct __noexcept_variant_const_copy_construct_impl<true, _Head, _Rest...> {
1364 static constexpr bool value =
1365 noexcept(_Head(std::declval<_Head const&>())) &&
1366 __noexcept_variant_const_copy_construct_impl<true, _Rest...>::value;
1367 };
1368
1369 template <>
1370 struct __noexcept_variant_const_copy_construct_impl<true> {
1371 static constexpr bool value = true;
1372 };
1373
1374 template <typename... _Types>
1375 struct __noexcept_variant_const_copy_construct
1376 : __noexcept_variant_const_copy_construct_impl<
1377 __all_copy_constructible<_Types...>::value,
1378 _Types...> {};
1379
1380 template <bool _CopyNon_Constructible, typename... _Types>
1381 struct __noexcept_variant_non_const_copy_construct_impl {};
1382
1383 template <typename _Head, typename... _Rest>
1384 struct __noexcept_variant_non_const_copy_construct_impl<true, _Head, _Rest...> {
1385 static constexpr bool value =
1386 noexcept(_Head(std::declval<_Head&>())) &&
1387 __noexcept_variant_non_const_copy_construct_impl<true, _Rest...>::value;
1388 };
1389
1390 template <>
1391 struct __noexcept_variant_non_const_copy_construct_impl<true> {
1392 static constexpr bool value = true;
1393 };
1394
1395 template <typename... _Types>
1396 struct __noexcept_variant_non_const_copy_construct
1397 : __noexcept_variant_non_const_copy_construct_impl<
1398 __all_copy_constructible<_Types...>::value,
1399 _Types...> {};
1400
1401 template <bool _Swappable, typename... _Types>
1402 struct __noexcept_variant_swap_impl {};
1403
1404 template <typename _Head, typename... _Rest>
1405 struct __noexcept_variant_swap_impl<true, _Head, _Rest...> {
1406 static constexpr bool value =
1407 noexcept(swap(std::declval<_Head&>(), std::declval<_Head&>())) &&
1408 __noexcept_variant_swap_impl<true, _Rest...>::value;
1409 };
1410
1411 template <>
1412 struct __noexcept_variant_swap_impl<true> {
1413 static constexpr bool value = true;
1414 };
1415
1416 template <typename... _Types>
1417 struct __noexcept_variant_swap
1418 : __noexcept_variant_swap_impl<__all_swappable<_Types...>::value,
1419 _Types...> {};
1420
1421 template <typename... _Types>
1422 class Variant
1423 : private __variant_base<Variant<_Types...>,
1424 __all_trivially_destructible<_Types...>::__value> {
1425 typedef __variant_base<Variant<_Types...>,
1426 __all_trivially_destructible<_Types...>::__value>
1427 __base_type;
1428 friend __base_type;
1429 friend struct __copy_construct_op_table<Variant>;
1430 friend struct __copy_assign_op_table<Variant>;
1431 friend struct __move_construct_op_table<Variant>;
1432 friend struct __move_assign_op_table<Variant>;
1433 friend struct __destroy_op_table<Variant>;
1434
1435 template <ptrdiff_t _Index, typename... _Types2>
1436 friend struct __variant_accessor;
1437
1438 friend struct __replace_construct_helper;
1439
1440 typedef __variant_data<_Types...> __storage_type;
1441 __storage_type __storage;
1442 typename __discriminator_type<sizeof...(_Types)>::__type __index;
1443
1444 template <size_t _Index, typename... _Args>
1445 size_t __emplace_construct(_Args&&... __args) {
1446 new (&__storage) __storage_type(variant_in_place<_Index>,
1447 std::forward<_Args>(__args)...);
1448 return _Index;
1449 }
1450
1451 void __destroy_self() {
1452 if (valueless_by_exception())
1453 return;
1454 __destroy_op_table<Variant>::__apply[index()](this);
1455 __index = -1;
1456 }
1457
1458 ptrdiff_t __move_construct(Variant& __other) {
1459 ptrdiff_t const __other_index = __other.index();
1460 if (__other_index == -1)
1461 return -1;
1462 __move_construct_op_table<Variant>::__apply[__other_index](this, __other);
1463 __other.__destroy_self();
1464 return __other_index;
1465 }
1466
1467 ptrdiff_t __copy_construct(Variant const& __other) {
1468 ptrdiff_t const __other_index = __other.index();
1469 if (__other_index == -1)
1470 return -1;
1471 __copy_construct_op_table<Variant>::__apply[__other_index](this, __other);
1472 return __other_index;
1473 }
1474
1475 template <size_t _Index, typename... _Args>
1476 void __replace_construct(_Args&&... __args) {
1477 typedef typename __indexed_type<_Index, _Types...>::__type __this_type;
1478 __replace_construct_helper::__helper<
1479 _Index,
1480 __storage_nothrow_constructible<__this_type, _Args...>::__value ||
1481 (sizeof...(_Types) == 1),
1482 __storage_nothrow_move_constructible<__this_type>::__value,
1483 __other_storage_nothrow_move_constructible<_Index, _Types...>::
1484 __value>::__trampoline(*this, std::forward<_Args>(__args)...);
1485 }
1486
1487 template <size_t _Index, typename... _Args>
1488 void __two_stage_replace(_Args&&... __args) {
1489 typedef typename __indexed_type<_Index, _Types...>::__type __type;
1490 __variant_data<__type> __local(variant_in_place<0>,
1491 std::forward<_Args>(__args)...);
1492 __destroy_self();
1493 __emplace_construct<_Index>(std::move(__local.__get(variant_in_place<0>)));
1494 __index = _Index;
1495 __local.__destroy(variant_in_place<0>);
1496 }
1497
1498 template <size_t _Index, typename... _Args>
1499 void __local_backup_replace(_Args&&... __args) {
1500 __backup_storage<_Index, _Types...> __backup(__index, __storage);
1501 __emplace_construct<_Index>(std::forward<_Args>(__args)...);
1502 __index = _Index;
1503 __backup.__destroy();
1504 }
1505
1506 template <size_t _Index, typename... _Args>
1507 void __direct_replace(_Args&&... __args) {
1508 __destroy_self();
1509 __emplace_construct<_Index>(std::forward<_Args>(__args)...);
1510 __index = _Index;
1511 }
1512
1513 struct __private_type {};
1514
1515 public:
1516 constexpr Variant()
1517 __NOEXCEPT_(noexcept(typename __indexed_type<0, _Types...>::__type()))
1518 : __storage(variant_in_place<0>), __index(0) {}
1519
1520 constexpr Variant(
1521 typename std::conditional<__all_move_constructible<_Types...>::value,
1522 Variant,
1523 __private_type>::type&& __other)
1524 __NOEXCEPT_(__noexcept_variant_move_construct<_Types...>::value)
1525 : __index(__move_construct(__other)) {}
1526
1527 constexpr Variant(
1528 typename std::conditional<!__all_move_constructible<_Types...>::value,
1529 Variant,
1530 __private_type>::type&& __other) = delete;
1531
1532 constexpr Variant(
1533 typename std::conditional<__all_copy_constructible<_Types...>::value,
1534 Variant,
1535 __private_type>::type& __other)
1536 __NOEXCEPT_(__noexcept_variant_non_const_copy_construct<_Types...>::value)
1537 : __index(__copy_construct(__other)) {}
1538
1539 constexpr Variant(
1540 typename std::conditional<!__all_copy_constructible<_Types...>::value,
1541 Variant,
1542 __private_type>::type& __other) = delete;
1543
1544 constexpr Variant(
1545 typename std::conditional<__all_copy_constructible<_Types...>::value,
1546 Variant,
1547 __private_type>::type const& __other)
1548 __NOEXCEPT_(__noexcept_variant_const_copy_construct<_Types...>::value)
1549 : __index(__copy_construct(__other)) {}
1550
1551 constexpr Variant(
1552 typename std::conditional<!__all_copy_constructible<_Types...>::value,
1553 Variant,
1554 __private_type>::type const& __other) = delete;
1555
1556 template <typename _Type, typename... _Args>
1557 explicit constexpr Variant(variant_in_place_type_t<_Type>, _Args&&... __args)
1558 : __storage(variant_in_place<__type_index<_Type, _Types...>::__value>,
1559 std::forward<_Args>(__args)...),
1560 __index(__type_index<_Type, _Types...>::__value) {
1561 static_assert(std::is_constructible<_Type, _Args...>::value,
1562 "Type must be constructible from args");
1563 }
1564
1565 template <size_t _Index, typename... _Args>
1566 explicit constexpr Variant(variant_in_place_index_t<_Index>,
1567 _Args&&... __args)
1568 : __storage(variant_in_place<_Index>, std::forward<_Args>(__args)...),
1569 __index(_Index) {
1570 static_assert(std::is_constructible<
1571 typename __indexed_type<_Index, _Types...>::__type,
1572 _Args...>::value,
1573 "Type must be constructible from args");
1574 }
1575
1576 template <typename _Type>
1577 constexpr Variant(_Type&& __x)
1578 : __storage(variant_in_place<
1579 __type_index_to_construct<_Type, _Types...>::__value>,
1580 std::forward<_Type>(__x)),
1581 __index(__type_index_to_construct<_Type, _Types...>::__value) {}
1582
1583 template <
1584 typename _Type,
1585 typename _Enable = typename std::enable_if<
1586 (__constructible_matches<std::initializer_list<_Type>,
1587 _Types...>::__type::__length > 0)>::type>
1588 constexpr Variant(std::initializer_list<_Type> __x)
1589 : __storage(variant_in_place<
1590 __type_index_to_construct<std::initializer_list<_Type>,
1591 _Types...>::__value>,
1592 __x),
1593 __index(__type_index_to_construct<std::initializer_list<_Type>,
1594 _Types...>::__value) {}
1595
1596 template <typename _Type>
1597 Variant& operator=(_Type&& __x) {
1598 constexpr size_t _Index =
1599 __type_index_to_construct<_Type, _Types...>::__value;
1600 if (_Index == __index) {
1601 get<_Index>(*this) = std::forward<_Type>(__x);
1602 } else {
1603 __replace_construct<_Index>(std::forward<_Type>(__x));
1604 }
1605 return *this;
1606 }
1607
1608 Variant& operator=(
1609 typename std::conditional<!(__all_copy_constructible<_Types...>::value &&
1610 __all_move_constructible<_Types...>::value &&
1611 __all_copy_assignable<_Types...>::value),
1612 Variant,
1613 __private_type>::type const& __other) = delete;
1614
1615 Variant& operator=(typename std::conditional<
1616 __all_copy_constructible<_Types...>::value &&
1617 __all_move_constructible<_Types...>::value &&
1618 __all_copy_assignable<_Types...>::value,
1619 Variant,
1620 __private_type>::type const& __other) {
1621 if (__other.valueless_by_exception()) {
1622 __destroy_self();
1623 } else if (__other.index() == index()) {
1624 __copy_assign_op_table<Variant>::__apply[index()](this, __other);
1625 } else {
1626 __replace_construct_helper::__op_table<
1627 Variant>::__copy_assign[__other.index()](this, __other);
1628 }
1629 return *this;
1630 }
1631 Variant& operator=(
1632 typename std::conditional<!(__all_copy_constructible<_Types...>::value &&
1633 __all_move_constructible<_Types...>::value &&
1634 __all_copy_assignable<_Types...>::value),
1635 Variant,
1636 __private_type>::type& __other) = delete;
1637
1638 Variant& operator=(typename std::conditional<
1639 __all_copy_constructible<_Types...>::value &&
1640 __all_move_constructible<_Types...>::value &&
1641 __all_copy_assignable<_Types...>::value,
1642 Variant,
1643 __private_type>::type& __other) {
1644 if (__other.valueless_by_exception()) {
1645 __destroy_self();
1646 } else if (__other.index() == index()) {
1647 __copy_assign_op_table<Variant>::__apply[index()](this, __other);
1648 } else {
1649 __replace_construct_helper::__op_table<
1650 Variant>::__copy_assign[__other.index()](this, __other);
1651 }
1652 return *this;
1653 }
1654 Variant& operator=(
1655 typename std::conditional<!(__all_move_constructible<_Types...>::value &&
1656 __all_move_assignable<_Types...>::value),
1657 Variant,
1658 __private_type>::type&& __other) = delete;
1659
1660 Variant& operator=(
1661 typename std::conditional<__all_move_constructible<_Types...>::value &&
1662 __all_move_assignable<_Types...>::value,
1663 Variant,
1664 __private_type>::type&& __other)
1665 __NOEXCEPT_(__noexcept_variant_move_assign<_Types...>::value) {
1666 if (__other.valueless_by_exception()) {
1667 __destroy_self();
1668 } else if (__other.index() == index()) {
1669 __move_assign_op_table<Variant>::__apply[index()](this, __other);
1670 __other.__destroy_self();
1671 } else {
1672 __replace_construct_helper::__op_table<
1673 Variant>::__move_assign[__other.index()](this, __other);
1674 }
1675 return *this;
1676 }
1677
1678 template <typename _Type, typename... _Args>
1679 void emplace(_Args&&... __args) {
1680 __direct_replace<__type_index<_Type, _Types...>::__value>(
1681 std::forward<_Args>(__args)...);
1682 }
1683
1684 template <size_t _Index, typename... _Args>
1685 void emplace(_Args&&... __args) {
1686 __direct_replace<_Index>(std::forward<_Args>(__args)...);
1687 }
1688
1689 constexpr bool valueless_by_exception() const __NOEXCEPT {
1690 return __index == -1;
1691 }
1692 constexpr ptrdiff_t index() const __NOEXCEPT { return __index; }
1693
1694 void swap(
1695 typename std::conditional<__all_swappable<_Types...>::value &&
1696 __all_move_constructible<_Types...>::value,
1697 Variant,
1698 __private_type>::type& __other)
1699 __NOEXCEPT_(__noexcept_variant_swap<_Types...>::value) {
1700 if (__other.index() == index()) {
1701 if (!valueless_by_exception())
1702 __swap_op_table<Variant>::__apply[index()](*this, __other);
1703 } else {
1704 Variant __temp(std::move(__other));
1705 __other.__index = __other.__move_construct(*this);
1706 __index = __move_construct(__temp);
1707 }
1708 }
1709 };
1710
1711 template <>
1712 class Variant<> {
1713 public:
1714 Variant() = delete;
1715
1716 constexpr bool valueless_by_exception() const __NOEXCEPT { return true; }
1717 constexpr ptrdiff_t index() const __NOEXCEPT { return -1; }
1718
1719 void swap(Variant&) {}
1720 };
1721
1722 template <typename... _Types>
1723 typename std::enable_if<__all_swappable<_Types...>::value &&
1724 __all_move_constructible<_Types...>::value,
1725 void>::type
1726 swap(Variant<_Types...>& __lhs, Variant<_Types...>& __rhs)
1727 __NOEXCEPT_(__noexcept_variant_swap<_Types...>::value) {
1728 __lhs.swap(__rhs);
1729 }
1730
1731 template <ptrdiff_t _Index, typename... _Types>
1732 struct __variant_accessor {
1733 typedef typename __indexed_type<_Index, _Types...>::__type __type;
1734 static constexpr __type& get(Variant<_Types...>& __v) {
1735 return __v.__storage.__get(variant_in_place<_Index>);
1736 }
1737 static constexpr __type const& get(Variant<_Types...> const& __v) {
1738 return __v.__storage.__get(variant_in_place<_Index>);
1739 }
1740 static constexpr __type&& get(Variant<_Types...>&& __v) {
1741 return __v.__storage.__get_rref(variant_in_place<_Index>);
1742 }
1743 static constexpr const __type&& get(Variant<_Types...> const&& __v) {
1744 return __v.__storage.__get_rref(variant_in_place<_Index>);
1745 }
1746 };
1747
1748 template <typename _Type, typename... _Types>
1749 constexpr _Type& get(Variant<_Types...>& __v) {
1750 return get<__type_index<_Type, _Types...>::__value>(__v);
1751 }
1752
1753 template <typename _Type, typename... _Types>
1754 constexpr _Type&& get(Variant<_Types...>&& __v) {
1755 return get<__type_index<_Type, _Types...>::__value>(std::move(__v));
1756 }
1757
1758 template <typename _Type, typename... _Types>
1759 constexpr _Type const& get(Variant<_Types...> const& __v) {
1760 return get<__type_index<_Type, _Types...>::__value>(__v);
1761 }
1762
1763 template <typename _Type, typename... _Types>
1764 constexpr const _Type&& get(Variant<_Types...> const&& __v) {
1765 return get<__type_index<_Type, _Types...>::__value>(std::move(__v));
1766 }
1767
1768 template <ptrdiff_t _Index, typename... _Types>
1769 constexpr typename __indexed_type<_Index, _Types...>::__type const& get(
1770 Variant<_Types...> const& __v) {
1771 return *((_Index != __v.index())
1772 ? &__throw_bad_variant_access<
1773 typename __indexed_type<_Index, _Types...>::__type const&>(
1774 "Bad Variant index in get")
1775 : &__variant_accessor<_Index, _Types...>::get(__v));
1776 }
1777
1778 template <ptrdiff_t _Index, typename... _Types>
1779 constexpr typename __indexed_type<_Index, _Types...>::__type& get(
1780 Variant<_Types...>& __v) {
1781 return *((_Index != __v.index())
1782 ? &__throw_bad_variant_access<
1783 typename __indexed_type<_Index, _Types...>::__type&>(
1784 "Bad Variant index in get")
1785 : &__variant_accessor<_Index, _Types...>::get(__v));
1786 }
1787
1788 template <ptrdiff_t _Index, typename... _Types>
1789 constexpr typename __indexed_type<_Index, _Types...>::__type&& get(
1790 Variant<_Types...>&& __v) {
1791 return __variant_accessor<_Index, _Types...>::get(
1792 (((_Index != __v.index())
1793 ? __throw_bad_variant_access<int>("Bad Variant index in get")
1794 : 0),
1795 std::move(__v)));
1796 }
1797
1798 template <ptrdiff_t _Index, typename... _Types>
1799 constexpr const typename __indexed_type<_Index, _Types...>::__type&& get(
1800 Variant<_Types...> const&& __v) {
1801 return __variant_accessor<_Index, _Types...>::get(
1802 (((_Index != __v.index())
1803 ? __throw_bad_variant_access<int>("Bad Variant index in get")
1804 : 0),
1805 std::move(__v)));
1806 }
1807
1808 template <typename _Type, typename... _Types>
1809 constexpr std::add_pointer_t<_Type> get_if(Variant<_Types...>& __v) {
1810 return (__type_index<_Type, _Types...>::__value != __v.index())
1811 ? nullptr
1812 : &get<_Type>(__v);
1813 }
1814
1815 template <typename _Type, typename... _Types>
1816 constexpr std::add_pointer_t<_Type const> get_if(
1817 Variant<_Types...> const& __v) {
1818 return (__type_index<_Type, _Types...>::__value != __v.index())
1819 ? nullptr
1820 : &get<_Type>(__v);
1821 }
1822
1823 template <ptrdiff_t _Index, typename... _Types>
1824 constexpr std::add_pointer_t<typename __indexed_type<_Index, _Types...>::__type>
1825 get_if(Variant<_Types...>& __v) {
1826 return ((_Index != __v.index())
1827 ? nullptr
1828 : &__variant_accessor<_Index, _Types...>::get(__v));
1829 }
1830
1831 template <ptrdiff_t _Index, typename... _Types>
1832 constexpr std::add_pointer_t<
1833 typename __indexed_type<_Index, _Types...>::__type const>
1834 get_if(Variant<_Types...> const& __v) {
1835 return ((_Index != __v.index())
1836 ? nullptr
1837 : &__variant_accessor<_Index, _Types...>::get(__v));
1838 }
1839
1840 template <typename _Type, typename... _Types>
1841 constexpr bool holds_alternative(Variant<_Types...> const& __v) __NOEXCEPT {
1842 return __v.index() == __type_index<_Type, _Types...>::__value;
1843 }
1844
1845 template <typename _Visitor, typename... _Types>
1846 struct __visitor_return_type;
1847
1848 template <typename _Visitor>
1849 struct __visitor_return_type<_Visitor> {
1850 typedef decltype(std::declval<_Visitor&>()()) __type;
1851 };
1852
1853 template <typename _Visitor, typename _Head, typename... _Rest>
1854 struct __visitor_return_type<_Visitor, _Head, _Rest...> {
1855 typedef decltype(std::declval<_Visitor&>()(std::declval<_Head&>())) __type;
1856 };
1857
1858 template <typename _Visitor, typename... _Types>
1859 struct __visitor_table {
1860 typedef Variant<_Types...> __variant_type;
1861 typedef
1862 typename __visitor_return_type<_Visitor, _Types...>::__type __return_type;
1863 typedef __return_type (*__func_type)(_Visitor&, __variant_type&);
1864
1865 template <typename _Type>
1866 static __return_type __trampoline_func(_Visitor& __visitor,
1867 __variant_type& __v) {
1868 return __visitor(get<_Type>(__v));
1869 }
1870
1871 static const __func_type __trampoline[sizeof...(_Types)];
1872 };
1873
1874 template <typename _Visitor, typename... _Types>
1875 const typename __visitor_table<_Visitor, _Types...>::__func_type
1876 __visitor_table<_Visitor, _Types...>::__trampoline[sizeof...(_Types)] = {
1877 &__trampoline_func<_Types>...};
1878
1879 template <typename _Visitor, typename... _Types>
1880 constexpr typename __visitor_return_type<_Visitor, _Types...>::__type visit(
1881 _Visitor&& __visitor,
1882 Variant<_Types...>& __v) {
1883 return (__v.valueless_by_exception())
1884 ? __throw_bad_variant_access<
1885 typename __visitor_return_type<_Visitor, _Types...>::__type>(
1886 "Visiting of empty Variant")
1887 : __visitor_table<_Visitor, _Types...>::__trampoline[__v.index()](
1888 __visitor, __v);
1889 }
1890
1891 template <typename _Visitor, typename... _Variants>
1892 struct __multi_visitor_return_type {
1893 typedef decltype(
1894 std::declval<_Visitor&>()(get<0>(std::declval<_Variants>())...)) __type;
1895 };
1896
1897 template <size_t _VariantIndex, typename _Indices>
1898 struct __visit_helper;
1899
1900 template <ptrdiff_t... _Indices>
1901 struct __visit_helper<0, __index_sequence<_Indices...>> {
1902 template <typename _Visitor, typename... _Variants>
1903 static constexpr
1904 typename __multi_visitor_return_type<_Visitor, _Variants...>::__type
1905 __visit(_Visitor& __visitor, _Variants&... __v) {
1906 return __visitor(get<_Indices>(__v)...);
1907 }
1908 };
1909
1910 template <size_t _Index, typename... _Args>
1911 struct __arg_selector_t;
1912
1913 template <typename _Head, typename... _Rest>
1914 struct __arg_selector_t<0, _Head, _Rest...> {
1915 typedef _Head __type;
1916
1917 static constexpr __type& __select(_Head& __head, _Rest&...) { return __head; }
1918 };
1919
1920 template <size_t _Index, typename _Head, typename... _Rest>
1921 struct __arg_selector_t<_Index, _Head, _Rest...> {
1922 typedef typename __arg_selector_t<_Index - 1, _Rest...>::__type __type;
1923 static constexpr __type& __select(_Head&, _Rest&... __rest) {
1924 return __arg_selector_t<_Index - 1, _Rest...>::__select(__rest...);
1925 }
1926 };
1927
1928 template <size_t _Index, typename... _Args>
1929 constexpr typename __arg_selector_t<_Index, _Args...>::__type&& __arg_selector(
1930 _Args&&... __args) {
1931 return std::forward<typename __arg_selector_t<_Index, _Args...>::__type>(
1932 __arg_selector_t<_Index, _Args...>::__select(__args...));
1933 }
1934
1935 template <ptrdiff_t _Index, size_t _VariantIndex, ptrdiff_t... _Indices>
1936 struct __visit_helper2 {
1937 template <typename _Visitor, typename... _Variants>
1938 static constexpr
1939 typename __multi_visitor_return_type<_Visitor, _Variants...>::__type
1940 __visit(_Visitor& __visitor, _Variants&&... __v) {
1941 return (__arg_selector<_VariantIndex - 1>(__v...).index() == _Index)
1942 ? __visit_helper<_VariantIndex - 1,
1943 __index_sequence<_Index, _Indices...>>::
1944 __visit(__visitor, std::forward<_Variants>(__v)...)
1945 : __visit_helper2<_Index - 1, _VariantIndex,
1946 _Indices...>::__visit(__visitor,
1947 std::forward<_Variants>(
1948 __v)...);
1949 }
1950 };
1951
1952 template <size_t _VariantIndex, ptrdiff_t... _Indices>
1953 struct __visit_helper2<-1, _VariantIndex, _Indices...> {
1954 template <typename _Visitor, typename... _Variants>
1955 static constexpr
1956 typename __multi_visitor_return_type<_Visitor, _Variants...>::__type
1957 __visit(_Visitor&, _Variants&&...) {
1958 return __throw_bad_variant_access<
1959 typename __multi_visitor_return_type<_Visitor, _Variants...>::__type>(
1960 "Visiting of empty Variant");
1961 }
1962 };
1963
1964 template <typename _Variant>
1965 struct __variant_type_count;
1966
1967 template <typename... _Types>
1968 struct __variant_type_count<Variant<_Types...>> {
1969 static constexpr size_t __value = sizeof...(_Types);
1970 };
1971
1972 template <typename _Variant>
1973 struct __variant_type_count<_Variant&> {
1974 static constexpr size_t __value = __variant_type_count<_Variant>::__value;
1975 };
1976
1977 template <typename _Variant>
1978 struct __variant_type_count<_Variant const&> {
1979 static constexpr size_t __value = __variant_type_count<_Variant>::__value;
1980 };
1981
1982 template <size_t _VariantIndex, ptrdiff_t... _Indices>
1983 struct __visit_helper<_VariantIndex, __index_sequence<_Indices...>> {
1984 template <typename _Visitor, typename... _Variants>
1985 static constexpr
1986 typename __multi_visitor_return_type<_Visitor, _Variants...>::__type
1987 __visit(_Visitor& __visitor, _Variants&&... __v) {
1988 return __visit_helper2<
1989 __variant_type_count<typename __arg_selector_t<
1990 _VariantIndex - 1, _Variants...>::__type>::__value -
1991 1,
1992 _VariantIndex, _Indices...>::__visit(__visitor,
1993 std::forward<_Variants&&>(__v)...);
1994 }
1995 };
1996
1997 template <typename _Visitor, typename... _Variants>
1998 constexpr typename __multi_visitor_return_type<_Visitor, _Variants...>::__type
1999 visit(_Visitor&& __visitor, _Variants&&... __v) {
2000 return __visit_helper<sizeof...(_Variants), __index_sequence<>>::__visit(
2001 __visitor, std::forward<_Variants>(__v)...);
2002 }
2003
2004 template <typename... _Types>
2005 constexpr bool operator==(Variant<_Types...> const& __lhs,
2006 Variant<_Types...> const& __rhs) {
2007 return (__lhs.index() == __rhs.index()) &&
2008 ((__lhs.index() == -1) ||
2009 __equality_op_table<
2010 Variant<_Types...>>::__equality_compare[__lhs.index()](__lhs,
2011 __rhs));
2012 }
2013
2014 template <typename... _Types>
2015 constexpr bool operator!=(Variant<_Types...> const& __lhs,
2016 Variant<_Types...> const& __rhs) {
2017 return !(__lhs == __rhs);
2018 }
2019
2020 template <typename... _Types>
2021 constexpr bool operator<(Variant<_Types...> const& __lhs,
2022 Variant<_Types...> const& __rhs) {
2023 return (__lhs.index() < __rhs.index()) ||
2024 ((__lhs.index() == __rhs.index()) &&
2025 ((__lhs.index() != -1) &&
2026 __less_than_op_table<
2027 Variant<_Types...>>::__less_than_compare[__lhs.index()](__lhs,
2028 __rhs)));
2029 }
2030
2031 template <typename... _Types>
2032 constexpr bool operator>(Variant<_Types...> const& __lhs,
2033 Variant<_Types...> const& __rhs) {
2034 return __rhs < __lhs;
2035 }
2036
2037 template <typename... _Types>
2038 constexpr bool operator>=(Variant<_Types...> const& __lhs,
2039 Variant<_Types...> const& __rhs) {
2040 return !(__lhs < __rhs);
2041 }
2042
2043 template <typename... _Types>
2044 constexpr bool operator<=(Variant<_Types...> const& __lhs,
2045 Variant<_Types...> const& __rhs) {
2046 return !(__lhs > __rhs);
2047 }
2048
2049 struct Monostate {};
2050
2051 constexpr inline bool operator==(Monostate const&, Monostate const&) {
2052 return true;
2053 }
2054 constexpr inline bool operator!=(Monostate const&, Monostate const&) {
2055 return false;
2056 }
2057 constexpr inline bool operator>=(Monostate const&, Monostate const&) {
2058 return true;
2059 }
2060 constexpr inline bool operator<=(Monostate const&, Monostate const&) {
2061 return true;
2062 }
2063 constexpr inline bool operator>(Monostate const&, Monostate const&) {
2064 return false;
2065 }
2066 constexpr inline bool operator<(Monostate const&, Monostate const&) {
2067 return false;
2068 }
2069
2070 struct __hash_visitor {
2071 template <typename _Type>
2072 size_t operator()(_Type const& __x) {
2073 return std::hash<_Type>()(__x);
2074 }
2075 };
2076
2077 // -- WebKit Additions --
2078
2079 template <class V, class... F>
2080 auto switchOn(V&& v, F&&... f)
2081 -> decltype(visit(makeVisitor(std::forward<F>(f)...), std::forward<V>(v))) {
2082 return visit(makeVisitor(std::forward<F>(f)...), std::forward<V>(v));
2083 }
2084
2085 } // namespace WTF
2086
2087 namespace std {
2088
2089 template <>
2090 struct hash<WTF::Monostate> {
2091 size_t operator()(WTF::Monostate) __NOEXCEPT { return 42; }
2092 };
2093
2094 template <typename... _Types>
2095 struct hash<WTF::Variant<_Types...>> {
2096 size_t operator()(WTF::Variant<_Types...> const& v) __NOEXCEPT {
2097 return std::hash<ptrdiff_t>()(v.index()) ^
2098 WTF::visit(WTF::__hash_visitor(), v);
2099 }
2100 };
2101
2102 } // namespace std
2103
2104 using WTF::Monostate;
2105 using WTF::Variant;
2106
2107 #if COMPILER(MSVC)
2108 #pragma warning(pop)
2109 #endif
2110
2111 #endif
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/web/api/frame.h ('k') | third_party/WebKit/Tools/Scripts/webkitpy/style/checker.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698