Changes to Vec/VecTraits for Vec-like objects.

Some changes to the Vec class and VecTraits in anticipation of creating
Vec-like objects. The following changes are made:

* Add GetNumberOfComponents to Vec, which returns NUM_COMPONENTS.

* Likewise, all VecTraits have a GetNumberOfComponents method.

* The ToVec method in VecTraits is changed to CopyInto so that it can be
used when the length of the Vec-like is not known. CopyInto is also
added to Vec.

* VecTraits has a typedef named IsSizeStatic which is set to
VecTraitsTagSizeStatic when the number of components is known at compile
time and VecTraitsTagSizeVariable when the number of components is not
known until runtime.
This commit is contained in:
Kenneth Moreland 2015-08-07 17:58:52 -06:00
parent e182388cbe
commit 5c3646af70
5 changed files with 115 additions and 22 deletions

@ -735,6 +735,9 @@ struct Negate
//-----------------------------------------------------------------------------
// Pre declaration
template<typename T, vtkm::IdComponent Size> class Vec;
namespace detail {
/// Base implementation of all Vec classes.
@ -766,6 +769,21 @@ protected:
}
public:
VTKM_EXEC_CONT_EXPORT
vtkm::IdComponent GetNumberOfComponents() { return NUM_COMPONENTS; }
template<vtkm::IdComponent OtherSize>
VTKM_EXEC_CONT_EXPORT
void CopyInto(vtkm::Vec<ComponentType,OtherSize> &dest) const
{
for (vtkm::IdComponent index = 0;
(index < NUM_COMPONENTS) && (index < OtherSize);
index++)
{
dest[index] = (*this)[index];
}
}
VTKM_EXEC_CONT_EXPORT
DerivedClass &operator=(const DerivedClass &src)
{

@ -38,6 +38,15 @@ struct VecTraitsTagMultipleComponents { };
///
struct VecTraitsTagSingleComponent { };
/// A tag for vectors where the number of components are known at compile time.
///
struct VecTraitsTagSizeStatic { };
/// A tag for vectors where the number of components are not determined until
/// run time.
///
struct VecTraitsTagSizeVariable { };
namespace internal {
template<vtkm::IdComponent numComponents>
@ -65,10 +74,15 @@ struct VecTraits
///
typedef typename VecType::ComponentType ComponentType;
/// Number of components in the vector.
/// Number of components in the vector. This is only defined for vectors
/// of a static size.
///
static const vtkm::IdComponent NUM_COMPONENTS = VecType::NUM_COMPONENTS;
/// Number of components in the given vector.
///
static vtkm::IdComponent GetNumberOfComponents(const VecType &vec);
/// 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.
@ -76,6 +90,14 @@ struct VecTraits
typedef typename internal::VecTraitsMultipleComponentChooser<
NUM_COMPONENTS>::Type HasMultipleComponents;
/// 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.
/// If set to \c VecTraitsTagSizeVariable, then the number of components is
/// not known at compile time and must be queried with \c
/// GetNumberOfComponents.
///
typedef vtkm::VecTraitsTagSizeStatic IsSizeStatic;
/// Returns the value in a given component of the vector.
///
VTKM_EXEC_CONT_EXPORT static const ComponentType &GetComponent(
@ -91,11 +113,12 @@ struct VecTraits
vtkm::IdComponent component,
ComponentType value);
/// Converts whatever type this vector is into the standard VTK-m Vec.
/// Copies the components in this vector into a given Vec object.
///
template<vktm::IdComponent destSize>
VTKM_EXEC_CONT_EXPORT
static vtkm::Vec<ComponentType,NUM_COMPONENTS>
ToVec(const VecType &vector);
static void
ToVec(const VecType &src, vtkm::Vec<ComponentType,destSize> &dest);
};
#else // VTKM_DOXYGEN_ONLY
;
@ -121,6 +144,12 @@ struct VecTraits<vtkm::Vec<T,Size> >
///
static const vtkm::IdComponent NUM_COMPONENTS = VecType::NUM_COMPONENTS;
/// Number of components in the given vector.
///
static vtkm::IdComponent GetNumberOfComponents(const VecType &) {
return NUM_COMPONENTS;
}
/// 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.
@ -128,6 +157,14 @@ struct VecTraits<vtkm::Vec<T,Size> >
typedef typename internal::VecTraitsMultipleComponentChooser<
NUM_COMPONENTS>::Type HasMultipleComponents;
/// 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.
/// If set to \c VecTraitsTagSizeVariable, then the number of components is
/// not known at compile time and must be queried with \c
/// GetNumberOfComponents.
///
typedef vtkm::VecTraitsTagSizeStatic IsSizeStatic;
/// Returns the value in a given component of the vector.
///
VTKM_EXEC_CONT_EXPORT
@ -151,11 +188,12 @@ struct VecTraits<vtkm::Vec<T,Size> >
/// Converts whatever type this vector is into the standard VTKm Tuple.
///
template<vtkm::IdComponent destSize>
VTKM_EXEC_CONT_EXPORT
static vtkm::Vec<ComponentType,NUM_COMPONENTS>
ToVec(const VecType &vector)
static void
CopyInto(const VecType &src, vtkm::Vec<ComponentType,destSize> &dest)
{
return vector;
src.CopyInto(dest);
}
};
@ -167,6 +205,11 @@ struct VecTraitsBasic {
typedef ScalarType ComponentType;
static const vtkm::IdComponent NUM_COMPONENTS = 1;
typedef VecTraitsTagSingleComponent HasMultipleComponents;
typedef vtkm::VecTraitsTagSizeStatic IsSizeStatic;
static vtkm::IdComponent GetNumberOfComponents(const ScalarType &) {
return 1;
}
VTKM_EXEC_CONT_EXPORT static const ComponentType &GetComponent(
const ScalarType &vector,
@ -184,10 +227,12 @@ struct VecTraitsBasic {
vector = value;
}
template<vtkm::IdComponent destSize>
VTKM_EXEC_CONT_EXPORT
static vtkm::Vec<ScalarType,1> ToVec(const ScalarType &vector)
static void CopyInto(const ScalarType &src,
vtkm::Vec<ScalarType,destSize> &dest)
{
return vtkm::Vec<ScalarType,1>(vector);
dest[0] = src;
}
};
} // namespace internal

