13 #if !defined(VTK_M_DEVICE) || !defined(VTK_M_NAMESPACE)
14 #error VarianImplDetail.h must be included from VariantImpl.h
17 #define VTK_M_NAMESPACE tmp
25 #include <vtkmstd/is_trivial.h>
27 #include <type_traits>
40 template <
typename... Ts>
45 using Constructible = vtkmstd::is_trivially_constructible<T>;
47 template <
typename... Ts>
50 template <
typename... Ts>
51 using AllTriviallyDestructible =
87 template <
typename T0,
typename... Ts>
91 template <
typename T0,
typename... Ts>
92 union VariantUnionNTD;
94 template <
typename T0>
95 union VariantUnionTD<T0>
98 VTK_M_DEVICE VariantUnionTD(vtkm::internal::NullType) { }
99 VariantUnionTD() =
default;
101 template <
typename T0>
102 union VariantUnionNTD<T0>
105 VTK_M_DEVICE VariantUnionNTD(vtkm::internal::NullType) { }
106 VariantUnionNTD() =
default;
110 template <
typename T0,
typename T1>
111 union VariantUnionTD<T0, T1>
115 VTK_M_DEVICE VariantUnionTD(vtkm::internal::NullType) { }
116 VariantUnionTD() =
default;
118 template <
typename T0,
typename T1>
119 union VariantUnionNTD<T0, T1>
123 VTK_M_DEVICE VariantUnionNTD(vtkm::internal::NullType) { }
124 VariantUnionNTD() =
default;
128 template <
typename T0,
typename T1,
typename T2>
129 union VariantUnionTD<T0, T1, T2>
134 VTK_M_DEVICE VariantUnionTD(vtkm::internal::NullType) { }
135 VariantUnionTD() =
default;
137 template <
typename T0,
typename T1,
typename T2>
138 union VariantUnionNTD<T0, T1, T2>
143 VTK_M_DEVICE VariantUnionNTD(vtkm::internal::NullType) { }
144 VariantUnionNTD() =
default;
148 template <
typename T0,
typename T1,
typename T2,
typename T3>
149 union VariantUnionTD<T0, T1, T2, T3>
155 VTK_M_DEVICE VariantUnionTD(vtkm::internal::NullType) { }
156 VariantUnionTD() =
default;
158 template <
typename T0,
typename T1,
typename T2,
typename T3>
159 union VariantUnionNTD<T0, T1, T2, T3>
165 VTK_M_DEVICE VariantUnionNTD(vtkm::internal::NullType) { }
166 VariantUnionNTD() =
default;
170 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4>
171 union VariantUnionTD<T0, T1, T2, T3, T4>
178 VTK_M_DEVICE VariantUnionTD(vtkm::internal::NullType) { }
179 VariantUnionTD() =
default;
181 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4>
182 union VariantUnionNTD<T0, T1, T2, T3, T4>
189 VTK_M_DEVICE VariantUnionNTD(vtkm::internal::NullType) { }
190 VariantUnionNTD() =
default;
194 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
195 union VariantUnionTD<T0, T1, T2, T3, T4, T5>
203 VTK_M_DEVICE VariantUnionTD(vtkm::internal::NullType) { }
204 VariantUnionTD() =
default;
206 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
207 union VariantUnionNTD<T0, T1, T2, T3, T4, T5>
215 VTK_M_DEVICE VariantUnionNTD(vtkm::internal::NullType) { }
216 VariantUnionNTD() =
default;
220 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6>
221 union VariantUnionTD<T0, T1, T2, T3, T4, T5, T6>
230 VTK_M_DEVICE VariantUnionTD(vtkm::internal::NullType) { }
231 VariantUnionTD() =
default;
233 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6>
234 union VariantUnionNTD<T0, T1, T2, T3, T4, T5, T6>
243 VTK_M_DEVICE VariantUnionNTD(vtkm::internal::NullType) { }
244 VariantUnionNTD() =
default;
248 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7>
249 union VariantUnionTD<T0, T1, T2, T3, T4, T5, T6, T7>
259 VTK_M_DEVICE VariantUnionTD(vtkm::internal::NullType) { }
260 VariantUnionTD() =
default;
262 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7>
263 union VariantUnionNTD<T0, T1, T2, T3, T4, T5, T6, T7>
273 VTK_M_DEVICE VariantUnionNTD(vtkm::internal::NullType) { }
274 VariantUnionNTD() =
default;
279 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7,
typename T8,
typename... Ts>
280 union VariantUnionTD<T0, T1, T2, T3, T4, T5, T6, T7, T8, Ts...>
290 VariantUnionTD<T8, Ts...> Remaining;
292 VTK_M_DEVICE VariantUnionTD(vtkm::internal::NullType) { }
293 VariantUnionTD() =
default;
296 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7,
typename T8,
typename... Ts>
297 union VariantUnionNTD<T0, T1, T2, T3, T4, T5, T6, T7, T8, Ts...>
307 VariantUnionNTD<T8, Ts...> Remaining;
309 VTK_M_DEVICE VariantUnionNTD(vtkm::internal::NullType) { }
310 VariantUnionNTD() =
default;
316 template <
bool TrivialConstructor,
typename... Ts>
317 struct VariantUnionFinder;
319 template <
typename... Ts>
320 struct VariantUnionFinder<true, Ts...>
322 using type = VariantUnionTD<Ts...>;
324 template <
typename... Ts>
325 struct VariantUnionFinder<false, Ts...>
327 using type = VariantUnionNTD<Ts...>;
330 template <
typename... Ts>
332 typename VariantUnionFinder<AllTriviallyDestructible<Ts...>::value, Ts...>::type;
336 template <vtkm::IdComponent I,
typename UnionType>
337 struct VariantUnionGetImpl;
339 template <
typename UnionType>
340 struct VariantUnionGetImpl<0, UnionType>
342 using ReturnType = decltype(std::declval<UnionType>().V0);
347 VTK_M_DEVICE static const ReturnType&
Get(
const UnionType& storage) noexcept
353 template <
typename UnionType>
354 struct VariantUnionGetImpl<1, UnionType>
356 using ReturnType = decltype(std::declval<UnionType>().V1);
361 VTK_M_DEVICE static const ReturnType&
Get(
const UnionType& storage) noexcept
367 template <
typename UnionType>
368 struct VariantUnionGetImpl<2, UnionType>
370 using ReturnType = decltype(std::declval<UnionType>().V2);
375 VTK_M_DEVICE static const ReturnType&
Get(
const UnionType& storage) noexcept
381 template <
typename UnionType>
382 struct VariantUnionGetImpl<3, UnionType>
384 using ReturnType = decltype(std::declval<UnionType>().V3);
389 VTK_M_DEVICE static const ReturnType&
Get(
const UnionType& storage) noexcept
395 template <
typename UnionType>
396 struct VariantUnionGetImpl<4, UnionType>
398 using ReturnType = decltype(std::declval<UnionType>().V4);
403 VTK_M_DEVICE static const ReturnType&
Get(
const UnionType& storage) noexcept
409 template <
typename UnionType>
410 struct VariantUnionGetImpl<5, UnionType>
412 using ReturnType = decltype(std::declval<UnionType>().V5);
417 VTK_M_DEVICE static const ReturnType&
Get(
const UnionType& storage) noexcept
423 template <
typename UnionType>
424 struct VariantUnionGetImpl<6, UnionType>
426 using ReturnType = decltype(std::declval<UnionType>().V6);
431 VTK_M_DEVICE static const ReturnType&
Get(
const UnionType& storage) noexcept
437 template <
typename UnionType>
438 struct VariantUnionGetImpl<7, UnionType>
440 using ReturnType = decltype(std::declval<UnionType>().V7);
445 VTK_M_DEVICE static const ReturnType&
Get(
const UnionType& storage) noexcept
452 template <vtkm::IdComponent I,
typename UnionType>
453 struct VariantUnionGetImpl
456 using RecursiveGet = VariantUnionGetImpl<I - 8, decltype(std::declval<UnionType&>().Remaining)>;
457 using ReturnType =
typename RecursiveGet::ReturnType;
462 VTK_M_DEVICE static const ReturnType&
Get(
const UnionType& storage) noexcept
468 template <vtkm::IdComponent I,
typename UnionType>
469 VTK_M_DEVICE auto VariantUnionGet(UnionType& storage) noexcept
470 -> decltype(VariantUnionGetImpl<I,
typename std::decay<UnionType>::type>::
Get(storage))&
472 return VariantUnionGetImpl<I, typename std::decay<UnionType>::type>
::Get(storage);
477 template <std::
size_t NumCases>
480 template <
typename Functor,
typename UnionType,
typename... Args>
488 __attribute__((noinline))
496 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
497 -> decltype(f(storage.V0, args...))
507 return f(storage.V0, std::forward<Args>(args)...);
513 return f(storage.V1, std::forward<Args>(args)...);
519 return f(storage.V2, std::forward<Args>(args)...);
525 return f(storage.V3, std::forward<Args>(args)...);
531 return f(storage.V4, std::forward<Args>(args)...);
537 return f(storage.V5, std::forward<Args>(args)...);
543 return f(storage.V6, std::forward<Args>(args)...);
549 return f(storage.V7, std::forward<Args>(args)...);
551 return VariantCases<NumCases - 8>::template
CastAndCall(
552 index - 8, std::forward<Functor>(f), storage.Remaining, std::forward<Args>(args)...);
558 struct VariantCases<1>
560 template <
typename Functor,
typename UnionType,
typename... Args>
565 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
566 -> decltype(f(storage.V0, args...))
571 return f(storage.V0, std::forward<Args>(args)...);
576 struct VariantCases<2>
578 template <
typename Functor,
typename UnionType,
typename... Args>
586 __attribute__((noinline))
594 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
595 -> decltype(f(storage.V0, args...))
607 return f(storage.V0, std::forward<Args>(args)...);
613 return f(storage.V1, std::forward<Args>(args)...);
618 struct VariantCases<3>
620 template <
typename Functor,
typename UnionType,
typename... Args>
628 __attribute__((noinline))
636 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
637 -> decltype(f(storage.V0, args...))
649 return f(storage.V0, std::forward<Args>(args)...);
655 return f(storage.V1, std::forward<Args>(args)...);
661 return f(storage.V2, std::forward<Args>(args)...);
666 struct VariantCases<4>
668 template <
typename Functor,
typename UnionType,
typename... Args>
676 __attribute__((noinline))
684 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
685 -> decltype(f(storage.V0, args...))
697 return f(storage.V0, std::forward<Args>(args)...);
703 return f(storage.V1, std::forward<Args>(args)...);
709 return f(storage.V2, std::forward<Args>(args)...);
715 return f(storage.V3, std::forward<Args>(args)...);
720 struct VariantCases<5>
722 template <
typename Functor,
typename UnionType,
typename... Args>
730 __attribute__((noinline))
738 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
739 -> decltype(f(storage.V0, args...))
751 return f(storage.V0, std::forward<Args>(args)...);
757 return f(storage.V1, std::forward<Args>(args)...);
763 return f(storage.V2, std::forward<Args>(args)...);
769 return f(storage.V3, std::forward<Args>(args)...);
775 return f(storage.V4, std::forward<Args>(args)...);
780 struct VariantCases<6>
782 template <
typename Functor,
typename UnionType,
typename... Args>
790 __attribute__((noinline))
798 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
799 -> decltype(f(storage.V0, args...))
811 return f(storage.V0, std::forward<Args>(args)...);
817 return f(storage.V1, std::forward<Args>(args)...);
823 return f(storage.V2, std::forward<Args>(args)...);
829 return f(storage.V3, std::forward<Args>(args)...);
835 return f(storage.V4, std::forward<Args>(args)...);
841 return f(storage.V5, std::forward<Args>(args)...);
846 struct VariantCases<7>
848 template <
typename Functor,
typename UnionType,
typename... Args>
856 __attribute__((noinline))
864 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
865 -> decltype(f(storage.V0, args...))
877 return f(storage.V0, std::forward<Args>(args)...);
883 return f(storage.V1, std::forward<Args>(args)...);
889 return f(storage.V2, std::forward<Args>(args)...);
895 return f(storage.V3, std::forward<Args>(args)...);
901 return f(storage.V4, std::forward<Args>(args)...);
907 return f(storage.V5, std::forward<Args>(args)...);
913 return f(storage.V6, std::forward<Args>(args)...);
918 struct VariantCases<8>
920 template <
typename Functor,
typename UnionType,
typename... Args>
928 __attribute__((noinline))
936 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
937 -> decltype(f(storage.V0, args...))
949 return f(storage.V0, std::forward<Args>(args)...);
955 return f(storage.V1, std::forward<Args>(args)...);
961 return f(storage.V2, std::forward<Args>(args)...);
967 return f(storage.V3, std::forward<Args>(args)...);
973 return f(storage.V4, std::forward<Args>(args)...);
979 return f(storage.V5, std::forward<Args>(args)...);
985 return f(storage.V6, std::forward<Args>(args)...);
991 return f(storage.V7, std::forward<Args>(args)...);
997 template <std::size_t UnionSize,
typename Functor,
typename UnionType,
typename... Args>
1002 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
1003 -> decltype(f(storage.V0, args...))
1006 index, std::forward<Functor>(f), storage, std::forward<Args>(args)...);