Add more safety to VecTraits
You can often get compile errors when trying to get `Vec` attributes from types that do not define `VecTraits`. This is of particular problem when you create an object like `Vec` with a component that does not define `VecTraits`. Make using these types safer by internally using `SafeVecTraits`, which will gracefully handle types that do not have `VecTraits`.
This commit is contained in:
parent
da731005b3
commit
a7679c9e99
@ -22,18 +22,20 @@ namespace internal
|
||||
{
|
||||
|
||||
template <typename T,
|
||||
typename MultipleComponents = typename vtkm::VecTraits<T>::HasMultipleComponents>
|
||||
typename MultipleComponents =
|
||||
typename vtkm::internal::SafeVecTraits<T>::HasMultipleComponents>
|
||||
struct TotalNumComponents;
|
||||
|
||||
template <typename T>
|
||||
struct TotalNumComponents<T, vtkm::VecTraitsTagMultipleComponents>
|
||||
{
|
||||
VTKM_STATIC_ASSERT_MSG(
|
||||
(std::is_same<typename vtkm::VecTraits<T>::IsSizeStatic, vtkm::VecTraitsTagSizeStatic>::value),
|
||||
(std::is_same<typename vtkm::internal::SafeVecTraits<T>::IsSizeStatic,
|
||||
vtkm::VecTraitsTagSizeStatic>::value),
|
||||
"vtkm::VecFlat can only be used with Vec types with a static number of components.");
|
||||
using ComponentType = typename vtkm::VecTraits<T>::ComponentType;
|
||||
using ComponentType = typename vtkm::internal::SafeVecTraits<T>::ComponentType;
|
||||
static constexpr vtkm::IdComponent value =
|
||||
vtkm::VecTraits<T>::NUM_COMPONENTS * TotalNumComponents<ComponentType>::value;
|
||||
vtkm::internal::SafeVecTraits<T>::NUM_COMPONENTS * TotalNumComponents<ComponentType>::value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@ -43,7 +45,7 @@ struct TotalNumComponents<T, vtkm::VecTraitsTagSingleComponent>
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using FlattenVec = vtkm::Vec<typename vtkm::VecTraits<T>::BaseComponentType,
|
||||
using FlattenVec = vtkm::Vec<typename vtkm::internal::SafeVecTraits<T>::BaseComponentType,
|
||||
vtkm::internal::TotalNumComponents<T>::value>;
|
||||
|
||||
template <typename T>
|
||||
@ -62,10 +64,10 @@ VTKM_EXEC_CONT T GetFlatVecComponentImpl(const T& component,
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
VTKM_EXEC_CONT typename vtkm::VecTraits<T>::BaseComponentType
|
||||
VTKM_EXEC_CONT typename vtkm::internal::SafeVecTraits<T>::BaseComponentType
|
||||
GetFlatVecComponentImpl(const T& vec, vtkm::IdComponent index, std::false_type vtkmNotUsed(isBase))
|
||||
{
|
||||
using Traits = vtkm::VecTraits<T>;
|
||||
using Traits = vtkm::internal::SafeVecTraits<T>;
|
||||
using ComponentType = typename Traits::ComponentType;
|
||||
using BaseComponentType = typename Traits::BaseComponentType;
|
||||
|
||||
@ -78,7 +80,7 @@ GetFlatVecComponentImpl(const T& vec, vtkm::IdComponent index, std::false_type v
|
||||
} // namespace detail
|
||||
|
||||
template <typename T>
|
||||
VTKM_EXEC_CONT typename vtkm::VecTraits<T>::BaseComponentType GetFlatVecComponent(
|
||||
VTKM_EXEC_CONT typename vtkm::internal::SafeVecTraits<T>::BaseComponentType GetFlatVecComponent(
|
||||
const T& vec,
|
||||
vtkm::IdComponent index)
|
||||
{
|
||||
@ -112,7 +114,7 @@ VTKM_EXEC_CONT void CopyVecNestedToFlatImpl(const NestedVecType& nestedVec,
|
||||
vtkm::Vec<T, N>& flatVec,
|
||||
vtkm::IdComponent flatOffset)
|
||||
{
|
||||
using Traits = vtkm::VecTraits<NestedVecType>;
|
||||
using Traits = vtkm::internal::SafeVecTraits<NestedVecType>;
|
||||
using ComponentType = typename Traits::ComponentType;
|
||||
constexpr vtkm::IdComponent subSize = TotalNumComponents<ComponentType>::value;
|
||||
|
||||
@ -174,7 +176,7 @@ VTKM_EXEC_CONT void CopyVecFlatToNestedImpl(const vtkm::Vec<T, N>& flatVec,
|
||||
vtkm::IdComponent flatOffset,
|
||||
NestedVecType& nestedVec)
|
||||
{
|
||||
using Traits = vtkm::VecTraits<NestedVecType>;
|
||||
using Traits = vtkm::internal::SafeVecTraits<NestedVecType>;
|
||||
using ComponentType = typename Traits::ComponentType;
|
||||
constexpr vtkm::IdComponent subSize = TotalNumComponents<ComponentType>::value;
|
||||
|
||||
|
@ -91,7 +91,8 @@ struct VecTraits<vtkm::VecFromPortal<PortalType>>
|
||||
using VecType = vtkm::VecFromPortal<PortalType>;
|
||||
|
||||
using ComponentType = typename VecType::ComponentType;
|
||||
using BaseComponentType = typename vtkm::VecTraits<ComponentType>::BaseComponentType;
|
||||
using BaseComponentType =
|
||||
typename vtkm::internal::SafeVecTraits<ComponentType>::BaseComponentType;
|
||||
using HasMultipleComponents = vtkm::VecTraitsTagMultipleComponents;
|
||||
using IsSizeStatic = vtkm::VecTraitsTagSizeVariable;
|
||||
|
||||
|
@ -45,16 +45,20 @@ struct VecTraitsTagSizeVariable
|
||||
namespace internal
|
||||
{
|
||||
|
||||
template <vtkm::IdComponent numComponents>
|
||||
// Forward declaration
|
||||
template <typename T>
|
||||
struct SafeVecTraits;
|
||||
|
||||
template <vtkm::IdComponent numComponents, typename ComponentType>
|
||||
struct VecTraitsMultipleComponentChooser
|
||||
{
|
||||
using Type = vtkm::VecTraitsTagMultipleComponents;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct VecTraitsMultipleComponentChooser<1>
|
||||
template <typename ComponentType>
|
||||
struct VecTraitsMultipleComponentChooser<1, ComponentType>
|
||||
{
|
||||
using Type = vtkm::VecTraitsTagSingleComponent;
|
||||
using Type = typename vtkm::internal::SafeVecTraits<ComponentType>::HasMultipleComponents;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
@ -95,7 +99,7 @@ struct VTKM_NEVER_EXPORT VecTraits
|
||||
/// is really just a scalar.
|
||||
///
|
||||
using HasMultipleComponents =
|
||||
typename internal::VecTraitsMultipleComponentChooser<NUM_COMPONENTS>::Type;
|
||||
typename internal::VecTraitsMultipleComponentChooser<NUM_COMPONENTS, ComponentType>::Type;
|
||||
|
||||
/// \brief A tag specifying whether the size of this vector is known at compile time.
|
||||
///
|
||||
@ -197,7 +201,8 @@ template <typename T, vtkm::IdComponent Size, typename NewT>
|
||||
struct VecReplaceBaseComponentTypeGCC4or5
|
||||
{
|
||||
using type =
|
||||
vtkm::Vec<typename vtkm::VecTraits<T>::template ReplaceBaseComponentType<NewT>, Size>;
|
||||
vtkm::Vec<typename vtkm::internal::SafeVecTraits<T>::template ReplaceBaseComponentType<NewT>,
|
||||
Size>;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
@ -219,7 +224,8 @@ struct VTKM_NEVER_EXPORT VecTraits<vtkm::Vec<T, Size>>
|
||||
/// Similar to ComponentType except that for nested vectors (e.g. Vec<Vec<T, M>, N>), it
|
||||
/// returns the base scalar type at the end of the composition (T in this example).
|
||||
///
|
||||
using BaseComponentType = typename vtkm::VecTraits<ComponentType>::BaseComponentType;
|
||||
using BaseComponentType =
|
||||
typename vtkm::internal::SafeVecTraits<ComponentType>::BaseComponentType;
|
||||
|
||||
/// Number of components in the vector.
|
||||
///
|
||||
@ -235,7 +241,7 @@ struct VTKM_NEVER_EXPORT VecTraits<vtkm::Vec<T, Size>>
|
||||
/// when a vector is really just a scalar.
|
||||
///
|
||||
using HasMultipleComponents =
|
||||
typename internal::VecTraitsMultipleComponentChooser<NUM_COMPONENTS>::Type;
|
||||
typename internal::VecTraitsMultipleComponentChooser<NUM_COMPONENTS, ComponentType>::Type;
|
||||
|
||||
/// A tag specifying whether the size of this vector is known at compile
|
||||
/// time. If set to \c VecTraitsTagSizeStatic, then \c NUM_COMPONENTS is set.
|
||||
@ -298,9 +304,10 @@ struct VTKM_NEVER_EXPORT VecTraits<vtkm::Vec<T, Size>>
|
||||
typename detail::VecReplaceBaseComponentTypeGCC4or5<T, Size, NewComponentType>::type;
|
||||
#else // !GCC <= 5
|
||||
template <typename NewComponentType>
|
||||
using ReplaceBaseComponentType = vtkm::Vec<
|
||||
typename vtkm::VecTraits<ComponentType>::template ReplaceBaseComponentType<NewComponentType>,
|
||||
Size>;
|
||||
using ReplaceBaseComponentType =
|
||||
vtkm::Vec<typename vtkm::internal::SafeVecTraits<
|
||||
ComponentType>::template ReplaceBaseComponentType<NewComponentType>,
|
||||
Size>;
|
||||
#endif
|
||||
///@}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user