@ -130,18 +130,26 @@ template<typename ComponentType, vtkm::IdComponent Size>
void GeneralVecTypeTest(const vtkm::Vec<ComponentType,Size> &)
{
typedef vtkm::Vec<ComponentType,Size> T;
VTKM_TEST_ASSERT(T::NUM_COMPONENTS == Size,
"NUM_COMPONENTS is wrong size.");
//grab the number of elements of T
T a, b, c;
ComponentType s(5);
VTKM_TEST_ASSERT(a.GetNumberOfComponents() == Size,
"GetNumberOfComponents returns wrong size.");
for(vtkm::IdComponent i=0; i < T::NUM_COMPONENTS; ++i)
{
a[i]=ComponentType((i+1)*2);
b[i]=ComponentType(i+1);
c[i]=ComponentType((i+1)*2);
}
a.CopyInto(c);
VTKM_TEST_ASSERT(test_equal(a, c), "CopyInto does not work.");
//verify prefix and postfix increment and decrement
++c[T::NUM_COMPONENTS-1];
c[T::NUM_COMPONENTS-1]++;

@ -39,7 +39,7 @@ struct TestVecTypeFunctor
{
Traits::SetComponent(vector, index, ComponentType(VecInit[index]));
}
vtkm::testing::TestVecType(vector);
vtkm::testing::TestVecType<Traits::NUM_COMPONENTS>(vector);
}
};

