mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-16 17:22:55 +00:00
Reduce the number of lines required to implement Variant::CastAndCall
This commit is contained in:
parent
991eeba9f3
commit
647bc94fed
@ -179,11 +179,8 @@ struct VariantStorageImpl
|
|||||||
-> decltype(f(std::declval<const TypeAt<0>&>(), args...))
|
-> decltype(f(std::declval<const TypeAt<0>&>(), args...))
|
||||||
{
|
{
|
||||||
VTKM_ASSERT(this->IsValid());
|
VTKM_ASSERT(this->IsValid());
|
||||||
return detail::VariantCastAndCallImpl(vtkm::ListSize<vtkm::List<Ts...>>{},
|
return detail::VariantCastAndCallImpl(
|
||||||
this->GetIndex(),
|
this->GetIndex(), std::forward<Functor>(f), this->Storage, std::forward<Args>(args)...);
|
||||||
std::forward<Functor>(f),
|
|
||||||
this->Storage,
|
|
||||||
std::forward<Args>(args)...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Functor, typename... Args>
|
template <typename Functor, typename... Args>
|
||||||
@ -192,11 +189,8 @@ struct VariantStorageImpl
|
|||||||
-> decltype(f(std::declval<TypeAt<0>&>(), args...))
|
-> decltype(f(std::declval<TypeAt<0>&>(), args...))
|
||||||
{
|
{
|
||||||
VTKM_ASSERT(this->IsValid());
|
VTKM_ASSERT(this->IsValid());
|
||||||
return detail::VariantCastAndCallImpl(vtkm::ListSize<vtkm::List<Ts...>>{},
|
return detail::VariantCastAndCallImpl(
|
||||||
this->GetIndex(),
|
this->GetIndex(), std::forward<Functor>(f), this->Storage, std::forward<Args>(args)...);
|
||||||
std::forward<Functor>(f),
|
|
||||||
this->Storage,
|
|
||||||
std::forward<Args>(args)...);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -466,11 +460,7 @@ public:
|
|||||||
{
|
{
|
||||||
VTKM_ASSERT(this->IsValid());
|
VTKM_ASSERT(this->IsValid());
|
||||||
return detail::VariantCastAndCallImpl(
|
return detail::VariantCastAndCallImpl(
|
||||||
std::integral_constant<vtkm::IdComponent, NumberOfTypes>{},
|
this->GetIndex(), std::forward<Functor>(f), this->Storage, std::forward<Args>(args)...);
|
||||||
this->GetIndex(),
|
|
||||||
std::forward<Functor>(f),
|
|
||||||
this->Storage,
|
|
||||||
std::forward<Args>(args)...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Functor, typename... Args>
|
template <typename Functor, typename... Args>
|
||||||
@ -480,11 +470,7 @@ public:
|
|||||||
{
|
{
|
||||||
VTKM_ASSERT(this->IsValid());
|
VTKM_ASSERT(this->IsValid());
|
||||||
return detail::VariantCastAndCallImpl(
|
return detail::VariantCastAndCallImpl(
|
||||||
std::integral_constant<vtkm::IdComponent, NumberOfTypes>{},
|
this->GetIndex(), std::forward<Functor>(f), this->Storage, std::forward<Args>(args)...);
|
||||||
this->GetIndex(),
|
|
||||||
std::forward<Functor>(f),
|
|
||||||
this->Storage,
|
|
||||||
std::forward<Args>(args)...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Destroys any object the Variant is holding and sets the Variant to an invalid state. This
|
/// Destroys any object the Variant is holding and sets the Variant to an invalid state. This
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -197,6 +197,7 @@ union VariantUnionTD<$type_list(max_expanded - 1)>
|
|||||||
$for(param_index in range(max_expanded))\
|
$for(param_index in range(max_expanded))\
|
||||||
T$(param_index) V$(param_index);
|
T$(param_index) V$(param_index);
|
||||||
$endfor\
|
$endfor\
|
||||||
|
vtkm::internal::NullType Remaining;
|
||||||
|
|
||||||
VTK_M_DEVICE VariantUnionTD(vtkm::internal::NullType) { }
|
VTK_M_DEVICE VariantUnionTD(vtkm::internal::NullType) { }
|
||||||
VariantUnionTD() = default;
|
VariantUnionTD() = default;
|
||||||
@ -208,6 +209,7 @@ union VariantUnionNTD<$type_list(max_expanded - 1)>
|
|||||||
$for(param_index in range(max_expanded))\
|
$for(param_index in range(max_expanded))\
|
||||||
T$(param_index) V$(param_index);
|
T$(param_index) V$(param_index);
|
||||||
$endfor\
|
$endfor\
|
||||||
|
vtkm::internal::NullType Remaining;
|
||||||
|
|
||||||
VTK_M_DEVICE VariantUnionNTD(vtkm::internal::NullType) { }
|
VTK_M_DEVICE VariantUnionNTD(vtkm::internal::NullType) { }
|
||||||
VariantUnionNTD() = default;
|
VariantUnionNTD() = default;
|
||||||
@ -217,7 +219,6 @@ $endfor\
|
|||||||
template <$typename_list(max_expanded), typename... Ts>
|
template <$typename_list(max_expanded), typename... Ts>
|
||||||
union VariantUnionTD<$type_list(max_expanded), Ts...>
|
union VariantUnionTD<$type_list(max_expanded), Ts...>
|
||||||
{
|
{
|
||||||
vtkm::internal::NullType Dummy;
|
|
||||||
$for(param_index in range(max_expanded))\
|
$for(param_index in range(max_expanded))\
|
||||||
T$(param_index) V$(param_index);
|
T$(param_index) V$(param_index);
|
||||||
$endfor\
|
$endfor\
|
||||||
@ -230,7 +231,6 @@ $endfor\
|
|||||||
template <$typename_list(max_expanded), typename... Ts>
|
template <$typename_list(max_expanded), typename... Ts>
|
||||||
union VariantUnionNTD<$type_list(max_expanded), Ts...>
|
union VariantUnionNTD<$type_list(max_expanded), Ts...>
|
||||||
{
|
{
|
||||||
vtkm::internal::NullType Dummy;
|
|
||||||
$for(param_index in range(max_expanded))\
|
$for(param_index in range(max_expanded))\
|
||||||
T$(param_index) V$(param_index);
|
T$(param_index) V$(param_index);
|
||||||
$endfor\
|
$endfor\
|
||||||
@ -304,64 +304,91 @@ VTK_M_DEVICE auto VariantUnionGet(UnionType& storage) noexcept
|
|||||||
return VariantUnionGetImpl<I, typename std::decay<UnionType>::type>::Get(storage);
|
return VariantUnionGetImpl<I, typename std::decay<UnionType>::type>::Get(storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------
|
|
||||||
// Internal implementation of CastAndCall for Variant
|
|
||||||
$for(num_params in range(max_expanded))\
|
|
||||||
template <typename Functor,
|
|
||||||
typename UnionType,
|
|
||||||
typename... Args>
|
|
||||||
VTK_M_DEVICE inline auto VariantCastAndCallImpl(
|
|
||||||
std::integral_constant<vtkm::IdComponent, $(num_params + 1)>,
|
|
||||||
vtkm::IdComponent index,
|
|
||||||
Functor&& f,
|
|
||||||
UnionType& storage,
|
|
||||||
Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
|
|
||||||
-> decltype(f(storage.V0, args...))
|
|
||||||
{
|
|
||||||
switch (index)
|
|
||||||
{
|
|
||||||
$for(param_index in range(num_params + 1))\
|
|
||||||
case $(param_index):
|
|
||||||
return f(storage.V$(param_index), std::forward<Args>(args)...);
|
|
||||||
$endfor\
|
|
||||||
default:
|
|
||||||
// If we are here, it means we failed to find the appropriate type in a variant
|
|
||||||
VTKM_ASSERT(false && "Internal error, bad Variant state.");
|
|
||||||
return VariantDummyReturn<decltype(f(storage.V0, args...))>::F();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$endfor\
|
|
||||||
//clang-format on
|
//clang-format on
|
||||||
|
|
||||||
// Recurse for cases where Variant has more than $(max_expanded) types
|
// --------------------------------------------------------------------------------
|
||||||
template <vtkm::IdComponent N,
|
// Internal implementation of CastAndCall for Variant
|
||||||
|
template <typename ReturnType,
|
||||||
typename Functor,
|
typename Functor,
|
||||||
typename UnionType,
|
typename CastMember,
|
||||||
typename... Args>
|
typename... Args>
|
||||||
VTK_M_DEVICE inline auto VariantCastAndCallImpl(
|
VTK_M_DEVICE inline ReturnType VariantCallFunctor(
|
||||||
std::integral_constant<vtkm::IdComponent, N>,
|
std::false_type,
|
||||||
|
Functor&& f,
|
||||||
|
CastMember& value,
|
||||||
|
Args&&... args) noexcept(noexcept(f(value, args...)))
|
||||||
|
{
|
||||||
|
// If you get a compile error here, it probably means that you have called Variant::CastAndCall
|
||||||
|
// with a functor that does not accept one of the types in the Variant. The functor you provide
|
||||||
|
// must be callable with all types in the Variant, not just the one that it currently holds.
|
||||||
|
return f(value, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ReturnType,
|
||||||
|
typename Functor,
|
||||||
|
typename... Args>
|
||||||
|
VTK_M_DEVICE inline ReturnType VariantCallFunctor(
|
||||||
|
std::true_type, Functor&&, vtkm::internal::NullType, Args&&...) noexcept
|
||||||
|
{
|
||||||
|
// If we are here, it means a Variant had an inappropriate index.
|
||||||
|
VTKM_ASSERT(false && "Internal error, bad Variant state.");
|
||||||
|
return VariantDummyReturn<ReturnType>::F();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Terminating condition in recursive template
|
||||||
|
template <typename ReturnType, typename Functor, typename... Args>
|
||||||
|
VTK_M_DEVICE inline ReturnType VariantCastAndCallImplR(
|
||||||
|
std::true_type,
|
||||||
|
vtkm::IdComponent vtkmNotUsed(index),
|
||||||
|
Functor&& vtkmNotUsed(f),
|
||||||
|
vtkm::internal::NullType,
|
||||||
|
Args&&... vtkmNotUsed(args)) noexcept
|
||||||
|
{
|
||||||
|
// If we are here, it means a Variant had an inappropriate index.
|
||||||
|
VTKM_ASSERT(false && "Internal error, bad Variant state.");
|
||||||
|
return VariantDummyReturn<ReturnType>::F();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ReturnType, typename Functor, typename UnionType, typename... Args>
|
||||||
|
VTK_M_DEVICE inline ReturnType VariantCastAndCallImplR(
|
||||||
|
std::false_type,
|
||||||
vtkm::IdComponent index,
|
vtkm::IdComponent index,
|
||||||
Functor&& f,
|
Functor&& f,
|
||||||
UnionType& storage,
|
UnionType& storage,
|
||||||
Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
|
Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
|
||||||
-> decltype(f(storage.V0, args...))
|
|
||||||
{
|
{
|
||||||
switch (index)
|
switch (index)
|
||||||
{
|
{
|
||||||
$for(param_index in range(max_expanded))\
|
$for(param_index in range(max_expanded))\
|
||||||
case $(param_index):
|
case $(param_index):
|
||||||
return f(storage.V$(param_index), std::forward<Args>(args)...);
|
return VariantCallFunctor<ReturnType>(
|
||||||
|
typename std::is_same<decltype(storage.V$(param_index)), vtkm::internal::NullType>::type{},
|
||||||
|
std::forward<Functor>(f),
|
||||||
|
storage.V$(param_index),
|
||||||
|
std::forward<Args>(args)...);
|
||||||
$endfor\
|
$endfor\
|
||||||
default:
|
default:
|
||||||
return VariantCastAndCallImpl(std::integral_constant<vtkm::IdComponent, N - $(max_expanded)>{},
|
return VariantCastAndCallImplR<ReturnType>(
|
||||||
index - $(max_expanded),
|
typename std::is_same<decltype(storage.Remaining), vtkm::internal::NullType>::type{},
|
||||||
std::forward<Functor>(f),
|
index - $(max_expanded),
|
||||||
storage.Remaining,
|
std::forward<Functor>(f),
|
||||||
std::forward<Args>(args)...);
|
storage.Remaining,
|
||||||
|
std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Functor, typename UnionType, typename... Args>
|
||||||
|
VTK_M_DEVICE inline auto VariantCastAndCallImpl(
|
||||||
|
vtkm::IdComponent index,
|
||||||
|
Functor&& f,
|
||||||
|
UnionType& storage,
|
||||||
|
Args&&... args) noexcept(noexcept(f(storage.V0, args...)))
|
||||||
|
-> decltype(f(storage.V0, args...))
|
||||||
|
{
|
||||||
|
return VariantCastAndCallImplR<decltype(f(storage.V0, args...))>(
|
||||||
|
std::false_type{}, index, std::forward<Functor>(f), storage, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user