mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-10-05 01:49:02 +00:00
Implement VecTraits class for all types
The `VecTraits` class allows templated functions, methods, and classes to treat type arguments uniformly as `Vec` types or to otherwise differentiate between scalar and vector types. This only works for types that `VecTraits` is defined for. The `VecTraits` templated class now has a default implementation that will be used for any type that does not have a `VecTraits` specialization. This removes many surprise compiler errors when using a template that, unknown to you, has `VecTraits` in its implementation. One potential issue is that if `VecTraits` gets defined for a new type, the behavior of `VecTraits` could change for that type in backward-incompatible ways. If `VecTraits` is used in a purely generic way, this should not be an issue. However, if assumptions were made about the components and length, this could cause problems. Fixes #589
This commit is contained in:
parent
ea5cb10eb1
commit
ac889b5004
19
docs/changelog/vectraits-for-all.md
Normal file
19
docs/changelog/vectraits-for-all.md
Normal file
@ -0,0 +1,19 @@
|
||||
# Implemented `VecTraits` class for all types
|
||||
|
||||
The `VecTraits` class allows templated functions, methods, and classes to
|
||||
treat type arguments uniformly as `Vec` types or to otherwise differentiate
|
||||
between scalar and vector types. This only works for types that `VecTraits`
|
||||
is defined for.
|
||||
|
||||
The `VecTraits` templated class now has a default implementation that will
|
||||
be used for any type that does not have a `VecTraits` specialization. This
|
||||
removes many surprise compiler errors when using a template that, unknown
|
||||
to you, has `VecTraits` in its implementation.
|
||||
|
||||
One potential issue is that if `VecTraits` gets defined for a new type, the
|
||||
behavior of `VecTraits` could change for that type in backward-incompatible
|
||||
ways. If `VecTraits` is used in a purely generic way, this should not be an
|
||||
issue. However, if assumptions were made about the components and length,
|
||||
this could cause problems.
|
||||
|
||||
Fixes #589.
|
@ -69,7 +69,7 @@ public:
|
||||
/// \brief A tag to determine whether the type has multiple components.
|
||||
///
|
||||
/// This tag is either TypeTraitsScalarTag or TypeTraitsVectorTag. Scalars can
|
||||
/// also be treated as vectors.
|
||||
/// also be treated as vectors with VecTraits.
|
||||
using DimensionalityTag = vtkm::TypeTraitsUnknownTag;
|
||||
|
||||
VTKM_EXEC_CONT static T ZeroInitialization() { return T(); }
|
||||
|
@ -22,20 +22,18 @@ namespace internal
|
||||
{
|
||||
|
||||
template <typename T,
|
||||
typename MultipleComponents =
|
||||
typename vtkm::internal::SafeVecTraits<T>::HasMultipleComponents>
|
||||
typename MultipleComponents = typename vtkm::VecTraits<T>::HasMultipleComponents>
|
||||
struct TotalNumComponents;
|
||||
|
||||
template <typename T>
|
||||
struct TotalNumComponents<T, vtkm::VecTraitsTagMultipleComponents>
|
||||
{
|
||||
VTKM_STATIC_ASSERT_MSG(
|
||||
(std::is_same<typename vtkm::internal::SafeVecTraits<T>::IsSizeStatic,
|
||||
vtkm::VecTraitsTagSizeStatic>::value),
|
||||
(std::is_same<typename vtkm::VecTraits<T>::IsSizeStatic, vtkm::VecTraitsTagSizeStatic>::value),
|
||||
"vtkm::VecFlat can only be used with Vec types with a static number of components.");
|
||||
using ComponentType = typename vtkm::internal::SafeVecTraits<T>::ComponentType;
|
||||
using ComponentType = typename vtkm::VecTraits<T>::ComponentType;
|
||||
static constexpr vtkm::IdComponent value =
|
||||
vtkm::internal::SafeVecTraits<T>::NUM_COMPONENTS * TotalNumComponents<ComponentType>::value;
|
||||
vtkm::VecTraits<T>::NUM_COMPONENTS * TotalNumComponents<ComponentType>::value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@ -45,7 +43,7 @@ struct TotalNumComponents<T, vtkm::VecTraitsTagSingleComponent>
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using FlattenVec = vtkm::Vec<typename vtkm::internal::SafeVecTraits<T>::BaseComponentType,
|
||||
using FlattenVec = vtkm::Vec<typename vtkm::VecTraits<T>::BaseComponentType,
|
||||
vtkm::internal::TotalNumComponents<T>::value>;
|
||||
|
||||
template <typename T>
|
||||
@ -64,10 +62,10 @@ VTKM_EXEC_CONT T GetFlatVecComponentImpl(const T& component,
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
VTKM_EXEC_CONT typename vtkm::internal::SafeVecTraits<T>::BaseComponentType
|
||||
VTKM_EXEC_CONT typename vtkm::VecTraits<T>::BaseComponentType
|
||||
GetFlatVecComponentImpl(const T& vec, vtkm::IdComponent index, std::false_type vtkmNotUsed(isBase))
|
||||
{
|
||||
using Traits = vtkm::internal::SafeVecTraits<T>;
|
||||
using Traits = vtkm::VecTraits<T>;
|
||||
using ComponentType = typename Traits::ComponentType;
|
||||
using BaseComponentType = typename Traits::BaseComponentType;
|
||||
|
||||
@ -80,7 +78,7 @@ GetFlatVecComponentImpl(const T& vec, vtkm::IdComponent index, std::false_type v
|
||||
} // namespace detail
|
||||
|
||||
template <typename T>
|
||||
VTKM_EXEC_CONT typename vtkm::internal::SafeVecTraits<T>::BaseComponentType GetFlatVecComponent(
|
||||
VTKM_EXEC_CONT typename vtkm::VecTraits<T>::BaseComponentType GetFlatVecComponent(
|
||||
const T& vec,
|
||||
vtkm::IdComponent index)
|
||||
{
|
||||
@ -114,7 +112,7 @@ VTKM_EXEC_CONT void CopyVecNestedToFlatImpl(const NestedVecType& nestedVec,
|
||||
vtkm::Vec<T, N>& flatVec,
|
||||
vtkm::IdComponent flatOffset)
|
||||
{
|
||||
using Traits = vtkm::internal::SafeVecTraits<NestedVecType>;
|
||||
using Traits = vtkm::VecTraits<NestedVecType>;
|
||||
using ComponentType = typename Traits::ComponentType;
|
||||
constexpr vtkm::IdComponent subSize = TotalNumComponents<ComponentType>::value;
|
||||
|
||||
@ -176,7 +174,7 @@ VTKM_EXEC_CONT void CopyVecFlatToNestedImpl(const vtkm::Vec<T, N>& flatVec,
|
||||
vtkm::IdComponent flatOffset,
|
||||
NestedVecType& nestedVec)
|
||||
{
|
||||
using Traits = vtkm::internal::SafeVecTraits<NestedVecType>;
|
||||
using Traits = vtkm::VecTraits<NestedVecType>;
|
||||
using ComponentType = typename Traits::ComponentType;
|
||||
constexpr vtkm::IdComponent subSize = TotalNumComponents<ComponentType>::value;
|
||||
|
||||
|
@ -117,8 +117,7 @@ struct VecTraits<vtkm::VecFromPortal<PortalType>>
|
||||
using VecType = vtkm::VecFromPortal<PortalType>;
|
||||
|
||||
using ComponentType = typename VecType::ComponentType;
|
||||
using BaseComponentType =
|
||||
typename vtkm::internal::SafeVecTraits<ComponentType>::BaseComponentType;
|
||||
using BaseComponentType = typename vtkm::VecTraits<ComponentType>::BaseComponentType;
|
||||
using HasMultipleComponents = vtkm::VecTraitsTagMultipleComponents;
|
||||
using IsSizeStatic = vtkm::VecTraitsTagSizeVariable;
|
||||
|
||||
|
296
vtkm/VecTraits.h
296
vtkm/VecTraits.h
@ -10,6 +10,8 @@
|
||||
#ifndef vtk_m_VecTraits_h
|
||||
#define vtk_m_VecTraits_h
|
||||
|
||||
#include <vtkm/Deprecated.h>
|
||||
#include <vtkm/StaticAssert.h>
|
||||
#include <vtkm/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
@ -42,64 +44,55 @@ struct VecTraitsTagSizeVariable
|
||||
{
|
||||
};
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
// Forward declaration
|
||||
template <typename T>
|
||||
struct SafeVecTraits;
|
||||
|
||||
template <vtkm::IdComponent numComponents, typename ComponentType>
|
||||
struct VecTraitsMultipleComponentChooser
|
||||
{
|
||||
using Type = vtkm::VecTraitsTagMultipleComponents;
|
||||
};
|
||||
|
||||
template <typename ComponentType>
|
||||
struct VecTraitsMultipleComponentChooser<1, ComponentType>
|
||||
{
|
||||
using Type = typename vtkm::internal::SafeVecTraits<ComponentType>::HasMultipleComponents;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
/// The VecTraits class gives several static members that define how
|
||||
/// to use a given type as a vector.
|
||||
/// \brief Traits that can be queried to treat any type as a `Vec`.
|
||||
///
|
||||
template <class VecType>
|
||||
/// The VecTraits class gives several static members that define how
|
||||
/// to use a given type as a vector. This is useful for templated
|
||||
/// functions and methods that have a parameter that could be either
|
||||
/// a standard scalar type or a `Vec` or some other `Vec`-like
|
||||
/// object. When using this class, scalar objects are treated like
|
||||
/// a `Vec` of size 1.
|
||||
///
|
||||
/// The default implementation of this template treats the type as
|
||||
/// a scalar. Types that actually behave like vectors should
|
||||
/// specialize this template to provide the proper information.
|
||||
///
|
||||
template <class T>
|
||||
struct VTKM_NEVER_EXPORT VecTraits
|
||||
{
|
||||
#ifdef VTKM_DOXYGEN_ONLY
|
||||
// The base VecTraits should not be used with qualifiers.
|
||||
VTKM_STATIC_ASSERT_MSG((std::is_same<std::remove_pointer_t<std::decay_t<T>>, T>::value),
|
||||
"The base VecTraits should not be used with qualifiers.");
|
||||
|
||||
/// \brief Type of the components in the vector.
|
||||
///
|
||||
/// If the type is really a scalar, then the component type is the same as the scalar type.
|
||||
///
|
||||
using ComponentType = typename VecType::ComponentType;
|
||||
using ComponentType = T;
|
||||
|
||||
/// \brief Base component type in the vector.
|
||||
///
|
||||
/// 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 = T;
|
||||
|
||||
/// \brief Number of components in the vector.
|
||||
///
|
||||
/// This is only defined for vectors of a static size.
|
||||
///
|
||||
static constexpr vtkm::IdComponent NUM_COMPONENTS = VecType::NUM_COMPONENTS;
|
||||
static constexpr vtkm::IdComponent NUM_COMPONENTS = 1;
|
||||
|
||||
/// Number of components in the given vector.
|
||||
///
|
||||
static vtkm::IdComponent GetNumberOfComponents(const VecType& vec);
|
||||
static constexpr vtkm::IdComponent GetNumberOfComponents(const T&) { return NUM_COMPONENTS; }
|
||||
|
||||
/// \brief A tag specifying whether this vector has multiple components (i.e. is a "real" vector).
|
||||
///
|
||||
/// This tag can be useful for creating specialized functions when a vector
|
||||
/// is really just a scalar.
|
||||
///
|
||||
using HasMultipleComponents =
|
||||
typename internal::VecTraitsMultipleComponentChooser<NUM_COMPONENTS, ComponentType>::Type;
|
||||
using HasMultipleComponents = vtkm::VecTraitsTagSingleComponent;
|
||||
|
||||
/// \brief A tag specifying whether the size of this vector is known at compile time.
|
||||
///
|
||||
@ -111,81 +104,113 @@ struct VTKM_NEVER_EXPORT VecTraits
|
||||
|
||||
/// Returns the value in a given component of the vector.
|
||||
///
|
||||
VTKM_EXEC_CONT static const ComponentType& GetComponent(
|
||||
const typename std::remove_const<VecType>::type& vector,
|
||||
vtkm::IdComponent component);
|
||||
VTKM_EXEC_CONT static ComponentType& GetComponent(
|
||||
typename std::remove_const<VecType>::type& vector,
|
||||
vtkm::IdComponent component);
|
||||
VTKM_EXEC_CONT static const ComponentType& GetComponent(const T& vector,
|
||||
vtkm::IdComponent vtkmNotUsed(component))
|
||||
{
|
||||
return vector;
|
||||
}
|
||||
VTKM_EXEC_CONT static ComponentType& GetComponent(T& vector,
|
||||
vtkm::IdComponent vtkmNotUsed(component))
|
||||
{
|
||||
return vector;
|
||||
}
|
||||
|
||||
/// Changes the value in a given component of the vector.
|
||||
///
|
||||
VTKM_EXEC_CONT static void SetComponent(VecType& vector,
|
||||
vtkm::IdComponent component,
|
||||
ComponentType value);
|
||||
VTKM_EXEC_CONT static void SetComponent(T& vector,
|
||||
vtkm::IdComponent vtkmNotUsed(component),
|
||||
ComponentType value)
|
||||
{
|
||||
vector = value;
|
||||
}
|
||||
|
||||
/// \brief Get a vector of the same type but with a different component.
|
||||
///
|
||||
/// This type resolves to another vector with a different component type. For example,
|
||||
/// @code vtkm::VecTraits<vtkm::Vec<T, N>>::ReplaceComponentType<T2> @endcode is vtkm::Vec<T2, N>.
|
||||
/// This replacement is not recursive. So @code VecTraits<Vec<Vec<T, M>, N>::ReplaceComponentType<T2> @endcode
|
||||
/// is vtkm::Vec<T2, N>.
|
||||
/// `vtkm::VecTraits<vtkm::Vec<T, N>>::ReplaceComponentType<T2>` is `vtkm::Vec<T2, N>`.
|
||||
/// This replacement is not recursive. So `VecTraits<Vec<Vec<T, M>, N>::ReplaceComponentType<T2>`
|
||||
/// is `vtkm::Vec<T2, N>`.
|
||||
///
|
||||
template <typename NewComponentType>
|
||||
using ReplaceComponentType = VecTemplate<NewComponentType, N>;
|
||||
using ReplaceComponentType = NewComponentType;
|
||||
|
||||
/// \brief Get a vector of the same type but with a different base component.
|
||||
///
|
||||
/// This type resolves to another vector with a different base component type. The replacement
|
||||
/// is recursive for nested types. For example,
|
||||
/// @code VecTraits<Vec<Vec<T, M>, N>::ReplaceBaseComponentType<T2> @endcode is Vec<Vec<T2, M>, N>.
|
||||
/// `VecTraits<Vec<Vec<T, M>, N>::ReplaceBaseComponentType<T2>` is `Vec<Vec<T2, M>, N>`.
|
||||
///
|
||||
template <typename NewComponentType>
|
||||
using ReplaceBaseComponentType = VecTemplate<
|
||||
typename VecTraits<ComponentType>::template ReplaceBaseComponentType<NewComponentType>,
|
||||
N>;
|
||||
using ReplaceBaseComponentType = NewComponentType;
|
||||
|
||||
/// Copies the components in the given vector into a given Vec object.
|
||||
///
|
||||
template <vktm::IdComponent destSize>
|
||||
VTKM_EXEC_CONT static void CopyInto(const VecType& src, vtkm::Vec<ComponentType, destSize>& dest);
|
||||
#endif // VTKM_DOXYGEN_ONLY
|
||||
template <vtkm::IdComponent destSize>
|
||||
VTKM_EXEC_CONT static void CopyInto(const T& src, vtkm::Vec<ComponentType, destSize>& dest)
|
||||
{
|
||||
dest[0] = src;
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
struct HasVecTraitsImpl
|
||||
{
|
||||
template <typename A, typename S = typename vtkm::VecTraits<A>::ComponentType>
|
||||
static std::true_type Test(A*);
|
||||
using HasVecTraits VTKM_DEPRECATED(2.1, "All types now have VecTraits defined.") = std::true_type;
|
||||
|
||||
static std::false_type Test(...);
|
||||
|
||||
using Type = decltype(Test(std::declval<T*>()));
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// \brief Determines whether the given type has VecTraits defined.
|
||||
///
|
||||
/// If the given type T has a valid VecTraits class, then HasVecTraits<T> will be set to
|
||||
/// std::true_type. Otherwise it will be set to std::false_type. For example,
|
||||
/// HasVecTraits<vtkm::Id> is the same as std::true_type whereas HasVecTraits<void *> is the same
|
||||
/// as std::false_type. This is useful to block the definition of methods using VecTraits when
|
||||
/// VecTraits are not defined.
|
||||
///
|
||||
template <typename T>
|
||||
using HasVecTraits = typename detail::HasVecTraitsImpl<T>::Type;
|
||||
|
||||
// This partial specialization allows you to define a non-const version of
|
||||
// VecTraits and have it still work for const version.
|
||||
//
|
||||
// These partial specializations allow VecTraits to work with const and reference qualifiers.
|
||||
template <typename T>
|
||||
struct VTKM_NEVER_EXPORT VecTraits<const T> : VecTraits<T>
|
||||
{
|
||||
};
|
||||
template <typename T>
|
||||
struct VTKM_NEVER_EXPORT VecTraits<T&> : VecTraits<T>
|
||||
{
|
||||
};
|
||||
template <typename T>
|
||||
struct VTKM_NEVER_EXPORT VecTraits<const T&> : VecTraits<T>
|
||||
{
|
||||
};
|
||||
|
||||
// This partial specialization allows VecTraits to work with pointers.
|
||||
template <typename T>
|
||||
struct VTKM_NEVER_EXPORT VecTraits<T*> : VecTraits<T>
|
||||
{
|
||||
VTKM_EXEC_CONT static vtkm::IdComponent GetNumberOfComponents(const T* vector)
|
||||
{
|
||||
return VecTraits<T>::GetNumberOfComponents(*vector);
|
||||
}
|
||||
VTKM_EXEC_CONT static auto GetComponent(const T* vector, vtkm::IdComponent component)
|
||||
-> decltype(VecTraits<T>::GetComponent(*vector, component))
|
||||
{
|
||||
return VecTraits<T>::GetComponent(*vector, component);
|
||||
}
|
||||
VTKM_EXEC_CONT static auto GetComponent(T* vector, vtkm::IdComponent component)
|
||||
-> decltype(VecTraits<T>::GetComponent(*vector, component))
|
||||
{
|
||||
return VecTraits<T>::GetComponent(*vector, component);
|
||||
}
|
||||
VTKM_EXEC_CONT static void SetComponent(T* vector,
|
||||
vtkm::IdComponent component,
|
||||
typename VecTraits<T>::ComponentType value)
|
||||
{
|
||||
VecTraits<T>::SetComponent(*vector, component, value);
|
||||
}
|
||||
template <typename NewComponentType>
|
||||
using ReplaceComponentType =
|
||||
typename VecTraits<T>::template ReplaceComponentType<NewComponentType>*;
|
||||
template <typename NewComponentType>
|
||||
using ReplaceBaseComponentType =
|
||||
typename VecTraits<T>::template ReplaceBaseComponentType<NewComponentType>*;
|
||||
template <vtkm::IdComponent destSize>
|
||||
VTKM_EXEC_CONT static void CopyInto(
|
||||
const T* src,
|
||||
vtkm::Vec<typename VecTraits<T>::ComponentType, destSize>& dest)
|
||||
{
|
||||
VecTraits<T>::CopyInto(*src, dest);
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct VTKM_NEVER_EXPORT VecTraits<const T*> : VecTraits<T*>
|
||||
{
|
||||
};
|
||||
|
||||
#if defined(VTKM_GCC) && (__GNUC__ <= 5)
|
||||
namespace detail
|
||||
@ -201,13 +226,29 @@ template <typename T, vtkm::IdComponent Size, typename NewT>
|
||||
struct VecReplaceBaseComponentTypeGCC4or5
|
||||
{
|
||||
using type =
|
||||
vtkm::Vec<typename vtkm::internal::SafeVecTraits<T>::template ReplaceBaseComponentType<NewT>,
|
||||
Size>;
|
||||
vtkm::Vec<typename vtkm::VecTraits<T>::template ReplaceBaseComponentType<NewT>, Size>;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
#endif // GCC Version 4.8
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
template <vtkm::IdComponent numComponents, typename ComponentType>
|
||||
struct VecTraitsMultipleComponentChooser
|
||||
{
|
||||
using Type = vtkm::VecTraitsTagMultipleComponents;
|
||||
};
|
||||
|
||||
template <typename ComponentType>
|
||||
struct VecTraitsMultipleComponentChooser<1, ComponentType>
|
||||
{
|
||||
using Type = typename vtkm::VecTraits<ComponentType>::HasMultipleComponents;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename T, vtkm::IdComponent Size>
|
||||
struct VTKM_NEVER_EXPORT VecTraits<vtkm::Vec<T, Size>>
|
||||
{
|
||||
@ -224,8 +265,7 @@ 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::internal::SafeVecTraits<ComponentType>::BaseComponentType;
|
||||
using BaseComponentType = typename vtkm::VecTraits<ComponentType>::BaseComponentType;
|
||||
|
||||
/// Number of components in the vector.
|
||||
///
|
||||
@ -304,9 +344,8 @@ 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::internal::SafeVecTraits<
|
||||
ComponentType>::template ReplaceBaseComponentType<NewComponentType>,
|
||||
using ReplaceBaseComponentType = vtkm::Vec<
|
||||
typename vtkm::VecTraits<ComponentType>::template ReplaceBaseComponentType<NewComponentType>,
|
||||
Size>;
|
||||
#endif
|
||||
///@}
|
||||
@ -509,7 +548,8 @@ namespace internal
|
||||
/// Used for overriding VecTraits for basic scalar types.
|
||||
///
|
||||
template <typename ScalarType>
|
||||
struct VTKM_NEVER_EXPORT VecTraitsBasic
|
||||
struct VTKM_DEPRECATED(2.1, "VecTraitsBasic is now the default implementation for VecTraits.")
|
||||
VTKM_NEVER_EXPORT VecTraitsBasic
|
||||
{
|
||||
using ComponentType = ScalarType;
|
||||
using BaseComponentType = ScalarType;
|
||||
@ -548,87 +588,41 @@ struct VTKM_NEVER_EXPORT VecTraitsBasic
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename T, typename = vtkm::HasVecTraits<T>>
|
||||
struct VTKM_NEVER_EXPORT SafeVecTraitsImpl;
|
||||
|
||||
template <typename T>
|
||||
struct VTKM_NEVER_EXPORT SafeVecTraitsImpl<T, std::true_type> : vtkm::VecTraits<T>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct VTKM_NEVER_EXPORT SafeVecTraitsImpl<T, std::false_type> : vtkm::internal::VecTraitsBasic<T>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// \brief A version of VecTraits that will be available for any type.
|
||||
///
|
||||
/// The `VecTraits` template is only defined for types that have a specific specialization
|
||||
/// for it. That means if you use `VecTraits` in a template, that template will likely
|
||||
/// fail to build for types that are not defined for `VecTraits`.
|
||||
///
|
||||
/// To use `VecTraits` in a class that should support all types, not just those with
|
||||
/// defined `VecTraits`, you can use this "safe" version. `SafeVecTraits` is the same as
|
||||
/// `VecTraits` if the latter is defined. If the `VecTraits` are not defined, then
|
||||
/// `SafeVecTraits` treats the type as a simple scalar value.
|
||||
///
|
||||
/// This template ensures that it will work reasonably well for all types. But be careful
|
||||
/// as if `VecTraits` is later defined, the template is likely to change.
|
||||
///
|
||||
template <typename T>
|
||||
struct VTKM_NEVER_EXPORT SafeVecTraits : detail::SafeVecTraitsImpl<T>
|
||||
struct VTKM_DEPRECATED(2.1 "VecTraits now safe to use on any type.") VTKM_NEVER_EXPORT SafeVecTraits
|
||||
: vtkm::VecTraits<T>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
/// \brief VecTraits for Pair types
|
||||
///
|
||||
/// Although a pair would seem better as a size-2 vector, we treat it as a
|
||||
/// scalar. This is because a \c Vec is assumed to have the same type for
|
||||
/// every component, and a pair in general has a different type for each
|
||||
/// component. Thus we treat a pair as a "scalar" unit.
|
||||
///
|
||||
template <typename T, typename U>
|
||||
struct VTKM_NEVER_EXPORT VecTraits<vtkm::Pair<T, U>>
|
||||
: public vtkm::internal::VecTraitsBasic<vtkm::Pair<T, U>>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
struct VTKM_DEPRECATED(2.1,
|
||||
"VTKM_BASIC_TYPE_VECTOR is no longer necessary because VecTraits implements "
|
||||
"basic type by default.") VTKM_BASIC_TYPE_VECTOR_is_deprecated
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct issue_VTKM_BASIC_TYPE_VECTOR_deprecation_warning;
|
||||
|
||||
}
|
||||
|
||||
} // namespace vtkm
|
||||
|
||||
#define VTKM_BASIC_TYPE_VECTOR(type) \
|
||||
namespace vtkm \
|
||||
{ \
|
||||
namespace detail \
|
||||
{ \
|
||||
template <> \
|
||||
struct VTKM_NEVER_EXPORT VecTraits<type> : public vtkm::internal::VecTraitsBasic<type> \
|
||||
struct issue_VTKM_BASIC_TYPE_VECTOR_deprecation_warning<type> \
|
||||
: public vtkm::detail::VTKM_BASIC_TYPE_VECTOR_is_deprecated \
|
||||
{ \
|
||||
}; \
|
||||
} \
|
||||
}
|
||||
|
||||
/// Allows you to treat basic types as if they were vectors.
|
||||
|
||||
VTKM_BASIC_TYPE_VECTOR(float)
|
||||
VTKM_BASIC_TYPE_VECTOR(double)
|
||||
|
||||
VTKM_BASIC_TYPE_VECTOR(bool)
|
||||
VTKM_BASIC_TYPE_VECTOR(char)
|
||||
VTKM_BASIC_TYPE_VECTOR(signed char)
|
||||
VTKM_BASIC_TYPE_VECTOR(unsigned char)
|
||||
VTKM_BASIC_TYPE_VECTOR(short)
|
||||
VTKM_BASIC_TYPE_VECTOR(unsigned short)
|
||||
VTKM_BASIC_TYPE_VECTOR(int)
|
||||
VTKM_BASIC_TYPE_VECTOR(unsigned int)
|
||||
VTKM_BASIC_TYPE_VECTOR(long)
|
||||
VTKM_BASIC_TYPE_VECTOR(unsigned long)
|
||||
VTKM_BASIC_TYPE_VECTOR(long long)
|
||||
VTKM_BASIC_TYPE_VECTOR(unsigned long long)
|
||||
|
||||
//#undef VTKM_BASIC_TYPE_VECTOR
|
||||
|
||||
#endif //vtk_m_VecTraits_h
|
||||
|
@ -33,21 +33,6 @@ namespace cont
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// Compile-time check to make sure that an `ArrayHandle` passed to `ArrayCopy`
|
||||
// can be passed to a `UnknownArrayHandle`. This function does nothing
|
||||
// except provide a compile error that is easier to understand than if you
|
||||
// let it go and error in `UnknownArrayHandle`. (Huh? I'm not using that.)
|
||||
template <typename T>
|
||||
inline void ArrayCopyValueTypeCheck()
|
||||
{
|
||||
VTKM_STATIC_ASSERT_MSG(vtkm::HasVecTraits<T>::value,
|
||||
"An `ArrayHandle` that has a special value type that is not supported "
|
||||
"by the precompiled version of `ArrayCopy` has been used. If this array "
|
||||
"must be deep copied, consider using `ArrayCopyDevice`. Look at the "
|
||||
"compile error for the type assigned to template parameter `T` to "
|
||||
"see the offending type.");
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
struct ArrayCopyConcreteSrc;
|
||||
|
||||
@ -74,8 +59,6 @@ void ArrayCopyImpl(const vtkm::cont::UnknownArrayHandle& source,
|
||||
std::false_type,
|
||||
std::true_type)
|
||||
{
|
||||
detail::ArrayCopyValueTypeCheck<T>();
|
||||
|
||||
using DestType = vtkm::cont::ArrayHandle<T, S>;
|
||||
if (source.CanConvert<DestType>())
|
||||
{
|
||||
@ -96,9 +79,6 @@ void ArrayCopyImpl(const vtkm::cont::ArrayHandle<TS, SS>& source,
|
||||
std::true_type,
|
||||
std::true_type)
|
||||
{
|
||||
ArrayCopyValueTypeCheck<TS>();
|
||||
ArrayCopyValueTypeCheck<TD>();
|
||||
|
||||
detail::ArrayCopyConcreteSrc<SS>{}(source, destination);
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ namespace internal
|
||||
// is defined rather than where it is resolved. This causes problems when extracting
|
||||
// components of, say, an ArrayHandleMultiplexer holding an ArrayHandleSOA.
|
||||
template <typename T, typename S>
|
||||
vtkm::cont::ArrayHandleStride<typename vtkm::internal::SafeVecTraits<T>::BaseComponentType>
|
||||
vtkm::cont::ArrayHandleStride<typename vtkm::VecTraits<T>::BaseComponentType>
|
||||
ArrayExtractComponentFallback(const vtkm::cont::ArrayHandle<T, S>& src,
|
||||
vtkm::IdComponent componentIndex,
|
||||
vtkm::CopyFlag allowCopy)
|
||||
@ -53,7 +53,7 @@ ArrayExtractComponentFallback(const vtkm::cont::ArrayHandle<T, S>& src,
|
||||
<< vtkm::cont::TypeToString<vtkm::cont::ArrayHandle<T, S>>()
|
||||
<< " requires an inefficient memory copy.");
|
||||
|
||||
using BaseComponentType = typename vtkm::internal::SafeVecTraits<T>::BaseComponentType;
|
||||
using BaseComponentType = typename vtkm::VecTraits<T>::BaseComponentType;
|
||||
vtkm::Id numValues = src.GetNumberOfValues();
|
||||
vtkm::cont::ArrayHandleBasic<BaseComponentType> dest;
|
||||
dest.Allocate(numValues);
|
||||
@ -78,8 +78,8 @@ template <typename S>
|
||||
struct ArrayExtractComponentImpl : ArrayExtractComponentImplInefficient
|
||||
{
|
||||
template <typename T>
|
||||
vtkm::cont::ArrayHandleStride<typename vtkm::internal::SafeVecTraits<T>::BaseComponentType>
|
||||
operator()(const vtkm::cont::ArrayHandle<T, S>& src,
|
||||
vtkm::cont::ArrayHandleStride<typename vtkm::VecTraits<T>::BaseComponentType> operator()(
|
||||
const vtkm::cont::ArrayHandle<T, S>& src,
|
||||
vtkm::IdComponent componentIndex,
|
||||
vtkm::CopyFlag allowCopy) const
|
||||
{
|
||||
@ -93,15 +93,13 @@ template <>
|
||||
struct ArrayExtractComponentImpl<vtkm::cont::StorageTagStride>
|
||||
{
|
||||
template <typename T>
|
||||
vtkm::cont::ArrayHandleStride<typename vtkm::internal::SafeVecTraits<T>::BaseComponentType>
|
||||
operator()(const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagStride>& src,
|
||||
vtkm::cont::ArrayHandleStride<typename vtkm::VecTraits<T>::BaseComponentType> operator()(
|
||||
const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagStride>& src,
|
||||
vtkm::IdComponent componentIndex,
|
||||
vtkm::CopyFlag allowCopy) const
|
||||
{
|
||||
return this->DoExtract(src,
|
||||
componentIndex,
|
||||
allowCopy,
|
||||
typename vtkm::internal::SafeVecTraits<T>::HasMultipleComponents{});
|
||||
return this->DoExtract(
|
||||
src, componentIndex, allowCopy, typename vtkm::VecTraits<T>::HasMultipleComponents{});
|
||||
}
|
||||
|
||||
private:
|
||||
@ -112,7 +110,7 @@ private:
|
||||
vtkm::VecTraitsTagSingleComponent) const
|
||||
{
|
||||
VTKM_ASSERT(componentIndex == 0);
|
||||
using VTraits = vtkm::internal::SafeVecTraits<T>;
|
||||
using VTraits = vtkm::VecTraits<T>;
|
||||
using TBase = typename VTraits::BaseComponentType;
|
||||
VTKM_STATIC_ASSERT(VTraits::NUM_COMPONENTS == 1);
|
||||
|
||||
@ -135,7 +133,7 @@ private:
|
||||
vtkm::CopyFlag allowCopy,
|
||||
vtkm::VecTraitsTagMultipleComponents) const
|
||||
{
|
||||
using VTraits = vtkm::internal::SafeVecTraits<VecType>;
|
||||
using VTraits = vtkm::VecTraits<VecType>;
|
||||
using T = typename VTraits::ComponentType;
|
||||
constexpr vtkm::IdComponent N = VTraits::NUM_COMPONENTS;
|
||||
|
||||
@ -254,8 +252,8 @@ using ArrayExtractComponentIsInefficient = typename std::is_base_of<
|
||||
/// `vtkm::cont::internal::ArrayExtractComponentImpl`.
|
||||
///
|
||||
template <typename T, typename S>
|
||||
vtkm::cont::ArrayHandleStride<typename vtkm::internal::SafeVecTraits<T>::BaseComponentType>
|
||||
ArrayExtractComponent(const vtkm::cont::ArrayHandle<T, S>& src,
|
||||
vtkm::cont::ArrayHandleStride<typename vtkm::VecTraits<T>::BaseComponentType> ArrayExtractComponent(
|
||||
const vtkm::cont::ArrayHandle<T, S>& src,
|
||||
vtkm::IdComponent componentIndex,
|
||||
vtkm::CopyFlag allowCopy = vtkm::CopyFlag::On)
|
||||
{
|
||||
|
@ -120,9 +120,6 @@ VTKM_CONT void ArrayGetValues(const vtkm::cont::ArrayHandle<vtkm::Id, SIds>& ids
|
||||
const vtkm::cont::ArrayHandle<T, SData>& data,
|
||||
vtkm::cont::ArrayHandle<T, SOut>& output)
|
||||
{
|
||||
VTKM_STATIC_ASSERT_MSG(
|
||||
vtkm::HasVecTraits<T>::value,
|
||||
"ArrayGetValues can only be used with arrays containing value types with VecTraits defined.");
|
||||
using DataArrayHandle = vtkm::cont::ArrayHandle<T, SData>;
|
||||
using InefficientExtract =
|
||||
vtkm::cont::internal::ArrayExtractComponentIsInefficient<DataArrayHandle>;
|
||||
|
@ -752,9 +752,9 @@ VTKM_NEVER_EXPORT VTKM_CONT inline void printSummary_ArrayHandle_Value(
|
||||
std::ostream& out,
|
||||
vtkm::VecTraitsTagMultipleComponents)
|
||||
{
|
||||
using Traits = vtkm::internal::SafeVecTraits<T>;
|
||||
using Traits = vtkm::VecTraits<T>;
|
||||
using ComponentType = typename Traits::ComponentType;
|
||||
using IsVecOfVec = typename vtkm::internal::SafeVecTraits<ComponentType>::HasMultipleComponents;
|
||||
using IsVecOfVec = typename vtkm::VecTraits<ComponentType>::HasMultipleComponents;
|
||||
vtkm::IdComponent numComponents = Traits::GetNumberOfComponents(value);
|
||||
out << "(";
|
||||
printSummary_ArrayHandle_Value(Traits::GetComponent(value, 0), out, IsVecOfVec());
|
||||
@ -774,10 +774,10 @@ VTKM_NEVER_EXPORT VTKM_CONT inline void printSummary_ArrayHandle_Value(
|
||||
{
|
||||
out << "{";
|
||||
printSummary_ArrayHandle_Value(
|
||||
value.first, out, typename vtkm::internal::SafeVecTraits<T1>::HasMultipleComponents());
|
||||
value.first, out, typename vtkm::VecTraits<T1>::HasMultipleComponents());
|
||||
out << ",";
|
||||
printSummary_ArrayHandle_Value(
|
||||
value.second, out, typename vtkm::internal::SafeVecTraits<T2>::HasMultipleComponents());
|
||||
value.second, out, typename vtkm::VecTraits<T2>::HasMultipleComponents());
|
||||
out << "}";
|
||||
}
|
||||
|
||||
@ -793,7 +793,7 @@ VTKM_NEVER_EXPORT VTKM_CONT inline void printSummary_ArrayHandle(
|
||||
{
|
||||
using ArrayType = vtkm::cont::ArrayHandle<T, StorageT>;
|
||||
using PortalType = typename ArrayType::ReadPortalType;
|
||||
using IsVec = typename vtkm::internal::SafeVecTraits<T>::HasMultipleComponents;
|
||||
using IsVec = typename vtkm::VecTraits<T>::HasMultipleComponents;
|
||||
|
||||
vtkm::Id sz = array.GetNumberOfValues();
|
||||
|
||||
|
@ -77,27 +77,17 @@ private:
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename T, typename UseVecTraits = vtkm::HasVecTraits<T>>
|
||||
struct CanCountImpl;
|
||||
|
||||
template <typename T>
|
||||
struct CanCountImpl<T, std::false_type>
|
||||
{
|
||||
using TTraits = vtkm::TypeTraits<T>;
|
||||
static constexpr bool IsNumeric =
|
||||
!std::is_same<typename TTraits::NumericTag, vtkm::TypeTraitsUnknownTag>::value;
|
||||
|
||||
static constexpr bool value = IsNumeric;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct CanCountImpl<T, std::true_type>
|
||||
struct CanCountImpl
|
||||
{
|
||||
using VTraits = vtkm::VecTraits<T>;
|
||||
using BaseType = typename VTraits::BaseComponentType;
|
||||
using TTraits = vtkm::TypeTraits<BaseType>;
|
||||
static constexpr bool IsNumeric =
|
||||
!std::is_same<typename TTraits::NumericTag, vtkm::TypeTraitsUnknownTag>::value;
|
||||
static constexpr bool IsBool = std::is_same<BaseType, bool>::value;
|
||||
|
||||
static constexpr bool value = CanCountImpl<BaseType, std::false_type>::value && !IsBool;
|
||||
static constexpr bool value = IsNumeric && !IsBool;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
@ -87,7 +87,7 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, typename = typename std::enable_if<vtkm::HasVecTraits<T>::value>::type>
|
||||
template <typename T>
|
||||
VTKM_EXEC_CONT RecombineVec& operator=(const T& src)
|
||||
{
|
||||
this->DoCopy(src);
|
||||
@ -104,7 +104,7 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T, typename = typename std::enable_if<vtkm::HasVecTraits<T>::value>::type>
|
||||
template <typename T>
|
||||
VTKM_EXEC_CONT RecombineVec& operator+=(const T& src)
|
||||
{
|
||||
using VTraits = vtkm::VecTraits<T>;
|
||||
@ -115,7 +115,7 @@ public:
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
template <typename T, typename = typename std::enable_if<vtkm::HasVecTraits<T>::value>::type>
|
||||
template <typename T>
|
||||
VTKM_EXEC_CONT RecombineVec& operator-=(const T& src)
|
||||
{
|
||||
using VTraits = vtkm::VecTraits<T>;
|
||||
@ -126,7 +126,7 @@ public:
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
template <typename T, typename = typename std::enable_if<vtkm::HasVecTraits<T>::value>::type>
|
||||
template <typename T>
|
||||
VTKM_EXEC_CONT RecombineVec& operator*=(const T& src)
|
||||
{
|
||||
using VTraits = vtkm::VecTraits<T>;
|
||||
@ -137,7 +137,7 @@ public:
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
template <typename T, typename = typename std::enable_if<vtkm::HasVecTraits<T>::value>::type>
|
||||
template <typename T>
|
||||
VTKM_EXEC_CONT RecombineVec& operator/=(const T& src)
|
||||
{
|
||||
using VTraits = vtkm::VecTraits<T>;
|
||||
@ -148,7 +148,7 @@ public:
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
template <typename T, typename = typename std::enable_if<vtkm::HasVecTraits<T>::value>::type>
|
||||
template <typename T>
|
||||
VTKM_EXEC_CONT RecombineVec& operator%=(const T& src)
|
||||
{
|
||||
using VTraits = vtkm::VecTraits<T>;
|
||||
@ -159,7 +159,7 @@ public:
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
template <typename T, typename = typename std::enable_if<vtkm::HasVecTraits<T>::value>::type>
|
||||
template <typename T>
|
||||
VTKM_EXEC_CONT RecombineVec& operator&=(const T& src)
|
||||
{
|
||||
using VTraits = vtkm::VecTraits<T>;
|
||||
@ -170,7 +170,7 @@ public:
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
template <typename T, typename = typename std::enable_if<vtkm::HasVecTraits<T>::value>::type>
|
||||
template <typename T>
|
||||
VTKM_EXEC_CONT RecombineVec& operator|=(const T& src)
|
||||
{
|
||||
using VTraits = vtkm::VecTraits<T>;
|
||||
@ -181,7 +181,7 @@ public:
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
template <typename T, typename = typename std::enable_if<vtkm::HasVecTraits<T>::value>::type>
|
||||
template <typename T>
|
||||
VTKM_EXEC_CONT RecombineVec& operator^=(const T& src)
|
||||
{
|
||||
using VTraits = vtkm::VecTraits<T>;
|
||||
@ -192,7 +192,7 @@ public:
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
template <typename T, typename = typename std::enable_if<vtkm::HasVecTraits<T>::value>::type>
|
||||
template <typename T>
|
||||
VTKM_EXEC_CONT RecombineVec& operator>>=(const T& src)
|
||||
{
|
||||
using VTraits = vtkm::VecTraits<T>;
|
||||
@ -203,7 +203,7 @@ public:
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
template <typename T, typename = typename std::enable_if<vtkm::HasVecTraits<T>::value>::type>
|
||||
template <typename T>
|
||||
VTKM_EXEC_CONT RecombineVec& operator<<=(const T& src)
|
||||
{
|
||||
using VTraits = vtkm::VecTraits<T>;
|
||||
|
@ -141,7 +141,7 @@ class Storage<vtkm::VecFromPortal<ComponentsPortal>, vtkm::cont::StorageTagRunti
|
||||
vtkm::cont::internal::Storage<ComponentType, vtkm::cont::StorageTagBasic>;
|
||||
|
||||
VTKM_STATIC_ASSERT_MSG(
|
||||
vtkm::internal::SafeVecTraits<ComponentType>::NUM_COMPONENTS == 1,
|
||||
vtkm::VecTraits<ComponentType>::NUM_COMPONENTS == 1,
|
||||
"ArrayHandleRuntimeVec only supports scalars grouped into a single Vec. Nested Vecs can "
|
||||
"still be used with ArrayHandleRuntimeVec. The values are treated as flattened (like "
|
||||
"with VecFlat).");
|
||||
|
@ -44,7 +44,6 @@ public:
|
||||
private:
|
||||
using ComponentType = typename ComponentPortalType::ValueType;
|
||||
|
||||
VTKM_STATIC_ASSERT(vtkm::HasVecTraits<ValueType>::value);
|
||||
using VTraits = vtkm::VecTraits<ValueType>;
|
||||
VTKM_STATIC_ASSERT((std::is_same<typename VTraits::ComponentType, ComponentType>::value));
|
||||
static constexpr vtkm::IdComponent NUM_COMPONENTS = VTraits::NUM_COMPONENTS;
|
||||
|
@ -82,11 +82,9 @@ inline auto UnknownAHNumberOfComponentsImpl(void* mem)
|
||||
// of a use case for the storage to report the number of components for a static data type.
|
||||
// If that happens, this implementation will need to be modified.
|
||||
template <typename T, typename S>
|
||||
inline auto UnknownAHNumberOfComponentsImpl(void*)
|
||||
-> decltype(vtkm::internal::SafeVecTraits<T>::NUM_COMPONENTS)
|
||||
inline auto UnknownAHNumberOfComponentsImpl(void*) -> decltype(vtkm::VecTraits<T>::NUM_COMPONENTS)
|
||||
{
|
||||
static constexpr vtkm::IdComponent numComponents =
|
||||
vtkm::internal::SafeVecTraits<T>::NUM_COMPONENTS;
|
||||
static constexpr vtkm::IdComponent numComponents = vtkm::VecTraits<T>::NUM_COMPONENTS;
|
||||
return numComponents;
|
||||
}
|
||||
|
||||
@ -117,7 +115,7 @@ inline auto UnknownAHNumberOfComponentsFlatImpl(void* mem)
|
||||
// static. If a future `ArrayHandle` type violates this, this code will have to become
|
||||
// more complex.
|
||||
return (vtkm::cont::internal::Storage<T, S>::GetNumberOfComponents(arrayHandle->GetBuffers()) *
|
||||
vtkm::VecFlat<typename vtkm::internal::SafeVecTraits<T>::ComponentType>::NUM_COMPONENTS);
|
||||
vtkm::VecFlat<typename vtkm::VecTraits<T>::ComponentType>::NUM_COMPONENTS);
|
||||
}
|
||||
|
||||
// Uses SFINAE to use the number of compnents in VecTraits.
|
||||
@ -364,14 +362,13 @@ std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceBasic(vtkm::VecTraitsTag
|
||||
template <typename T>
|
||||
std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceBasic()
|
||||
{
|
||||
return UnknownAHNewInstanceBasic<T>(typename vtkm::internal::SafeVecTraits<T>::IsSizeStatic{});
|
||||
return UnknownAHNewInstanceBasic<T>(typename vtkm::VecTraits<T>::IsSizeStatic{});
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceFloatBasic(vtkm::VecTraitsTagSizeStatic)
|
||||
{
|
||||
using FloatT = typename vtkm::internal::SafeVecTraits<T>::template ReplaceBaseComponentType<
|
||||
vtkm::FloatDefault>;
|
||||
using FloatT = typename vtkm::VecTraits<T>::template ReplaceBaseComponentType<vtkm::FloatDefault>;
|
||||
return UnknownAHContainer::Make(vtkm::cont::ArrayHandleBasic<FloatT>{});
|
||||
}
|
||||
template <typename T>
|
||||
@ -383,8 +380,7 @@ std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceFloatBasic(vtkm::VecTrai
|
||||
template <typename T>
|
||||
std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceFloatBasic()
|
||||
{
|
||||
return UnknownAHNewInstanceFloatBasic<T>(
|
||||
typename vtkm::internal::SafeVecTraits<T>::IsSizeStatic{});
|
||||
return UnknownAHNewInstanceFloatBasic<T>(typename vtkm::VecTraits<T>::IsSizeStatic{});
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
@ -393,7 +389,7 @@ inline UnknownAHContainer::UnknownAHContainer(const vtkm::cont::ArrayHandle<T, S
|
||||
, ValueType(typeid(T))
|
||||
, StorageType(typeid(S))
|
||||
, BaseComponentType(
|
||||
UnknownAHComponentInfo::Make<typename vtkm::internal::SafeVecTraits<T>::BaseComponentType>())
|
||||
UnknownAHComponentInfo::Make<typename vtkm::VecTraits<T>::BaseComponentType>())
|
||||
, DeleteFunction(detail::UnknownAHDelete<T, S>)
|
||||
, Buffers(detail::UnknownAHBuffers<T, S>)
|
||||
, NewInstance(detail::UnknownAHNewInstance<T, S>)
|
||||
@ -1031,8 +1027,8 @@ namespace detail
|
||||
{
|
||||
|
||||
template <typename T,
|
||||
vtkm::IdComponent = vtkm::internal::SafeVecTraits<
|
||||
typename vtkm::internal::UnrollVec<T>::ComponentType>::NUM_COMPONENTS>
|
||||
vtkm::IdComponent =
|
||||
vtkm::VecTraits<typename vtkm::internal::UnrollVec<T>::ComponentType>::NUM_COMPONENTS>
|
||||
struct UnknownArrayHandleRuntimeVecAsBasic
|
||||
{
|
||||
VTKM_CONT bool operator()(const vtkm::cont::UnknownArrayHandle*,
|
||||
|
@ -36,7 +36,6 @@ struct MapPermutationWorklet : vtkm::worklet::WorkletMapField
|
||||
InputPortalType inputPortal,
|
||||
OutputType& output) const
|
||||
{
|
||||
VTKM_STATIC_ASSERT(vtkm::HasVecTraits<OutputType>::value);
|
||||
if ((permutationIndex >= 0) && (permutationIndex < inputPortal.GetNumberOfValues()))
|
||||
{
|
||||
output = inputPortal.Get(permutationIndex);
|
||||
|
@ -76,8 +76,8 @@ struct PassThrough : vtkm::worklet::WorkletMapField
|
||||
OutValue& outValue,
|
||||
vtkm::IdComponent& outIndex) const
|
||||
{
|
||||
using VTraitsIn = vtkm::internal::SafeVecTraits<InValue>;
|
||||
using VTraitsOut = vtkm::internal::SafeVecTraits<OutValue>;
|
||||
using VTraitsIn = vtkm::VecTraits<InValue>;
|
||||
using VTraitsOut = vtkm::VecTraits<OutValue>;
|
||||
VTraitsOut::SetComponent(outValue, outIndex, VTraitsIn::GetComponent(inValue, inIndex));
|
||||
inIndex++;
|
||||
outIndex++;
|
||||
|
@ -19,39 +19,6 @@ namespace vtkm
|
||||
namespace internal
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// TODO: VecTraits should just always be supported. See #589.
|
||||
|
||||
template <typename Vec, typename = typename std::enable_if<vtkm::HasVecTraits<Vec>::value>::type>
|
||||
VTKM_EXEC_CONT inline vtkm::IdComponent SafeGetNumberOfComponents(const Vec& vec)
|
||||
{
|
||||
return vtkm::VecTraits<Vec>::GetNumberOfComponents(vec);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT inline vtkm::IdComponent SafeGetNumberOfComponents(...)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <typename Vec, typename = typename std::enable_if<vtkm::HasVecTraits<Vec>::value>::type>
|
||||
VTKM_EXEC_CONT inline typename vtkm::VecTraits<Vec>::ComponentType SafeGetComponent(
|
||||
const Vec& vec,
|
||||
vtkm::IdComponent index)
|
||||
{
|
||||
return vtkm::VecTraits<Vec>::GetComponent(vec, index);
|
||||
}
|
||||
|
||||
template <typename T, typename = typename std::enable_if<!vtkm::HasVecTraits<T>::value>::type>
|
||||
VTKM_EXEC_CONT inline T SafeGetComponent(const T& value, vtkm::IdComponent index)
|
||||
{
|
||||
VTKM_ASSERT(index == 0);
|
||||
return value;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// \brief A value class for returning setable values of an ArrayPortal
|
||||
///
|
||||
/// \c ArrayPortal classes have a pair of \c Get and \c Set methods that
|
||||
@ -350,12 +317,12 @@ struct ArrayPortalValueReference
|
||||
// cannot write components one at a time.
|
||||
VTKM_EXEC_CONT vtkm::IdComponent GetNumberOfComponents() const
|
||||
{
|
||||
return detail::SafeGetNumberOfComponents(static_cast<ValueType>(*this));
|
||||
return vtkm::VecTraits<ValueType>::GetNumberOfComponents(this->Get());
|
||||
}
|
||||
VTKM_EXEC_CONT auto operator[](vtkm::IdComponent index) const
|
||||
-> decltype(detail::SafeGetComponent(std::declval<ValueType>(), index))
|
||||
VTKM_EXEC_CONT
|
||||
typename vtkm::VecTraits<ValueType>::ComponentType operator[](vtkm::IdComponent index) const
|
||||
{
|
||||
return detail::SafeGetComponent(static_cast<ValueType>(*this), index);
|
||||
return vtkm::VecTraits<ValueType>::GetComponent(this->Get(), index);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -242,11 +242,9 @@ inline void SelectTypeAndCall(DataType dtype,
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::io::internal
|
||||
|
||||
VTKM_BASIC_TYPE_VECTOR(vtkm::io::internal::ColorChannel8)
|
||||
VTKM_BASIC_TYPE_VECTOR(vtkm::io::internal::DummyBitType)
|
||||
|
||||
#endif // vtk_m_io_internal_VTKDataSetTypes_h
|
||||
|
@ -624,12 +624,8 @@ namespace detail
|
||||
template <typename T1, typename T2>
|
||||
struct TestEqualImpl
|
||||
{
|
||||
template <typename Dimensionality1, typename Dimensionality2>
|
||||
VTKM_EXEC_CONT bool DoIt(T1 vector1,
|
||||
T2 vector2,
|
||||
vtkm::Float64 tolerance,
|
||||
Dimensionality1,
|
||||
Dimensionality2) const
|
||||
template <typename IsBase1, typename IsBase2>
|
||||
VTKM_EXEC_CONT bool DoIt(T1 vector1, T2 vector2, vtkm::Float64 tolerance, IsBase1, IsBase2) const
|
||||
{
|
||||
using Traits1 = vtkm::VecTraits<T1>;
|
||||
using Traits2 = vtkm::VecTraits<T2>;
|
||||
@ -658,8 +654,8 @@ struct TestEqualImpl
|
||||
VTKM_EXEC_CONT bool DoIt(T1 scalar1,
|
||||
T2 scalar2,
|
||||
vtkm::Float64 tolerance,
|
||||
vtkm::TypeTraitsScalarTag,
|
||||
vtkm::TypeTraitsScalarTag) const
|
||||
std::true_type,
|
||||
std::true_type) const
|
||||
{
|
||||
// Do all comparisons using 64-bit floats.
|
||||
return test_equal(
|
||||
@ -668,11 +664,13 @@ struct TestEqualImpl
|
||||
|
||||
VTKM_EXEC_CONT bool operator()(T1 value1, T2 value2, vtkm::Float64 tolerance) const
|
||||
{
|
||||
using Base1 = typename vtkm::VecTraits<T1>::BaseComponentType;
|
||||
using Base2 = typename vtkm::VecTraits<T2>::BaseComponentType;
|
||||
return this->DoIt(value1,
|
||||
value2,
|
||||
tolerance,
|
||||
typename vtkm::TypeTraits<T1>::DimensionalityTag(),
|
||||
typename vtkm::TypeTraits<T2>::DimensionalityTag());
|
||||
typename std::is_same<T1, Base1>::type{},
|
||||
typename std::is_same<T2, Base2>::type{});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -17,12 +17,18 @@ namespace
|
||||
static constexpr vtkm::Id MAX_VECTOR_SIZE = 5;
|
||||
static constexpr vtkm::Id VecInit[MAX_VECTOR_SIZE] = { 42, 54, 67, 12, 78 };
|
||||
|
||||
void ExpectTrueType(std::true_type) {}
|
||||
|
||||
void ExpectFalseType(std::false_type) {}
|
||||
|
||||
struct TypeWithoutVecTraits
|
||||
{
|
||||
vtkm::Id Value = -1;
|
||||
|
||||
TypeWithoutVecTraits() = default;
|
||||
|
||||
TypeWithoutVecTraits(vtkm::Id value)
|
||||
: Value(value)
|
||||
{
|
||||
}
|
||||
|
||||
operator vtkm::Id() const { return this->Value; }
|
||||
};
|
||||
|
||||
struct TestVecTypeFunctor
|
||||
@ -30,9 +36,6 @@ struct TestVecTypeFunctor
|
||||
template <typename T>
|
||||
void operator()(const T&) const
|
||||
{
|
||||
// Make sure that VecTraits actually exists
|
||||
ExpectTrueType(vtkm::HasVecTraits<T>());
|
||||
|
||||
using Traits = vtkm::VecTraits<T>;
|
||||
using ComponentType = typename Traits::ComponentType;
|
||||
VTKM_TEST_ASSERT(Traits::NUM_COMPONENTS <= MAX_VECTOR_SIZE,
|
||||
@ -59,8 +62,8 @@ void TestVecTraits()
|
||||
vtkm::testing::Testing::TryTypes(test);
|
||||
std::cout << "vtkm::Vec<vtkm::FloatDefault, 5>" << std::endl;
|
||||
test(vtkm::Vec<vtkm::FloatDefault, 5>());
|
||||
|
||||
ExpectFalseType(vtkm::HasVecTraits<TypeWithoutVecTraits>());
|
||||
std::cout << "TypeWithoutVecTraits" << std::endl;
|
||||
test(TypeWithoutVecTraits{});
|
||||
|
||||
vtkm::testing::TestVecComponentsTag<vtkm::Id3>();
|
||||
vtkm::testing::TestVecComponentsTag<vtkm::Vec3f>();
|
||||
@ -69,6 +72,7 @@ void TestVecTraits()
|
||||
vtkm::testing::TestVecComponentsTag<vtkm::VecCConst<vtkm::Id>>();
|
||||
vtkm::testing::TestScalarComponentsTag<vtkm::Id>();
|
||||
vtkm::testing::TestScalarComponentsTag<vtkm::FloatDefault>();
|
||||
vtkm::testing::TestScalarComponentsTag<TypeWithoutVecTraits>();
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
@ -47,6 +47,12 @@ inline void CompareDimensionalityTags(vtkm::TypeTraitsVectorTag,
|
||||
{
|
||||
// If we are here, everything is fine.
|
||||
}
|
||||
inline void CompareDimensionalityTags(vtkm::TypeTraitsUnknownTag, vtkm::VecTraitsTagSingleComponent)
|
||||
{
|
||||
// If we are here, type traits are probably not defined (and default to unknown). In this case,
|
||||
// we expect VecTraits to have the default implementation, in which case it is treated as a
|
||||
// single component.
|
||||
}
|
||||
|
||||
template <vtkm::IdComponent NUM_COMPONENTS, typename T>
|
||||
inline void CheckIsStatic(const T&, vtkm::VecTraitsTagSizeStatic)
|
||||
@ -73,6 +79,12 @@ struct VecIsWritable<vtkm::VecCConst<ComponentType>>
|
||||
using type = std::false_type;
|
||||
};
|
||||
|
||||
template <typename ComponentType>
|
||||
struct VecIsWritable<vtkm::VecCConst<ComponentType>*>
|
||||
{
|
||||
using type = std::false_type;
|
||||
};
|
||||
|
||||
// Part of TestVecTypeImpl that writes to the Vec type
|
||||
template <vtkm::IdComponent NUM_COMPONENTS, typename T, typename VecCopyType>
|
||||
static void TestVecTypeWritableImpl(const T& inVector,
|
||||
@ -150,7 +162,8 @@ static void TestVecTypeImpl(const typename std::remove_const<T>::type& inVector,
|
||||
}
|
||||
|
||||
// This will fail to compile if the tags are wrong.
|
||||
detail::CompareDimensionalityTags(typename vtkm::TypeTraits<T>::DimensionalityTag(),
|
||||
detail::CompareDimensionalityTags(
|
||||
typename vtkm::TypeTraits<std::remove_pointer_t<T>>::DimensionalityTag(),
|
||||
typename vtkm::VecTraits<T>::HasMultipleComponents());
|
||||
|
||||
TestVecTypeWritableImpl<NUM_COMPONENTS, NonConstT>(
|
||||
@ -159,7 +172,9 @@ static void TestVecTypeImpl(const typename std::remove_const<T>::type& inVector,
|
||||
// Compiler checks for base component types
|
||||
using BaseComponentType = typename vtkm::VecTraits<T>::BaseComponentType;
|
||||
VTKM_STATIC_ASSERT((std::is_same<typename vtkm::TypeTraits<BaseComponentType>::DimensionalityTag,
|
||||
vtkm::TypeTraitsScalarTag>::value));
|
||||
vtkm::TypeTraitsScalarTag>::value) ||
|
||||
(std::is_same<typename vtkm::TypeTraits<BaseComponentType>::DimensionalityTag,
|
||||
vtkm::TypeTraitsUnknownTag>::value));
|
||||
VTKM_STATIC_ASSERT((std::is_same<typename vtkm::VecTraits<ComponentType>::BaseComponentType,
|
||||
BaseComponentType>::value));
|
||||
|
||||
@ -167,12 +182,12 @@ static void TestVecTypeImpl(const typename std::remove_const<T>::type& inVector,
|
||||
using ReplaceWithVecComponent =
|
||||
typename vtkm::VecTraits<T>::template ReplaceComponentType<vtkm::Vec<char, 2>>;
|
||||
VTKM_STATIC_ASSERT(
|
||||
(std::is_same<typename vtkm::TypeTraits<T>::DimensionalityTag,
|
||||
(std::is_same<typename vtkm::TypeTraits<std::remove_pointer_t<T>>::DimensionalityTag,
|
||||
vtkm::TypeTraitsVectorTag>::value &&
|
||||
std::is_same<typename vtkm::VecTraits<ReplaceWithVecComponent>::ComponentType,
|
||||
vtkm::Vec<char, 2>>::value) ||
|
||||
(std::is_same<typename vtkm::TypeTraits<T>::DimensionalityTag,
|
||||
vtkm::TypeTraitsScalarTag>::value &&
|
||||
(!std::is_same<typename vtkm::TypeTraits<std::remove_pointer_t<T>>::DimensionalityTag,
|
||||
vtkm::TypeTraitsVectorTag>::value &&
|
||||
std::is_same<typename vtkm::VecTraits<ReplaceWithVecComponent>::ComponentType, char>::value));
|
||||
VTKM_STATIC_ASSERT(
|
||||
(std::is_same<typename vtkm::VecTraits<ReplaceWithVecComponent>::BaseComponentType,
|
||||
@ -180,12 +195,12 @@ static void TestVecTypeImpl(const typename std::remove_const<T>::type& inVector,
|
||||
using ReplaceBaseComponent =
|
||||
typename vtkm::VecTraits<ReplaceWithVecComponent>::template ReplaceBaseComponentType<short>;
|
||||
VTKM_STATIC_ASSERT(
|
||||
(std::is_same<typename vtkm::TypeTraits<T>::DimensionalityTag,
|
||||
(std::is_same<typename vtkm::TypeTraits<std::remove_pointer_t<T>>::DimensionalityTag,
|
||||
vtkm::TypeTraitsVectorTag>::value &&
|
||||
std::is_same<typename vtkm::VecTraits<ReplaceBaseComponent>::ComponentType,
|
||||
vtkm::Vec<short, 2>>::value) ||
|
||||
(std::is_same<typename vtkm::TypeTraits<T>::DimensionalityTag,
|
||||
vtkm::TypeTraitsScalarTag>::value &&
|
||||
(!std::is_same<typename vtkm::TypeTraits<std::remove_pointer_t<T>>::DimensionalityTag,
|
||||
vtkm::TypeTraitsVectorTag>::value &&
|
||||
std::is_same<typename vtkm::VecTraits<ReplaceBaseComponent>::ComponentType, short>::value));
|
||||
VTKM_STATIC_ASSERT((
|
||||
std::is_same<typename vtkm::VecTraits<ReplaceBaseComponent>::BaseComponentType, short>::value));
|
||||
@ -227,6 +242,13 @@ static void TestVecType(const T& inVector, T& outVector)
|
||||
{
|
||||
detail::TestVecTypeImpl<NUM_COMPONENTS, T>(inVector, outVector);
|
||||
detail::TestVecTypeImpl<NUM_COMPONENTS, const T>(inVector, outVector);
|
||||
// The local pointer variables are for some weirdness about `TestVecTypeImpl` taking references
|
||||
// of its argument type.
|
||||
T* inPointer = const_cast<T*>(&inVector);
|
||||
T* outPointer = &outVector;
|
||||
detail::TestVecTypeImpl<NUM_COMPONENTS, T*>(inPointer, outPointer);
|
||||
VTKM_STATIC_ASSERT_MSG((std::is_base_of<vtkm::VecTraits<T*>, vtkm::VecTraits<const T*>>::value),
|
||||
"Constant pointer should have same implementation as pointer.");
|
||||
}
|
||||
|
||||
/// Checks to make sure that the HasMultipleComponents tag is actually for a
|
||||
|
Loading…
Reference in New Issue
Block a user