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>
 
  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