21 #if !defined(VISKORES_DEVICE) || !defined(VISKORES_NAMESPACE)
22 #error VarianImplDetail.h must be included from VariantImpl.h
24 #define VISKORES_DEVICE
25 #define VISKORES_NAMESPACE tmp
33 #include <viskoresstd/is_trivial.h>
37 #include <type_traits>
50 template <
typename... Ts>
55 using Constructible = viskoresstd::is_trivially_constructible<T>;
57 template <
typename... Ts>
60 template <
typename... Ts>
61 using AllTriviallyDestructible =
66 #if defined(VISKORES_GCC) && (__GNUC__ == 5)
68 template <
typename T0>
69 constexpr std::size_t MaxSizeOf()
73 template <
typename T0,
typename T1,
typename... Ts>
74 constexpr std::size_t MaxSizeOf()
76 return std::max(
sizeof(T0), MaxSizeOf<T1, Ts...>());
79 template <
typename... Ts>
80 constexpr std::size_t MaxSizeOf()
82 return std::max({
sizeof(Ts)... });
88 template <
typename... Ts>
89 constexpr std::size_t MaxAlignmentOf()
91 return std::max({ std::alignment_of<Ts>::value... });
106 template <std::
size_t Alignment>
107 struct TypeForAlignmentImpl;
109 struct TypeForAlignmentImpl<8>
114 struct TypeForAlignmentImpl<4>
119 struct TypeForAlignmentImpl<2>
124 struct TypeForAlignmentImpl<1>
128 template <std::
size_t Alignment>
129 using TypeForAlignment =
typename TypeForAlignmentImpl<Alignment>::type;
131 template <std::
size_t Size,
typename Word,
bool = (Size >= 4)>
132 struct SizedPlaceholderImpl;
134 template <std::
size_t Size,
typename Word>
135 struct SizedPlaceholderImpl<Size, Word, true>
141 SizedPlaceholderImpl<Size - 4, Word> E;
143 template <
typename Word>
144 struct SizedPlaceholderImpl<4, Word, true>
152 template <std::
size_t Size,
typename Word>
153 struct SizedPlaceholderImpl<Size, Word, false>
156 SizedPlaceholderImpl<Size - 1, Word> B;
158 template <
typename Word>
159 struct SizedPlaceholderImpl<1, Word, false>
164 template <
typename... Ts>
165 struct SizedPlaceholder
166 : SizedPlaceholderImpl<(MaxSizeOf<Ts...>() / MaxAlignmentOf<Ts...>()),
167 TypeForAlignment<MaxAlignmentOf<Ts...>()>>
204 template <
typename T0,
typename... Ts>
205 union VariantUnionTD;
208 template <
typename T0,
typename... Ts>
209 union VariantUnionNTD;
211 template <
typename T0>
212 union VariantUnionTD<T0>
216 SizedPlaceholder<T0> Placeholder;
220 VariantUnionTD() =
default;
222 template <
typename T0>
223 union VariantUnionNTD<T0>
227 SizedPlaceholder<T0> Placeholder;
231 VariantUnionNTD() =
default;
235 template <
typename T0,
typename T1>
236 union VariantUnionTD<T0, T1>
240 SizedPlaceholder<T0, T1> Placeholder;
245 VariantUnionTD() =
default;
247 template <
typename T0,
typename T1>
248 union VariantUnionNTD<T0, T1>
252 SizedPlaceholder<T0, T1> Placeholder;
257 VariantUnionNTD() =
default;
261 template <
typename T0,
typename T1,
typename T2>
262 union VariantUnionTD<T0, T1, T2>
266 SizedPlaceholder<T0, T1, T2> Placeholder;
272 VariantUnionTD() =
default;
274 template <
typename T0,
typename T1,
typename T2>
275 union VariantUnionNTD<T0, T1, T2>
279 SizedPlaceholder<T0, T1, T2> Placeholder;
285 VariantUnionNTD() =
default;
289 template <
typename T0,
typename T1,
typename T2,
typename T3>
290 union VariantUnionTD<T0, T1, T2, T3>
294 SizedPlaceholder<T0, T1, T2, T3> Placeholder;
301 VariantUnionTD() =
default;
303 template <
typename T0,
typename T1,
typename T2,
typename T3>
304 union VariantUnionNTD<T0, T1, T2, T3>
308 SizedPlaceholder<T0, T1, T2, T3> Placeholder;
315 VariantUnionNTD() =
default;
319 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4>
320 union VariantUnionTD<T0, T1, T2, T3, T4>
324 SizedPlaceholder<T0, T1, T2, T3, T4> Placeholder;
332 VariantUnionTD() =
default;
334 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4>
335 union VariantUnionNTD<T0, T1, T2, T3, T4>
339 SizedPlaceholder<T0, T1, T2, T3, T4> Placeholder;
347 VariantUnionNTD() =
default;
351 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
352 union VariantUnionTD<T0, T1, T2, T3, T4, T5>
356 SizedPlaceholder<T0, T1, T2, T3, T4, T5> Placeholder;
365 VariantUnionTD() =
default;
367 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
368 union VariantUnionNTD<T0, T1, T2, T3, T4, T5>
372 SizedPlaceholder<T0, T1, T2, T3, T4, T5> Placeholder;
381 VariantUnionNTD() =
default;
385 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6>
386 union VariantUnionTD<T0, T1, T2, T3, T4, T5, T6>
390 SizedPlaceholder<T0, T1, T2, T3, T4, T5, T6> Placeholder;
400 VariantUnionTD() =
default;
402 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6>
403 union VariantUnionNTD<T0, T1, T2, T3, T4, T5, T6>
407 SizedPlaceholder<T0, T1, T2, T3, T4, T5, T6> Placeholder;
417 VariantUnionNTD() =
default;
421 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7>
422 union VariantUnionTD<T0, T1, T2, T3, T4, T5, T6, T7>
426 SizedPlaceholder<T0, T1, T2, T3, T4, T5, T6, T7> Placeholder;
437 VariantUnionTD() =
default;
439 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7>
440 union VariantUnionNTD<T0, T1, T2, T3, T4, T5, T6, T7>
444 SizedPlaceholder<T0, T1, T2, T3, T4, T5, T6, T7> Placeholder;
455 VariantUnionNTD() =
default;
460 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7,
typename T8,
typename... Ts>
461 union VariantUnionTD<T0, T1, T2, T3, T4, T5, T6, T7, T8, Ts...>
466 SizedPlaceholder<T0, T1, T2, T3, T4, T5, T6, T7, T8, Ts...> Placeholder;
476 VariantUnionTD<T8, Ts...> Remaining;
479 VariantUnionTD() =
default;
482 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7,
typename T8,
typename... Ts>
483 union VariantUnionNTD<T0, T1, T2, T3, T4, T5, T6, T7, T8, Ts...>
488 SizedPlaceholder<T0, T1, T2, T3, T4, T5, T6, T7, T8, Ts...> Placeholder;
498 VariantUnionNTD<T8, Ts...> Remaining;
501 VariantUnionNTD() =
default;
507 template <
bool TrivialConstructor,
typename... Ts>
508 struct VariantUnionFinder;
510 template <
typename... Ts>
511 struct VariantUnionFinder<true, Ts...>
513 using type = VariantUnionTD<Ts...>;
515 template <
typename... Ts>
516 struct VariantUnionFinder<false, Ts...>
518 using type = VariantUnionNTD<Ts...>;
521 template <
typename... Ts>
523 typename VariantUnionFinder<AllTriviallyDestructible<Ts...>::value, Ts...>::type;
527 template <viskores::IdComponent I,
typename UnionType>
528 struct VariantUnionGetImpl;
530 template <
typename UnionType>
531 struct VariantUnionGetImpl<0, UnionType>
533 using ReturnType = decltype(std::declval<UnionType>().V0);
544 template <
typename UnionType>
545 struct VariantUnionGetImpl<1, UnionType>
547 using ReturnType = decltype(std::declval<UnionType>().V1);
558 template <
typename UnionType>
559 struct VariantUnionGetImpl<2, UnionType>
561 using ReturnType = decltype(std::declval<UnionType>().V2);
572 template <
typename UnionType>
573 struct VariantUnionGetImpl<3, UnionType>
575 using ReturnType = decltype(std::declval<UnionType>().V3);
586 template <
typename UnionType>
587 struct VariantUnionGetImpl<4, UnionType>
589 using ReturnType = decltype(std::declval<UnionType>().V4);
600 template <
typename UnionType>
601 struct VariantUnionGetImpl<5, UnionType>
603 using ReturnType = decltype(std::declval<UnionType>().V5);
614 template <
typename UnionType>
615 struct VariantUnionGetImpl<6, UnionType>
617 using ReturnType = decltype(std::declval<UnionType>().V6);
628 template <
typename UnionType>
629 struct VariantUnionGetImpl<7, UnionType>
631 using ReturnType = decltype(std::declval<UnionType>().V7);
643 template <viskores::IdComponent I,
typename UnionType>
644 struct VariantUnionGetImpl
647 using RecursiveGet = VariantUnionGetImpl<I - 8, decltype(std::declval<UnionType&>().Remaining)>;
648 using ReturnType =
typename RecursiveGet::ReturnType;
659 template <viskores::IdComponent I,
typename UnionType>
661 -> decltype(VariantUnionGetImpl<I,
typename std::decay<UnionType>::type>::
Get(storage))&
663 return VariantUnionGetImpl<I, typename std::decay<UnionType>::type>
::Get(storage);
668 template <std::
size_t NumCases>
671 template <
typename Functor,
typename UnionType,
typename... Args>
679 __attribute__((noinline))
687 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
688 -> decltype(f(storage.V0, args...))
698 return f(storage.V0, std::forward<Args>(args)...);
704 return f(storage.V1, std::forward<Args>(args)...);
710 return f(storage.V2, std::forward<Args>(args)...);
716 return f(storage.V3, std::forward<Args>(args)...);
722 return f(storage.V4, std::forward<Args>(args)...);
728 return f(storage.V5, std::forward<Args>(args)...);
734 return f(storage.V6, std::forward<Args>(args)...);
740 return f(storage.V7, std::forward<Args>(args)...);
742 return VariantCases<NumCases - 8>::template CastAndCall<>(
743 index - 8, std::forward<Functor>(f), storage.Remaining, std::forward<Args>(args)...);
749 struct VariantCases<1>
751 template <
typename Functor,
typename UnionType,
typename... Args>
756 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
757 -> decltype(f(storage.V0, args...))
762 return f(storage.V0, std::forward<Args>(args)...);
767 struct VariantCases<2>
769 template <
typename Functor,
typename UnionType,
typename... Args>
777 __attribute__((noinline))
785 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
786 -> decltype(f(storage.V0, args...))
798 return f(storage.V0, std::forward<Args>(args)...);
804 return f(storage.V1, std::forward<Args>(args)...);
809 struct VariantCases<3>
811 template <
typename Functor,
typename UnionType,
typename... Args>
819 __attribute__((noinline))
827 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
828 -> decltype(f(storage.V0, args...))
840 return f(storage.V0, std::forward<Args>(args)...);
846 return f(storage.V1, std::forward<Args>(args)...);
852 return f(storage.V2, std::forward<Args>(args)...);
857 struct VariantCases<4>
859 template <
typename Functor,
typename UnionType,
typename... Args>
867 __attribute__((noinline))
875 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
876 -> decltype(f(storage.V0, args...))
888 return f(storage.V0, std::forward<Args>(args)...);
894 return f(storage.V1, std::forward<Args>(args)...);
900 return f(storage.V2, std::forward<Args>(args)...);
906 return f(storage.V3, std::forward<Args>(args)...);
911 struct VariantCases<5>
913 template <
typename Functor,
typename UnionType,
typename... Args>
921 __attribute__((noinline))
929 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
930 -> decltype(f(storage.V0, args...))
942 return f(storage.V0, std::forward<Args>(args)...);
948 return f(storage.V1, std::forward<Args>(args)...);
954 return f(storage.V2, std::forward<Args>(args)...);
960 return f(storage.V3, std::forward<Args>(args)...);
966 return f(storage.V4, std::forward<Args>(args)...);
971 struct VariantCases<6>
973 template <
typename Functor,
typename UnionType,
typename... Args>
981 __attribute__((noinline))
989 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
990 -> decltype(f(storage.V0, args...))
1002 return f(storage.V0, std::forward<Args>(args)...);
1008 return f(storage.V1, std::forward<Args>(args)...);
1014 return f(storage.V2, std::forward<Args>(args)...);
1020 return f(storage.V3, std::forward<Args>(args)...);
1026 return f(storage.V4, std::forward<Args>(args)...);
1032 return f(storage.V5, std::forward<Args>(args)...);
1037 struct VariantCases<7>
1039 template <
typename Functor,
typename UnionType,
typename... Args>
1047 __attribute__((noinline))
1055 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
1056 -> decltype(f(storage.V0, args...))
1068 return f(storage.V0, std::forward<Args>(args)...);
1074 return f(storage.V1, std::forward<Args>(args)...);
1080 return f(storage.V2, std::forward<Args>(args)...);
1086 return f(storage.V3, std::forward<Args>(args)...);
1092 return f(storage.V4, std::forward<Args>(args)...);
1098 return f(storage.V5, std::forward<Args>(args)...);
1104 return f(storage.V6, std::forward<Args>(args)...);
1109 struct VariantCases<8>
1111 template <
typename Functor,
typename UnionType,
typename... Args>
1119 __attribute__((noinline))
1127 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
1128 -> decltype(f(storage.V0, args...))
1140 return f(storage.V0, std::forward<Args>(args)...);
1146 return f(storage.V1, std::forward<Args>(args)...);
1152 return f(storage.V2, std::forward<Args>(args)...);
1158 return f(storage.V3, std::forward<Args>(args)...);
1164 return f(storage.V4, std::forward<Args>(args)...);
1170 return f(storage.V5, std::forward<Args>(args)...);
1176 return f(storage.V6, std::forward<Args>(args)...);
1182 return f(storage.V7, std::forward<Args>(args)...);
1188 template <std::size_t UnionSize,
typename Functor,
typename UnionType,
typename... Args>
1193 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
1194 -> decltype(f(storage.V0, args...))
1197 index, std::forward<Functor>(f), storage, std::forward<Args>(args)...);