@ -46,17 +46,38 @@ inline void CompareDimensionalityTags(vtkm::TypeTraitsVectorTag,
// If we are here, everything is fine.
}
template<vtkm::IdComponent NUM_COMPONENTS, typename T>
inline void CheckIsStatic(const T &, vtkm::VecTraitsTagSizeStatic)
{
VTKM_TEST_ASSERT(vtkm::VecTraits<T>::NUM_COMPONENTS == NUM_COMPONENTS,
"Traits returns unexpected number of components");
}
template<vtkm::IdComponent NUM_COMPONENTS, typename T>
inline void CheckIsStatic(const T &, vtkm::VecTraitsTagSizeVariable)
{
// If we are here, everything is fine.
}
/// Compares some manual arithmetic through type traits to arithmetic with
/// the Tuple class.
template <class T>
template <vtkm::IdComponent NUM_COMPONENTS, typename T>
static void TestVecTypeImpl(
const typename boost::remove_const<T>::type &vector)
{
typedef typename vtkm::VecTraits<T> Traits;
typedef typename Traits::ComponentType ComponentType;
static const vtkm::IdComponent NUM_COMPONENTS = Traits::NUM_COMPONENTS;
typedef typename boost::remove_const<T>::type NonConstT;
CheckIsStatic<NUM_COMPONENTS>(vector, typename Traits::IsSizeStatic());
VTKM_TEST_ASSERT(Traits::GetNumberOfComponents(vector) == NUM_COMPONENTS,
"Traits returned wrong number of components.");
vtkm::Vec<ComponentType,NUM_COMPONENTS> vectorCopy;
Traits::CopyInto(vector, vectorCopy);
VTKM_TEST_ASSERT(test_equal(vectorCopy, vector), "CopyInto does not work.");
{
NonConstT result;
const ComponentType multiplier = 4;
@ -67,8 +88,9 @@ static void TestVecTypeImpl(
ComponentType(
multiplier*Traits::GetComponent(vector, i)));
}
VTKM_TEST_ASSERT(test_equal(Traits::ToVec(result),
multiplier*Traits::ToVec(vector)),
vtkm::Vec<ComponentType,NUM_COMPONENTS> resultCopy;
Traits::CopyInto(result, resultCopy);
VTKM_TEST_ASSERT(test_equal(resultCopy, multiplier*vectorCopy),
"Got bad result for scalar multiple");
}
@ -80,8 +102,9 @@ static void TestVecTypeImpl(
Traits::GetComponent(result, i)
= ComponentType(multiplier * Traits::GetComponent(vector, i));
}
VTKM_TEST_ASSERT(test_equal(Traits::ToVec(result),
multiplier*Traits::ToVec(vector)),
vtkm::Vec<ComponentType,NUM_COMPONENTS> resultCopy;
Traits::CopyInto(result, resultCopy);
VTKM_TEST_ASSERT(test_equal(resultCopy, multiplier*vectorCopy),
"Got bad result for scalar multiple");
}
@ -94,8 +117,7 @@ static void TestVecTypeImpl(
result = ComponentType(result + (component * component));
}
VTKM_TEST_ASSERT(
test_equal(result,
vtkm::dot(Traits::ToVec(vector), Traits::ToVec(vector))),
test_equal(result, vtkm::dot(vectorCopy, vectorCopy)),
"Got bad result for dot product");
}
@ -136,11 +158,11 @@ inline void CheckScalarComponentsTag(vtkm::VecTraitsTagSingleComponent)
/// Compares some manual arithmetic through type traits to arithmetic with
/// the Tuple class.
template <class T>
template <vtkm::IdComponent NUM_COMPONENTS, typename T>
static void TestVecType(const T &vector)
{
detail::TestVecTypeImpl<T>(vector);
detail::TestVecTypeImpl<const T>(vector);
detail::TestVecTypeImpl<NUM_COMPONENTS, T>(vector);
detail::TestVecTypeImpl<NUM_COMPONENTS, const T>(vector);
}
/// Checks to make sure that the HasMultipleComponents tag is actually for a