11 #if !defined(VTK_M_DEVICE) || !defined(VTK_M_NAMESPACE)
12 #error VariantImpl.h must be included from Variant.h
15 #define VTK_M_NAMESPACE tmp
30 template <
typename... Ts>
39 template <
typename UnionType>
40 struct VariantUnionToListImpl;
41 template <
typename... Ts>
42 struct VariantUnionToListImpl<detail::VariantUnionTD<Ts...>>
46 template <
typename... Ts>
47 struct VariantUnionToListImpl<detail::VariantUnionNTD<Ts...>>
52 template <
typename UnionType>
53 using VariantUnionToList =
54 typename VariantUnionToListImpl<typename std::decay<UnionType>::type>::type;
56 struct VariantCopyConstructFunctor
58 template <
typename T,
typename UnionType>
59 VTK_M_DEVICE void operator()(
const T& src, UnionType& destUnion)
const noexcept
63 new (&VariantUnionGet<Index>(destUnion)) T(src);
67 struct VariantCopyFunctor
69 template <
typename T,
typename UnionType>
70 VTK_M_DEVICE void operator()(
const T& src, UnionType& destUnion)
const noexcept
75 src, VariantUnionGet<Index>(destUnion),
typename std::is_copy_assignable<T>::type{});
79 VTK_M_DEVICE void DoCopy(
const T& src, T& dest, std::true_type)
const noexcept
85 VTK_M_DEVICE void DoCopy(
const T& src, T& dest, std::false_type)
const noexcept
100 struct VariantDestroyFunctor
102 template <
typename T>
109 template <
typename T>
110 struct VariantCheckType
118 "References are not allowed in VTK-m Variant.");
122 template <
typename VariantType>
123 struct VariantTriviallyCopyable;
125 template <
typename... Ts>
126 struct VariantTriviallyCopyable<
vtkm::VTK_M_NAMESPACE::Variant<Ts...>> : AllTriviallyCopyable<Ts...>
130 template <
typename VariantType>
131 struct VariantTriviallyConstructible;
133 template <
typename... Ts>
134 struct VariantTriviallyConstructible<
vtkm::VTK_M_NAMESPACE::Variant<Ts...>>
135 : AllTriviallyConstructible<Ts...>
141 template <
typename... Ts>
142 struct VariantStorageImpl
144 VariantUnion<Ts...> Storage;
147 VariantStorageImpl() =
default;
149 VTK_M_DEVICE VariantStorageImpl(vtkm::internal::NullType dummy)
154 template <vtkm::IdComponent Index>
160 return (this->Index >= 0) && (this->Index < static_cast<vtkm::IdComponent>(
sizeof...(Ts)));
167 this->
CastAndCall(detail::VariantDestroyFunctor{});
172 template <
typename Functor,
typename... Args>
174 noexcept(noexcept(f(std::declval<
const TypeAt<0>&>(), args...)))
175 -> decltype(f(std::declval<
const TypeAt<0>&>(), args...))
178 return detail::VariantCastAndCallImpl<
sizeof...(Ts)>(
179 this->GetIndex(), std::forward<Functor>(f), this->Storage, std::forward<Args>(args)...);
182 template <
typename Functor,
typename... Args>
184 noexcept(f(std::declval<
const TypeAt<0>&>(), args...)))
185 -> decltype(f(std::declval<TypeAt<0>&>(), args...))
188 return detail::VariantCastAndCallImpl<
sizeof...(Ts)>(
189 this->GetIndex(), std::forward<Functor>(f), this->Storage, std::forward<Args>(args)...);
196 template <
typename VariantType,
197 typename TriviallyConstructible =
198 typename VariantTriviallyConstructible<VariantType>::type,
199 typename TriviallyCopyable =
typename VariantTriviallyCopyable<VariantType>::type>
200 struct VariantConstructorImpl;
203 template <
typename... Ts>
204 struct VariantConstructorImpl<
vtkm::VTK_M_NAMESPACE::Variant<Ts...>, std::true_type, std::true_type>
205 : VariantStorageImpl<Ts...>
207 VariantConstructorImpl() =
default;
208 ~VariantConstructorImpl() =
default;
210 VariantConstructorImpl(
const VariantConstructorImpl&) =
default;
211 VariantConstructorImpl(VariantConstructorImpl&&) =
default;
212 VariantConstructorImpl& operator=(
const VariantConstructorImpl&) =
default;
213 VariantConstructorImpl& operator=(VariantConstructorImpl&&) =
default;
218 template <
typename... Ts>
219 struct VariantConstructorImpl<
vtkm::VTK_M_NAMESPACE::Variant<Ts...>,
221 std::true_type> : VariantStorageImpl<Ts...>
224 : VariantStorageImpl<Ts...>(
vtkm::internal::NullType{})
230 ~VariantConstructorImpl() =
default;
232 VariantConstructorImpl(
const VariantConstructorImpl&) =
default;
233 VariantConstructorImpl(VariantConstructorImpl&&) =
default;
234 VariantConstructorImpl& operator=(
const VariantConstructorImpl&) =
default;
235 VariantConstructorImpl& operator=(VariantConstructorImpl&&) =
default;
239 template <
typename construct_type,
typename... Ts>
240 struct VariantConstructorImpl<
vtkm::VTK_M_NAMESPACE::Variant<Ts...>,
242 std::false_type> : VariantStorageImpl<Ts...>
245 : VariantStorageImpl<Ts...>(
vtkm::internal::NullType{})
249 VTK_M_DEVICE ~VariantConstructorImpl() { this->Reset(); }
251 VTK_M_DEVICE VariantConstructorImpl(
const VariantConstructorImpl& src) noexcept
252 : VariantStorageImpl<Ts...>(vtkm::internal::NullType{})
256 src.CastAndCall(VariantCopyConstructFunctor{}, this->Storage);
258 this->Index = src.Index;
261 VTK_M_DEVICE VariantConstructorImpl& operator=(
const VariantConstructorImpl& src) noexcept
265 if (this->GetIndex() == src.GetIndex())
267 src.CastAndCall(detail::VariantCopyFunctor{}, this->Storage);
272 src.CastAndCall(detail::VariantCopyConstructFunctor{}, this->Storage);
273 this->Index = src.Index;
286 template <
typename... Ts>
287 class Variant : detail::VariantConstructorImpl<Variant<Ts...>>
297 template <
typename T>
302 template <
typename T>
310 template <vtkm::IdComponent Index>
318 template <
typename T>
323 template <
typename T>
347 return (this->Index >= 0) && (this->Index < NumberOfTypes);
352 template <
typename T>
355 return (this->GetIndex() == this->GetIndexOf<T>());
365 template <
typename T>
373 new (&this->Get<index>()) T(src);
376 template <
typename T>
379 if (this->IsType<T>())
381 this->Get<T>() = src;
385 this->Emplace<T>(src);
390 template <
typename T,
typename... Args>
395 return this->EmplaceImpl<T, I>(std::forward<Args>(args)...);
398 template <
typename T,
typename U,
typename... Args>
403 return this->EmplaceImpl<T, I>(il, std::forward<Args>(args)...);
410 "Variant::Emplace called with invalid index");
411 return this->EmplaceImpl<TypeAt<I>, I>(std::forward<Args>(args)...);
418 "Variant::Emplace called with invalid index");
419 return this->EmplaceImpl<TypeAt<I>, I>(il, std::forward<Args>(args)...);
428 return *(
new (&this->Get<I>()) T{ args... });
436 return *(
new (&this->Get<I>()) T(il, args...));
444 template <vtkm::IdComponent I>
448 return detail::VariantUnionGet<I>(this->Storage);
451 template <vtkm::IdComponent I>
455 return detail::VariantUnionGet<I>(this->Storage);
463 template <
typename T>
469 template <
typename T>
477 template <
typename T>
481 return detail::VariantUnionGet<IndexOf<T>::value>(this->Storage);
484 template <
typename T>
488 return detail::VariantUnionGet<IndexOf<T>::value>(this->Storage);
496 template <
typename T>
500 "Attempted to get a type from a variant that the variant does not contain.");
502 return *
reinterpret_cast<T*
>(0);
513 template <
typename Functor,
typename... Args>
515 noexcept(noexcept(f(std::declval<
const TypeAt<0>&>(), args...)))
518 return detail::VariantCastAndCallImpl<
sizeof...(Ts)>(
519 this->GetIndex(), std::forward<Functor>(f), this->Storage, std::forward<Args>(args)...);
522 template <
typename Functor,
typename... Args>
524 Args&&... args) noexcept(noexcept(f(std::declval<
TypeAt<0>&>(),
528 return detail::VariantCastAndCallImpl<
sizeof...(Ts)>(
529 this->GetIndex(), std::forward<Functor>(f), this->Storage, std::forward<Args>(args)...);
539 this->
CastAndCall(detail::VariantDestroyFunctor{});
547 template <
typename List>
553 #undef VTK_M_NAMESPACE