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>
29 #include <type_traits>
42 template <
typename... Ts>
47 using Constructible = vtkmstd::is_trivially_constructible<T>;
49 template <
typename... Ts>
52 template <
typename... Ts>
53 using AllTriviallyDestructible =
58 #if defined(VTKM_GCC) && (__GNUC__ == 5)
60 template <
typename T0>
61 constexpr std::size_t MaxSizeOf()
65 template <
typename T0,
typename T1,
typename... Ts>
66 constexpr std::size_t MaxSizeOf()
68 return std::max(
sizeof(T0), MaxSizeOf<T1, Ts...>());
71 template <
typename... Ts>
72 constexpr std::size_t MaxSizeOf()
74 return std::max({
sizeof(Ts)... });
80 template <
typename... Ts>
81 constexpr std::size_t MaxAlignmentOf()
83 return std::max({ std::alignment_of<Ts>::value... });
98 template <std::
size_t Alignment>
99 struct TypeForAlignmentImpl;
101 struct TypeForAlignmentImpl<8>
106 struct TypeForAlignmentImpl<4>
111 struct TypeForAlignmentImpl<2>
116 struct TypeForAlignmentImpl<1>
120 template <std::
size_t Alignment>
121 using TypeForAlignment =
typename TypeForAlignmentImpl<Alignment>::type;
123 template <std::
size_t Size,
typename Word,
bool = (Size >= 4)>
124 struct SizedPlaceholderImpl;
126 template <std::
size_t Size,
typename Word>
127 struct SizedPlaceholderImpl<Size, Word, true>
133 SizedPlaceholderImpl<Size - 4, Word> E;
135 template <
typename Word>
136 struct SizedPlaceholderImpl<4, Word, true>
144 template <std::
size_t Size,
typename Word>
145 struct SizedPlaceholderImpl<Size, Word, false>
148 SizedPlaceholderImpl<Size - 1, Word> B;
150 template <
typename Word>
151 struct SizedPlaceholderImpl<1, Word, false>
156 template <
typename... Ts>
157 struct SizedPlaceholder
158 : SizedPlaceholderImpl<(MaxSizeOf<Ts...>() / MaxAlignmentOf<Ts...>()),
159 TypeForAlignment<MaxAlignmentOf<Ts...>()>>
196 template <
typename T0,
typename... Ts>
197 union VariantUnionTD;
200 template <
typename T0,
typename... Ts>
201 union VariantUnionNTD;
203 template <
typename T0>
204 union VariantUnionTD<T0>
208 SizedPlaceholder<T0> Placeholder;
211 VTK_M_DEVICE VariantUnionTD(vtkm::internal::NullType) { }
212 VariantUnionTD() =
default;
214 template <
typename T0>
215 union VariantUnionNTD<T0>
219 SizedPlaceholder<T0> Placeholder;
222 VTK_M_DEVICE VariantUnionNTD(vtkm::internal::NullType) { }
223 VariantUnionNTD() =
default;
227 template <
typename T0,
typename T1>
228 union VariantUnionTD<T0, T1>
232 SizedPlaceholder<T0, T1> Placeholder;
236 VTK_M_DEVICE VariantUnionTD(vtkm::internal::NullType) { }
237 VariantUnionTD() =
default;
239 template <
typename T0,
typename T1>
240 union VariantUnionNTD<T0, T1>
244 SizedPlaceholder<T0, T1> Placeholder;
248 VTK_M_DEVICE VariantUnionNTD(vtkm::internal::NullType) { }
249 VariantUnionNTD() =
default;
253 template <
typename T0,
typename T1,
typename T2>
254 union VariantUnionTD<T0, T1, T2>
258 SizedPlaceholder<T0, T1, T2> Placeholder;
263 VTK_M_DEVICE VariantUnionTD(vtkm::internal::NullType) { }
264 VariantUnionTD() =
default;
266 template <
typename T0,
typename T1,
typename T2>
267 union VariantUnionNTD<T0, T1, T2>
271 SizedPlaceholder<T0, T1, T2> Placeholder;
276 VTK_M_DEVICE VariantUnionNTD(vtkm::internal::NullType) { }
277 VariantUnionNTD() =
default;
281 template <
typename T0,
typename T1,
typename T2,
typename T3>
282 union VariantUnionTD<T0, T1, T2, T3>
286 SizedPlaceholder<T0, T1, T2, T3> Placeholder;
292 VTK_M_DEVICE VariantUnionTD(vtkm::internal::NullType) { }
293 VariantUnionTD() =
default;
295 template <
typename T0,
typename T1,
typename T2,
typename T3>
296 union VariantUnionNTD<T0, T1, T2, T3>
300 SizedPlaceholder<T0, T1, T2, T3> Placeholder;
306 VTK_M_DEVICE VariantUnionNTD(vtkm::internal::NullType) { }
307 VariantUnionNTD() =
default;
311 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4>
312 union VariantUnionTD<T0, T1, T2, T3, T4>
316 SizedPlaceholder<T0, T1, T2, T3, T4> Placeholder;
323 VTK_M_DEVICE VariantUnionTD(vtkm::internal::NullType) { }
324 VariantUnionTD() =
default;
326 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4>
327 union VariantUnionNTD<T0, T1, T2, T3, T4>
331 SizedPlaceholder<T0, T1, T2, T3, T4> Placeholder;
338 VTK_M_DEVICE VariantUnionNTD(vtkm::internal::NullType) { }
339 VariantUnionNTD() =
default;
343 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
344 union VariantUnionTD<T0, T1, T2, T3, T4, T5>
348 SizedPlaceholder<T0, T1, T2, T3, T4, T5> Placeholder;
356 VTK_M_DEVICE VariantUnionTD(vtkm::internal::NullType) { }
357 VariantUnionTD() =
default;
359 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
360 union VariantUnionNTD<T0, T1, T2, T3, T4, T5>
364 SizedPlaceholder<T0, T1, T2, T3, T4, T5> Placeholder;
372 VTK_M_DEVICE VariantUnionNTD(vtkm::internal::NullType) { }
373 VariantUnionNTD() =
default;
377 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6>
378 union VariantUnionTD<T0, T1, T2, T3, T4, T5, T6>
382 SizedPlaceholder<T0, T1, T2, T3, T4, T5, T6> Placeholder;
391 VTK_M_DEVICE VariantUnionTD(vtkm::internal::NullType) { }
392 VariantUnionTD() =
default;
394 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6>
395 union VariantUnionNTD<T0, T1, T2, T3, T4, T5, T6>
399 SizedPlaceholder<T0, T1, T2, T3, T4, T5, T6> Placeholder;
408 VTK_M_DEVICE VariantUnionNTD(vtkm::internal::NullType) { }
409 VariantUnionNTD() =
default;
413 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7>
414 union VariantUnionTD<T0, T1, T2, T3, T4, T5, T6, T7>
418 SizedPlaceholder<T0, T1, T2, T3, T4, T5, T6, T7> Placeholder;
428 VTK_M_DEVICE VariantUnionTD(vtkm::internal::NullType) { }
429 VariantUnionTD() =
default;
431 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7>
432 union VariantUnionNTD<T0, T1, T2, T3, T4, T5, T6, T7>
436 SizedPlaceholder<T0, T1, T2, T3, T4, T5, T6, T7> Placeholder;
446 VTK_M_DEVICE VariantUnionNTD(vtkm::internal::NullType) { }
447 VariantUnionNTD() =
default;
452 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7,
typename T8,
typename... Ts>
453 union VariantUnionTD<T0, T1, T2, T3, T4, T5, T6, T7, T8, Ts...>
458 SizedPlaceholder<T0, T1, T2, T3, T4, T5, T6, T7, T8, Ts...> Placeholder;
468 VariantUnionTD<T8, Ts...> Remaining;
470 VTK_M_DEVICE VariantUnionTD(vtkm::internal::NullType) { }
471 VariantUnionTD() =
default;
474 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7,
typename T8,
typename... Ts>
475 union VariantUnionNTD<T0, T1, T2, T3, T4, T5, T6, T7, T8, Ts...>
480 SizedPlaceholder<T0, T1, T2, T3, T4, T5, T6, T7, T8, Ts...> Placeholder;
490 VariantUnionNTD<T8, Ts...> Remaining;
492 VTK_M_DEVICE VariantUnionNTD(vtkm::internal::NullType) { }
493 VariantUnionNTD() =
default;
499 template <
bool TrivialConstructor,
typename... Ts>
500 struct VariantUnionFinder;
502 template <
typename... Ts>
503 struct VariantUnionFinder<true, Ts...>
505 using type = VariantUnionTD<Ts...>;
507 template <
typename... Ts>
508 struct VariantUnionFinder<false, Ts...>
510 using type = VariantUnionNTD<Ts...>;
513 template <
typename... Ts>
515 typename VariantUnionFinder<AllTriviallyDestructible<Ts...>::value, Ts...>::type;
519 template <vtkm::IdComponent I,
typename UnionType>
520 struct VariantUnionGetImpl;
522 template <
typename UnionType>
523 struct VariantUnionGetImpl<0, UnionType>
525 using ReturnType = decltype(std::declval<UnionType>().V0);
530 VTK_M_DEVICE static const ReturnType&
Get(
const UnionType& storage) noexcept
536 template <
typename UnionType>
537 struct VariantUnionGetImpl<1, UnionType>
539 using ReturnType = decltype(std::declval<UnionType>().V1);
544 VTK_M_DEVICE static const ReturnType&
Get(
const UnionType& storage) noexcept
550 template <
typename UnionType>
551 struct VariantUnionGetImpl<2, UnionType>
553 using ReturnType = decltype(std::declval<UnionType>().V2);
558 VTK_M_DEVICE static const ReturnType&
Get(
const UnionType& storage) noexcept
564 template <
typename UnionType>
565 struct VariantUnionGetImpl<3, UnionType>
567 using ReturnType = decltype(std::declval<UnionType>().V3);
572 VTK_M_DEVICE static const ReturnType&
Get(
const UnionType& storage) noexcept
578 template <
typename UnionType>
579 struct VariantUnionGetImpl<4, UnionType>
581 using ReturnType = decltype(std::declval<UnionType>().V4);
586 VTK_M_DEVICE static const ReturnType&
Get(
const UnionType& storage) noexcept
592 template <
typename UnionType>
593 struct VariantUnionGetImpl<5, UnionType>
595 using ReturnType = decltype(std::declval<UnionType>().V5);
600 VTK_M_DEVICE static const ReturnType&
Get(
const UnionType& storage) noexcept
606 template <
typename UnionType>
607 struct VariantUnionGetImpl<6, UnionType>
609 using ReturnType = decltype(std::declval<UnionType>().V6);
614 VTK_M_DEVICE static const ReturnType&
Get(
const UnionType& storage) noexcept
620 template <
typename UnionType>
621 struct VariantUnionGetImpl<7, UnionType>
623 using ReturnType = decltype(std::declval<UnionType>().V7);
628 VTK_M_DEVICE static const ReturnType&
Get(
const UnionType& storage) noexcept
635 template <vtkm::IdComponent I,
typename UnionType>
636 struct VariantUnionGetImpl
639 using RecursiveGet = VariantUnionGetImpl<I - 8, decltype(std::declval<UnionType&>().Remaining)>;
640 using ReturnType =
typename RecursiveGet::ReturnType;
645 VTK_M_DEVICE static const ReturnType&
Get(
const UnionType& storage) noexcept
651 template <vtkm::IdComponent I,
typename UnionType>
652 VTK_M_DEVICE auto VariantUnionGet(UnionType& storage) noexcept
653 -> decltype(VariantUnionGetImpl<I,
typename std::decay<UnionType>::type>::
Get(storage))&
655 return VariantUnionGetImpl<I, typename std::decay<UnionType>::type>
::Get(storage);
660 template <std::
size_t NumCases>
663 template <
typename Functor,
typename UnionType,
typename... Args>
671 __attribute__((noinline))
679 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
680 -> decltype(f(storage.V0, args...))
690 return f(storage.V0, std::forward<Args>(args)...);
696 return f(storage.V1, std::forward<Args>(args)...);
702 return f(storage.V2, std::forward<Args>(args)...);
708 return f(storage.V3, std::forward<Args>(args)...);
714 return f(storage.V4, std::forward<Args>(args)...);
720 return f(storage.V5, std::forward<Args>(args)...);
726 return f(storage.V6, std::forward<Args>(args)...);
732 return f(storage.V7, std::forward<Args>(args)...);
734 return VariantCases<NumCases - 8>::template CastAndCall<>(
735 index - 8, std::forward<Functor>(f), storage.Remaining, std::forward<Args>(args)...);
741 struct VariantCases<1>
743 template <
typename Functor,
typename UnionType,
typename... Args>
748 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
749 -> decltype(f(storage.V0, args...))
754 return f(storage.V0, std::forward<Args>(args)...);
759 struct VariantCases<2>
761 template <
typename Functor,
typename UnionType,
typename... Args>
769 __attribute__((noinline))
777 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
778 -> decltype(f(storage.V0, args...))
790 return f(storage.V0, std::forward<Args>(args)...);
796 return f(storage.V1, std::forward<Args>(args)...);
801 struct VariantCases<3>
803 template <
typename Functor,
typename UnionType,
typename... Args>
811 __attribute__((noinline))
819 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
820 -> decltype(f(storage.V0, args...))
832 return f(storage.V0, std::forward<Args>(args)...);
838 return f(storage.V1, std::forward<Args>(args)...);
844 return f(storage.V2, std::forward<Args>(args)...);
849 struct VariantCases<4>
851 template <
typename Functor,
typename UnionType,
typename... Args>
859 __attribute__((noinline))
867 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
868 -> decltype(f(storage.V0, args...))
880 return f(storage.V0, std::forward<Args>(args)...);
886 return f(storage.V1, std::forward<Args>(args)...);
892 return f(storage.V2, std::forward<Args>(args)...);
898 return f(storage.V3, std::forward<Args>(args)...);
903 struct VariantCases<5>
905 template <
typename Functor,
typename UnionType,
typename... Args>
913 __attribute__((noinline))
921 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
922 -> decltype(f(storage.V0, args...))
934 return f(storage.V0, std::forward<Args>(args)...);
940 return f(storage.V1, std::forward<Args>(args)...);
946 return f(storage.V2, std::forward<Args>(args)...);
952 return f(storage.V3, std::forward<Args>(args)...);
958 return f(storage.V4, std::forward<Args>(args)...);
963 struct VariantCases<6>
965 template <
typename Functor,
typename UnionType,
typename... Args>
973 __attribute__((noinline))
981 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
982 -> decltype(f(storage.V0, args...))
994 return f(storage.V0, std::forward<Args>(args)...);
1000 return f(storage.V1, std::forward<Args>(args)...);
1006 return f(storage.V2, std::forward<Args>(args)...);
1012 return f(storage.V3, std::forward<Args>(args)...);
1018 return f(storage.V4, std::forward<Args>(args)...);
1024 return f(storage.V5, std::forward<Args>(args)...);
1029 struct VariantCases<7>
1031 template <
typename Functor,
typename UnionType,
typename... Args>
1039 __attribute__((noinline))
1047 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
1048 -> decltype(f(storage.V0, args...))
1060 return f(storage.V0, std::forward<Args>(args)...);
1066 return f(storage.V1, std::forward<Args>(args)...);
1072 return f(storage.V2, std::forward<Args>(args)...);
1078 return f(storage.V3, std::forward<Args>(args)...);
1084 return f(storage.V4, std::forward<Args>(args)...);
1090 return f(storage.V5, std::forward<Args>(args)...);
1096 return f(storage.V6, std::forward<Args>(args)...);
1101 struct VariantCases<8>
1103 template <
typename Functor,
typename UnionType,
typename... Args>
1111 __attribute__((noinline))
1119 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
1120 -> decltype(f(storage.V0, args...))
1132 return f(storage.V0, std::forward<Args>(args)...);
1138 return f(storage.V1, std::forward<Args>(args)...);
1144 return f(storage.V2, std::forward<Args>(args)...);
1150 return f(storage.V3, std::forward<Args>(args)...);
1156 return f(storage.V4, std::forward<Args>(args)...);
1162 return f(storage.V5, std::forward<Args>(args)...);
1168 return f(storage.V6, std::forward<Args>(args)...);
1174 return f(storage.V7, std::forward<Args>(args)...);
1180 template <std::size_t UnionSize,
typename Functor,
typename UnionType,
typename... Args>
1185 Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
1186 -> decltype(f(storage.V0, args...))
1189 index, std::forward<Functor>(f), storage, std::forward<Args>(args)...);