Merge topic 'vec-c'
f53cd748 Add VecC and VecCConst structs Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !627
This commit is contained in:
commit
b76280c849
@ -134,6 +134,32 @@ struct TypeTraits<vtkm::Vec<T,Size> >
|
||||
{ return vtkm::Vec<T,Size>( (T()) ); }
|
||||
};
|
||||
|
||||
/// Traits for VecCConst types.
|
||||
///
|
||||
template<typename T>
|
||||
struct TypeTraits<vtkm::VecCConst<T> >
|
||||
{
|
||||
using NumericTag = typename vtkm::TypeTraits<T>::NumericTag;
|
||||
using DimensionalityTag = TypeTraitsVectorTag;
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
static vtkm::VecCConst<T> ZeroInitialization()
|
||||
{ return vtkm::VecCConst<T>(); }
|
||||
};
|
||||
|
||||
/// Traits for VecC types.
|
||||
///
|
||||
template<typename T>
|
||||
struct TypeTraits<vtkm::VecC<T> >
|
||||
{
|
||||
using NumericTag = typename vtkm::TypeTraits<T>::NumericTag;
|
||||
using DimensionalityTag = TypeTraitsVectorTag;
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
static vtkm::VecC<T> ZeroInitialization()
|
||||
{ return vtkm::VecC<T>(); }
|
||||
};
|
||||
|
||||
/// \brief Traits for Pair types.
|
||||
///
|
||||
template<typename T, typename U>
|
||||
|
675
vtkm/Types.h
675
vtkm/Types.h
@ -24,6 +24,7 @@
|
||||
#include <vtkm/internal/ExportMacros.h>
|
||||
|
||||
#include <vtkm/Assert.h>
|
||||
#include <vtkm/StaticAssert.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <type_traits>
|
||||
@ -343,9 +344,15 @@ struct Negate
|
||||
template <typename T, vtkm::IdComponent Size>
|
||||
class Vec;
|
||||
|
||||
template<typename T>
|
||||
class VecC;
|
||||
|
||||
template<typename T>
|
||||
class VecCConst;
|
||||
|
||||
namespace detail {
|
||||
|
||||
/// Base implementation of all Vec classes.
|
||||
/// Base implementation of all Vec and VecC classes.
|
||||
///
|
||||
// Disable conversion warnings for Add, Subtract, Multiply, Divide on GCC only.
|
||||
// GCC creates false positive warnings for signed/unsigned char* operations.
|
||||
@ -363,8 +370,284 @@ namespace detail {
|
||||
#pragma GCC diagnostic ignored "-Wconversion"
|
||||
#endif // gcc || clang
|
||||
#endif // use cuda < 8
|
||||
template <typename T, typename DerivedClass>
|
||||
class VecBaseCommon
|
||||
{
|
||||
public:
|
||||
typedef T ComponentType;
|
||||
|
||||
protected:
|
||||
VTKM_EXEC_CONT
|
||||
VecBaseCommon()
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
const DerivedClass &Derived() const
|
||||
{
|
||||
return *static_cast<const DerivedClass *>(this);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
DerivedClass &Derived()
|
||||
{
|
||||
return *static_cast<DerivedClass *>(this);
|
||||
}
|
||||
|
||||
private:
|
||||
// Only for internal use
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::IdComponent NumComponents() const
|
||||
{
|
||||
return this->Derived().GetNumberOfComponents();
|
||||
}
|
||||
|
||||
// Only for internal use
|
||||
VTKM_EXEC_CONT
|
||||
const T &Component(vtkm::IdComponent index) const
|
||||
{
|
||||
return this->Derived()[index];
|
||||
}
|
||||
|
||||
// Only for internal use
|
||||
VTKM_EXEC_CONT
|
||||
T &Component(vtkm::IdComponent index)
|
||||
{
|
||||
return this->Derived()[index];
|
||||
}
|
||||
|
||||
public:
|
||||
template <vtkm::IdComponent OtherSize>
|
||||
VTKM_EXEC_CONT void CopyInto(
|
||||
vtkm::Vec<ComponentType, OtherSize>& dest) const
|
||||
{
|
||||
for (vtkm::IdComponent index = 0;
|
||||
(index < this->NumComponents()) && (index < OtherSize);
|
||||
index++)
|
||||
{
|
||||
dest[index] = this->Component(index);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename OtherComponentType, typename OtherVecType>
|
||||
VTKM_EXEC_CONT
|
||||
DerivedClass&
|
||||
operator=(
|
||||
const vtkm::detail::VecBaseCommon<OtherComponentType,OtherVecType>& src)
|
||||
{
|
||||
const OtherVecType &srcDerived = static_cast<const OtherVecType &>(src);
|
||||
VTKM_ASSERT(this->NumComponents() == srcDerived.GetNumberOfComponents());
|
||||
for (vtkm::IdComponent i = 0; i < this->NumComponents(); ++i)
|
||||
{
|
||||
this->Component(i) = OtherComponentType(srcDerived[i]);
|
||||
}
|
||||
return this->Derived();
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
bool operator==(const DerivedClass& other) const
|
||||
{
|
||||
bool equal=true;
|
||||
for(vtkm::IdComponent i=0; i < this->NumComponents() && equal; ++i)
|
||||
{
|
||||
equal = (this->Component(i) == other[i]);
|
||||
}
|
||||
return equal;
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
bool operator<(const DerivedClass& other) const
|
||||
{
|
||||
for (vtkm::IdComponent i = 0; i < this->NumComponents(); ++i)
|
||||
{
|
||||
// ignore equals as that represents check next value
|
||||
if (this->Component(i) < other[i])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (other[i] < this->Component(i))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} // if all same we are not less
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
bool operator!=(const DerivedClass& other) const
|
||||
{
|
||||
return !(this->operator==(other));
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
ComponentType
|
||||
Dot(const VecBaseCommon<ComponentType,DerivedClass>& other) const
|
||||
{
|
||||
// Why the static_cast here and below? Because * on small integers (char,
|
||||
// short) promotes the result to a 32-bit int. After helpfully promoting
|
||||
// the width of the result, some compilers then warn you about casting it
|
||||
// back to the type you were expecting in the first place. The static_cast
|
||||
// suppresses this warning.
|
||||
ComponentType result =
|
||||
static_cast<ComponentType>(this->Component(0) * other.Component(0));
|
||||
for (vtkm::IdComponent i = 1; i < this->NumComponents(); ++i)
|
||||
{
|
||||
result = static_cast<ComponentType>(
|
||||
result + this->Component(i) * other.Component(i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#if (!(defined(VTKM_CUDA) && (__CUDACC_VER_MAJOR__ < 8)))
|
||||
#if (defined(VTKM_GCC) || defined(VTKM_CLANG))
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wconversion"
|
||||
#endif // gcc || clang
|
||||
#endif // not using cuda < 8
|
||||
|
||||
template<vtkm::IdComponent Size>
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::Vec<ComponentType,Size>
|
||||
operator+(const vtkm::Vec<ComponentType,Size> &other) const
|
||||
{
|
||||
VTKM_ASSERT(Size == this->NumComponents());
|
||||
vtkm::Vec<ComponentType,Size> result;
|
||||
for (vtkm::IdComponent i = 0; i < Size; ++i)
|
||||
{
|
||||
result[i] = this->Component(i) + other[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename OtherClass>
|
||||
VTKM_EXEC_CONT
|
||||
DerivedClass &
|
||||
operator+=(const VecBaseCommon<ComponentType, OtherClass> &other)
|
||||
{
|
||||
const OtherClass &other_derived =
|
||||
static_cast<const OtherClass &>(other);
|
||||
VTKM_ASSERT(this->NumComponents() == other_derived.GetNumberOfComponents());
|
||||
for (vtkm::IdComponent i = 0; i < this->NumComponents(); ++i)
|
||||
{
|
||||
this->Component(i) += other_derived[i];
|
||||
}
|
||||
return this->Derived();
|
||||
}
|
||||
|
||||
template<vtkm::IdComponent Size>
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::Vec<ComponentType,Size>
|
||||
operator-(const vtkm::Vec<ComponentType,Size> &other) const
|
||||
{
|
||||
VTKM_ASSERT(Size == this->NumComponents());
|
||||
vtkm::Vec<ComponentType,Size> result;
|
||||
for (vtkm::IdComponent i = 0; i < Size; ++i)
|
||||
{
|
||||
result[i] = this->Component(i) - other[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename OtherClass>
|
||||
VTKM_EXEC_CONT
|
||||
DerivedClass &
|
||||
operator-=(const VecBaseCommon<ComponentType, OtherClass> &other)
|
||||
{
|
||||
const OtherClass &other_derived =
|
||||
static_cast<const OtherClass &>(other);
|
||||
VTKM_ASSERT(this->NumComponents() == other_derived.GetNumberOfComponents());
|
||||
for (vtkm::IdComponent i = 0; i < this->NumComponents(); ++i)
|
||||
{
|
||||
this->Component(i) -= other_derived[i];
|
||||
}
|
||||
return this->Derived();
|
||||
}
|
||||
|
||||
template<vtkm::IdComponent Size>
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::Vec<ComponentType,Size>
|
||||
operator*(const vtkm::Vec<ComponentType,Size> &other) const
|
||||
{
|
||||
vtkm::Vec<ComponentType,Size> result;
|
||||
for (vtkm::IdComponent i = 0; i < Size; ++i)
|
||||
{
|
||||
result[i] = this->Component(i) * other[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename OtherClass>
|
||||
VTKM_EXEC_CONT
|
||||
DerivedClass &
|
||||
operator*=(const VecBaseCommon<ComponentType, OtherClass> &other)
|
||||
{
|
||||
const OtherClass &other_derived =
|
||||
static_cast<const OtherClass &>(other);
|
||||
VTKM_ASSERT(this->NumComponents() == other_derived.GetNumberOfComponents());
|
||||
for (vtkm::IdComponent i = 0; i < this->NumComponents(); ++i)
|
||||
{
|
||||
this->Component(i) *= other_derived[i];
|
||||
}
|
||||
return this->Derived();
|
||||
}
|
||||
|
||||
template<vtkm::IdComponent Size>
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::Vec<ComponentType,Size>
|
||||
operator/(const vtkm::Vec<ComponentType,Size> &other) const
|
||||
{
|
||||
vtkm::Vec<ComponentType,Size> result;
|
||||
for (vtkm::IdComponent i = 0; i < Size; ++i)
|
||||
{
|
||||
result[i] = this->Component(i) / other[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename OtherClass>
|
||||
VTKM_EXEC_CONT
|
||||
DerivedClass &
|
||||
operator/=(const VecBaseCommon<ComponentType, OtherClass> &other)
|
||||
{
|
||||
const OtherClass &other_derived =
|
||||
static_cast<const OtherClass &>(other);
|
||||
VTKM_ASSERT(this->NumComponents() == other_derived.GetNumberOfComponents());
|
||||
for (vtkm::IdComponent i = 0; i < this->NumComponents(); ++i)
|
||||
{
|
||||
this->Component(i) /= other_derived[i];
|
||||
}
|
||||
return this->Derived();
|
||||
}
|
||||
|
||||
#if (!(defined(VTKM_CUDA) && (__CUDACC_VER_MAJOR__ < 8)))
|
||||
#if (defined(VTKM_GCC) || defined(VTKM_CLANG))
|
||||
#pragma GCC diagnostic pop
|
||||
#endif // gcc || clang
|
||||
#endif // not using cuda < 8
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
ComponentType* GetPointer()
|
||||
{
|
||||
return &this->Component(0);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
const ComponentType* GetPointer() const
|
||||
{
|
||||
return &this->Component(0);
|
||||
}
|
||||
};
|
||||
#if (defined(VTKM_CUDA) && (__CUDACC_VER_MAJOR__ < 8))
|
||||
#if (defined(VTKM_GCC) || defined(VTKM_CLANG))
|
||||
#pragma GCC diagnostic pop
|
||||
#endif // gcc || clang
|
||||
#endif // use cuda < 8
|
||||
|
||||
/// Base implementation of all Vec classes.
|
||||
///
|
||||
template <typename T, vtkm::IdComponent Size, typename DerivedClass>
|
||||
class VecBase
|
||||
class VecBase : public vtkm::detail::VecBaseCommon<T, DerivedClass>
|
||||
{
|
||||
public:
|
||||
typedef T ComponentType;
|
||||
@ -402,27 +685,6 @@ public:
|
||||
return NUM_COMPONENTS;
|
||||
}
|
||||
|
||||
template <vtkm::IdComponent OtherSize>
|
||||
VTKM_EXEC_CONT 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
|
||||
DerivedClass& operator=(const DerivedClass& src)
|
||||
{
|
||||
for (vtkm::IdComponent i = 0; i < Size; ++i)
|
||||
{
|
||||
this->Components[i] = src[i];
|
||||
}
|
||||
return *static_cast<DerivedClass*>(this);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
const ComponentType& operator[](vtkm::IdComponent idx) const
|
||||
{
|
||||
@ -438,53 +700,6 @@ public:
|
||||
return this->Components[idx];
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
bool operator==(const DerivedClass& other) const
|
||||
{
|
||||
bool equal=true;
|
||||
for(vtkm::IdComponent i=0; i < Size && equal; ++i)
|
||||
{
|
||||
equal = (this->Components[i] == other.Components[i]);
|
||||
}
|
||||
return equal;
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
bool operator<(const DerivedClass& other) const
|
||||
{
|
||||
for (vtkm::IdComponent i = 0; i < NUM_COMPONENTS; ++i)
|
||||
{
|
||||
// ignore equals as that represents check next value
|
||||
if (this->Components[i] < other[i])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (other[i] < this->Components[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} // if all same we are not less
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
bool operator!=(const DerivedClass& other) const
|
||||
{
|
||||
return !(this->operator==(other));
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
ComponentType Dot(const DerivedClass& other) const
|
||||
{
|
||||
ComponentType result = this->Components[0] * other[0];
|
||||
for (vtkm::IdComponent i = 1; i < Size; ++i)
|
||||
{
|
||||
result += this->Components[i] * other[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#if (!(defined(VTKM_CUDA) && (__CUDACC_VER_MAJOR__ < 8)))
|
||||
#if (defined(VTKM_GCC) || defined(VTKM_CLANG))
|
||||
#pragma GCC diagnostic push
|
||||
@ -492,116 +707,99 @@ public:
|
||||
#endif // gcc || clang
|
||||
#endif // not using cuda < 8
|
||||
|
||||
template<typename OtherComponentType, typename OtherClass>
|
||||
VTKM_EXEC_CONT
|
||||
DerivedClass operator+(const DerivedClass& other) const
|
||||
DerivedClass
|
||||
operator+(const VecBaseCommon<OtherComponentType, OtherClass> &other) const
|
||||
{
|
||||
const OtherClass &other_derived =
|
||||
static_cast<const OtherClass &>(other);
|
||||
VTKM_ASSERT(NUM_COMPONENTS == other_derived.GetNumberOfComponents());
|
||||
|
||||
DerivedClass result;
|
||||
for (vtkm::IdComponent i = 0; i < Size; ++i)
|
||||
for (vtkm::IdComponent i = 0; i < NUM_COMPONENTS; ++i)
|
||||
{
|
||||
result[i] = this->Components[i] + other[i];
|
||||
result[i] =
|
||||
this->Components[i] + static_cast<ComponentType>(other_derived[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename OtherComponentType, typename OtherClass>
|
||||
VTKM_EXEC_CONT
|
||||
DerivedClass& operator+=(const DerivedClass& other)
|
||||
DerivedClass
|
||||
operator-(const VecBaseCommon<OtherComponentType, OtherClass> &other) const
|
||||
{
|
||||
for (vtkm::IdComponent i = 0; i < Size; ++i)
|
||||
{
|
||||
this->Components[i] += other[i];
|
||||
}
|
||||
return *static_cast<DerivedClass*>(this);
|
||||
}
|
||||
const OtherClass &other_derived =
|
||||
static_cast<const OtherClass &>(other);
|
||||
VTKM_ASSERT(NUM_COMPONENTS == other_derived.GetNumberOfComponents());
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
DerivedClass operator-(const DerivedClass& other) const
|
||||
{
|
||||
DerivedClass result;
|
||||
for (vtkm::IdComponent i = 0; i < Size; ++i)
|
||||
for (vtkm::IdComponent i = 0; i < NUM_COMPONENTS; ++i)
|
||||
{
|
||||
result[i] = this->Components[i] - other[i];
|
||||
result[i] =
|
||||
this->Components[i] - static_cast<ComponentType>(other_derived[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename OtherComponentType, typename OtherClass>
|
||||
VTKM_EXEC_CONT
|
||||
DerivedClass& operator-=(const DerivedClass& other)
|
||||
DerivedClass
|
||||
operator*(const VecBaseCommon<OtherComponentType, OtherClass> &other) const
|
||||
{
|
||||
for (vtkm::IdComponent i = 0; i < Size; ++i)
|
||||
{
|
||||
this->Components[i] -= other[i];
|
||||
}
|
||||
return *static_cast<DerivedClass*>(this);
|
||||
}
|
||||
const OtherClass &other_derived =
|
||||
static_cast<const OtherClass &>(other);
|
||||
VTKM_ASSERT(NUM_COMPONENTS == other_derived.GetNumberOfComponents());
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
DerivedClass operator*(const DerivedClass& other) const
|
||||
{
|
||||
DerivedClass result;
|
||||
for (vtkm::IdComponent i = 0; i < Size; ++i)
|
||||
for (vtkm::IdComponent i = 0; i < NUM_COMPONENTS; ++i)
|
||||
{
|
||||
result[i] = this->Components[i] * other[i];
|
||||
result[i] =
|
||||
this->Components[i] * static_cast<ComponentType>(other_derived[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename OtherComponentType, typename OtherClass>
|
||||
VTKM_EXEC_CONT
|
||||
DerivedClass& operator*=(const DerivedClass& other)
|
||||
DerivedClass
|
||||
operator/(const VecBaseCommon<OtherComponentType, OtherClass> &other) const
|
||||
{
|
||||
for (vtkm::IdComponent i = 0; i < Size; ++i)
|
||||
{
|
||||
this->Components[i] *= other[i];
|
||||
}
|
||||
return *static_cast<DerivedClass*>(this);
|
||||
}
|
||||
const OtherClass &other_derived =
|
||||
static_cast<const OtherClass &>(other);
|
||||
VTKM_ASSERT(NUM_COMPONENTS == other_derived.GetNumberOfComponents());
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
DerivedClass operator/(const DerivedClass& other) const
|
||||
{
|
||||
DerivedClass result;
|
||||
for (vtkm::IdComponent i = 0; i < Size; ++i)
|
||||
for (vtkm::IdComponent i = 0; i < NUM_COMPONENTS; ++i)
|
||||
{
|
||||
result[i] = this->Components[i] / other[i];
|
||||
result[i] =
|
||||
this->Components[i] / static_cast<ComponentType>(other_derived[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
DerivedClass& operator/=(const DerivedClass& other)
|
||||
{
|
||||
for (vtkm::IdComponent i = 0; i < Size; ++i)
|
||||
{
|
||||
this->Components[i] /= other[i];
|
||||
}
|
||||
return *static_cast<DerivedClass*>(this);
|
||||
}
|
||||
|
||||
#if (!(defined(VTKM_CUDA) && (__CUDACC_VER_MAJOR__ < 8)))
|
||||
#if (defined(VTKM_GCC) || defined(VTKM_CLANG))
|
||||
#pragma GCC diagnostic pop
|
||||
#endif // gcc || clang
|
||||
#endif // not using cuda < 8
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
ComponentType* GetPointer()
|
||||
{
|
||||
return this->Components;
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
const ComponentType* GetPointer() const
|
||||
{
|
||||
return this->Components;
|
||||
}
|
||||
|
||||
protected:
|
||||
ComponentType Components[NUM_COMPONENTS];
|
||||
};
|
||||
#if (defined(VTKM_CUDA) && (__CUDACC_VER_MAJOR__ < 8))
|
||||
#if (defined(VTKM_GCC) || defined(VTKM_CLANG))
|
||||
#pragma GCC diagnostic pop
|
||||
#endif // gcc || clang
|
||||
#endif // use cuda < 8
|
||||
|
||||
/// Base of all VecC and VecCConst classes.
|
||||
///
|
||||
template <typename T, typename DerivedClass>
|
||||
class VecCBase : public vtkm::detail::VecBaseCommon<T, DerivedClass>
|
||||
{
|
||||
protected:
|
||||
VTKM_EXEC_CONT
|
||||
VecCBase()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
@ -823,6 +1021,202 @@ vtkm::Vec<T,4> make_Vec(const T &x, const T &y, const T &z, const T &w)
|
||||
return vtkm::Vec<T,4>(x, y, z, w);
|
||||
}
|
||||
|
||||
/// \brief A Vec-like representation for short arrays.
|
||||
///
|
||||
/// The \c VecC class takes a short array of values and provides an interface
|
||||
/// that mimics \c Vec. This provides a mechanism to treat C arrays like a \c
|
||||
/// Vec. It is useful in situations where you want to use a \c Vec but the data
|
||||
/// must come from elsewhere or in certain situations where the size cannot be
|
||||
/// determined at compile time. In particular, \c Vec objects of different
|
||||
/// sizes can potentially all be converted to a \c VecC of the same type.
|
||||
///
|
||||
/// Note that \c VecC holds a reference to an outside array given to it. If
|
||||
/// that array gets destroyed (for example because the source goes out of
|
||||
/// scope), the behavior becomes undefined.
|
||||
///
|
||||
/// You cannot use \c VecC with a const type in its template argument. For
|
||||
/// example, you cannot declare <tt>VecC<const vtkm::Id></tt>. If you want a
|
||||
/// non-mutable \c VecC, the \c VecCConst class (e.g.
|
||||
/// <tt>VecCConst<vtkm::Id></tt>).
|
||||
///
|
||||
template<typename T>
|
||||
class VecC : public detail::VecCBase<T, VecC<T> >
|
||||
{
|
||||
using Superclass = detail::VecCBase<T, VecC<T> >;
|
||||
|
||||
VTKM_STATIC_ASSERT_MSG(
|
||||
std::is_const<T>::value == false,
|
||||
"You cannot use VecC with a const type as its template argument. "
|
||||
"Use either const VecC or VecCConst.");
|
||||
|
||||
public:
|
||||
#ifdef VTKM_DOXYGEN_ONLY
|
||||
using ComponentType = T;
|
||||
#endif
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
VecC()
|
||||
: Components(NULL), NumberOfComponents(0)
|
||||
{ }
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
VecC(T *array, vtkm::IdComponent size)
|
||||
: Components(array), NumberOfComponents(size)
|
||||
{ }
|
||||
|
||||
template<vtkm::IdComponent Size>
|
||||
VTKM_EXEC_CONT
|
||||
VecC(vtkm::Vec<T,Size> &src)
|
||||
: Components(src.GetPointer()), NumberOfComponents(Size)
|
||||
{ }
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
explicit VecC(T &src)
|
||||
: Components(&src), NumberOfComponents(1)
|
||||
{ }
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
VecC(const VecC<T> &src)
|
||||
: Components(src.Components), NumberOfComponents(src.NumberOfComponents)
|
||||
{ }
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
const T &operator[](vtkm::IdComponent index) const
|
||||
{
|
||||
VTKM_ASSERT(index >= 0);
|
||||
VTKM_ASSERT(index < this->NumberOfComponents);
|
||||
return this->Components[index];
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
T &operator[](vtkm::IdComponent index)
|
||||
{
|
||||
VTKM_ASSERT(index >= 0);
|
||||
VTKM_ASSERT(index < this->NumberOfComponents);
|
||||
return this->Components[index];
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::IdComponent GetNumberOfComponents() const
|
||||
{
|
||||
return this->NumberOfComponents;
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
VecC<T> &operator=(const VecC<T> &src)
|
||||
{
|
||||
VTKM_ASSERT(this->NumberOfComponents == src.GetNumberOfComponents());
|
||||
for (vtkm::IdComponent index = 0; index < this->NumberOfComponents; index++)
|
||||
{
|
||||
(*this)[index] = src[index];
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
T * const Components;
|
||||
vtkm::IdComponent NumberOfComponents;
|
||||
};
|
||||
|
||||
/// \brief A const version of VecC
|
||||
///
|
||||
/// \c VecCConst is a non-mutable form of \c VecC. It can be used in place of
|
||||
/// \c VecC when a constant array is available.
|
||||
///
|
||||
/// A \c VecC can be automatically converted to a \c VecCConst, but not vice
|
||||
/// versa, so function arguments should use \c VecCConst when the data do not
|
||||
/// need to be changed.
|
||||
///
|
||||
template<typename T>
|
||||
class VecCConst : public detail::VecCBase<T, VecCConst<T> >
|
||||
{
|
||||
using Superclass = detail::VecCBase<T, VecCConst<T> >;
|
||||
|
||||
VTKM_STATIC_ASSERT_MSG(
|
||||
std::is_const<T>::value == false,
|
||||
"You cannot use VecCConst with a const type as its template argument. "
|
||||
"Remove the const from the type.");
|
||||
|
||||
public:
|
||||
#ifdef VTKM_DOXYGEN_ONLY
|
||||
using ComponentType = T;
|
||||
#endif
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
VecCConst()
|
||||
: Components(NULL), NumberOfComponents(0)
|
||||
{ }
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
VecCConst(const T *array, vtkm::IdComponent size)
|
||||
: Components(array), NumberOfComponents(size)
|
||||
{ }
|
||||
|
||||
template<vtkm::IdComponent Size>
|
||||
VTKM_EXEC_CONT
|
||||
VecCConst(const vtkm::Vec<T,Size> &src)
|
||||
: Components(src.GetPointer()), NumberOfComponents(Size)
|
||||
{ }
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
explicit VecCConst(const T &src)
|
||||
: Components(&src), NumberOfComponents(1)
|
||||
{ }
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
VecCConst(const VecCConst<T> &src)
|
||||
: Components(src.Components), NumberOfComponents(src.NumberOfComponents)
|
||||
{ }
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
VecCConst(const VecC<T> &src)
|
||||
: Components(src.Components), NumberOfComponents(src.NumberOfComponents)
|
||||
{ }
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
const T &operator[](vtkm::IdComponent index) const
|
||||
{
|
||||
VTKM_ASSERT(index >= 0);
|
||||
VTKM_ASSERT(index < this->NumberOfComponents);
|
||||
return this->Components[index];
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::IdComponent GetNumberOfComponents() const
|
||||
{
|
||||
return this->NumberOfComponents;
|
||||
}
|
||||
|
||||
private:
|
||||
const T * const Components;
|
||||
vtkm::IdComponent NumberOfComponents;
|
||||
|
||||
// You are not allowed to assign to a VecCConst, so these operators are not
|
||||
// implemented and are disallowed.
|
||||
void operator=(const VecCConst<T> &);
|
||||
void operator+=(const VecCConst<T> &);
|
||||
void operator-=(const VecCConst<T> &);
|
||||
void operator*=(const VecCConst<T> &);
|
||||
void operator/=(const VecCConst<T> &);
|
||||
};
|
||||
|
||||
/// Creates a \c VecC from an input array.
|
||||
///
|
||||
template<typename T>
|
||||
vtkm::VecC<T> make_VecC(T *array, vtkm::IdComponent size)
|
||||
{
|
||||
return vtkm::VecC<T>(array, size);
|
||||
}
|
||||
|
||||
/// Creates a \c VecCConst from a constant input array.
|
||||
///
|
||||
template<typename T>
|
||||
vtkm::VecCConst<T> make_VecC(const T *array, vtkm::IdComponent size)
|
||||
{
|
||||
return vtkm::VecCConst<T>(array, size);
|
||||
}
|
||||
|
||||
// A pre-declaration of vtkm::Pair so that classes templated on them can refer
|
||||
// to it. The actual implementation is in vtkm/Pair.h.
|
||||
template<typename U, typename V>
|
||||
@ -865,6 +1259,15 @@ dot(const vtkm::Vec<T, 4>& a, const vtkm::Vec<T, 4>& b)
|
||||
return T((a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]) + (a[3] * b[3]));
|
||||
}
|
||||
|
||||
template<typename T, typename VecType>
|
||||
static inline
|
||||
VTKM_EXEC_CONT T
|
||||
dot(const vtkm::detail::VecBaseCommon<T,VecType> &a,
|
||||
const vtkm::detail::VecBaseCommon<T,VecType> &b)
|
||||
{
|
||||
return a.Dot(b);
|
||||
}
|
||||
|
||||
template <typename T, vtkm::IdComponent Size>
|
||||
VTKM_EXEC_CONT T
|
||||
ReduceSum(const vtkm::Vec<T, Size>& a)
|
||||
|
132
vtkm/VecTraits.h
132
vtkm/VecTraits.h
@ -196,6 +196,138 @@ struct VecTraits<vtkm::Vec<T,Size> >
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct VecTraits<vtkm::VecC<T> >
|
||||
{
|
||||
using VecType = vtkm::VecC<T>;
|
||||
|
||||
/// Type of the components in the vector.
|
||||
///
|
||||
using ComponentType = typename VecType::ComponentType;
|
||||
|
||||
/// Number of components in the given vector.
|
||||
///
|
||||
VTKM_EXEC_CONT
|
||||
static vtkm::IdComponent GetNumberOfComponents(const VecType &vector)
|
||||
{
|
||||
return vector.GetNumberOfComponents();
|
||||
}
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// The size of a \c VecC is not known until runtime and can always
|
||||
/// potentially have multiple components, this is always set to \c
|
||||
/// HasMultipleComponents.
|
||||
///
|
||||
using HasMultipleComponents = vtkm::VecTraitsTagMultipleComponents;
|
||||
|
||||
/// 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.
|
||||
///
|
||||
using IsSizeStatic = vtkm::VecTraitsTagSizeVariable;
|
||||
|
||||
/// Returns the value in a given component of the vector.
|
||||
///
|
||||
VTKM_EXEC_CONT
|
||||
static const ComponentType &GetComponent(const VecType &vector,
|
||||
vtkm::IdComponent component)
|
||||
{
|
||||
return vector[component];
|
||||
}
|
||||
VTKM_EXEC_CONT
|
||||
static ComponentType &GetComponent(VecType &vector, vtkm::IdComponent component) {
|
||||
return vector[component];
|
||||
}
|
||||
|
||||
/// Changes the value in a given component of the vector.
|
||||
///
|
||||
VTKM_EXEC_CONT
|
||||
static void SetComponent(VecType &vector,
|
||||
vtkm::IdComponent component,
|
||||
ComponentType value) {
|
||||
vector[component] = value;
|
||||
}
|
||||
|
||||
/// Converts whatever type this vector is into the standard VTKm Tuple.
|
||||
///
|
||||
template<vtkm::IdComponent destSize>
|
||||
VTKM_EXEC_CONT
|
||||
static void
|
||||
CopyInto(const VecType &src, vtkm::Vec<ComponentType,destSize> &dest)
|
||||
{
|
||||
src.CopyInto(dest);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct VecTraits<vtkm::VecCConst<T> >
|
||||
{
|
||||
using VecType = vtkm::VecCConst<T>;
|
||||
|
||||
/// Type of the components in the vector.
|
||||
///
|
||||
using ComponentType = typename VecType::ComponentType;
|
||||
|
||||
/// Number of components in the given vector.
|
||||
///
|
||||
VTKM_EXEC_CONT
|
||||
static vtkm::IdComponent GetNumberOfComponents(const VecType &vector)
|
||||
{
|
||||
return vector.GetNumberOfComponents();
|
||||
}
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// The size of a \c VecCConst is not known until runtime and can always
|
||||
/// potentially have multiple components, this is always set to \c
|
||||
/// HasMultipleComponents.
|
||||
///
|
||||
using HasMultipleComponents = vtkm::VecTraitsTagMultipleComponents;
|
||||
|
||||
/// 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.
|
||||
///
|
||||
using IsSizeStatic = vtkm::VecTraitsTagSizeVariable;
|
||||
|
||||
/// Returns the value in a given component of the vector.
|
||||
///
|
||||
VTKM_EXEC_CONT
|
||||
static const ComponentType &GetComponent(const VecType &vector,
|
||||
vtkm::IdComponent component)
|
||||
{
|
||||
return vector[component];
|
||||
}
|
||||
|
||||
/// Changes the value in a given component of the vector.
|
||||
///
|
||||
VTKM_EXEC_CONT
|
||||
static void SetComponent(VecType &vector,
|
||||
vtkm::IdComponent component,
|
||||
ComponentType value) {
|
||||
vector[component] = value;
|
||||
}
|
||||
|
||||
/// Converts whatever type this vector is into the standard VTKm Tuple.
|
||||
///
|
||||
template<vtkm::IdComponent destSize>
|
||||
VTKM_EXEC_CONT
|
||||
static void
|
||||
CopyInto(const VecType &src, vtkm::Vec<ComponentType,destSize> &dest)
|
||||
{
|
||||
src.CopyInto(dest);
|
||||
}
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
/// Used for overriding VecTraits for basic scalar types.
|
||||
///
|
||||
|
@ -26,6 +26,7 @@ namespace {
|
||||
|
||||
void CheckTypeSizes()
|
||||
{
|
||||
std::cout << "Checking sizes of base types." << std::endl;
|
||||
VTKM_TEST_ASSERT(sizeof(vtkm::Int8) == 1, "Int8 wrong size.");
|
||||
VTKM_TEST_ASSERT(sizeof(vtkm::UInt8) == 1, "UInt8 wrong size.");
|
||||
VTKM_TEST_ASSERT(sizeof(vtkm::Int16) == 2, "Int16 wrong size.");
|
||||
@ -105,10 +106,232 @@ void GeneralVecTypeTestNegate(const vtkm::Vec<vtkm::Float64,Size> &x)
|
||||
DoGeneralVecTypeTestNegate(x);
|
||||
}
|
||||
|
||||
//general type test
|
||||
//general type test for VecC
|
||||
template<typename ComponentType, vtkm::IdComponent Size>
|
||||
void GeneralVecCTypeTest(const vtkm::Vec<ComponentType,Size> &)
|
||||
{
|
||||
std::cout << "Checking VecC functionality" << std::endl;
|
||||
|
||||
using T = vtkm::VecC<ComponentType>;
|
||||
using VecT = vtkm::Vec<ComponentType,Size>;
|
||||
|
||||
//grab the number of elements of T
|
||||
VecT aSrc, bSrc, cSrc;
|
||||
T a(aSrc), b(bSrc), c(cSrc);
|
||||
|
||||
VTKM_TEST_ASSERT(a.GetNumberOfComponents() == Size,
|
||||
"GetNumberOfComponents returns wrong size.");
|
||||
|
||||
for(vtkm::IdComponent i=0; i < Size; ++i)
|
||||
{
|
||||
a[i]=ComponentType((i+1)*2);
|
||||
b[i]=ComponentType(i+1);
|
||||
}
|
||||
|
||||
c = a;
|
||||
VTKM_TEST_ASSERT(test_equal(a, c), "Copy does not work.");
|
||||
|
||||
//verify prefix and postfix increment and decrement
|
||||
++c[Size-1];
|
||||
c[Size-1]++;
|
||||
VTKM_TEST_ASSERT(test_equal(c[Size-1], a[Size-1]+2),
|
||||
"Bad increment on component.");
|
||||
--c[Size-1];
|
||||
c[Size-1]--;
|
||||
VTKM_TEST_ASSERT(test_equal(c[Size-1], a[Size-1]),
|
||||
"Bad decrement on component.");
|
||||
|
||||
c = a;
|
||||
c += b;
|
||||
VTKM_TEST_ASSERT(test_equal(c, aSrc+bSrc), "Bad +=");
|
||||
c -= b;
|
||||
VTKM_TEST_ASSERT(test_equal(c, a), "Bad -=");
|
||||
c *= b;
|
||||
VTKM_TEST_ASSERT(test_equal(c, aSrc*bSrc), "Bad *=");
|
||||
c /= b;
|
||||
VTKM_TEST_ASSERT(test_equal(c, a), "Bad /=");
|
||||
|
||||
//make c nearly alike a to verify == and != are correct.
|
||||
c = a;
|
||||
c[Size-1]=ComponentType(c[Size-1]-1);
|
||||
|
||||
VecT correct_plus;
|
||||
for(vtkm::IdComponent i=0; i < Size; ++i)
|
||||
{
|
||||
correct_plus[i] = ComponentType(a[i] + b[i]);
|
||||
}
|
||||
VecT plus = a + bSrc;
|
||||
VTKM_TEST_ASSERT(test_equal(plus, correct_plus),"Tuples not added correctly.");
|
||||
plus = aSrc + b;
|
||||
VTKM_TEST_ASSERT(test_equal(plus, correct_plus),"Tuples not added correctly.");
|
||||
|
||||
VecT correct_minus;
|
||||
for(vtkm::IdComponent i=0; i < Size; ++i)
|
||||
{
|
||||
correct_minus[i] = ComponentType(a[i] - b[i]);
|
||||
}
|
||||
VecT minus = a - bSrc;
|
||||
VTKM_TEST_ASSERT(test_equal(minus, correct_minus),"Tuples not subtracted correctly.");
|
||||
minus = aSrc - b;
|
||||
VTKM_TEST_ASSERT(test_equal(minus, correct_minus),"Tuples not subtracted correctly.");
|
||||
|
||||
|
||||
VecT correct_mult;
|
||||
for(vtkm::IdComponent i=0; i < Size; ++i)
|
||||
{
|
||||
correct_mult[i] = ComponentType(a[i] * b[i]);
|
||||
}
|
||||
VecT mult = a * bSrc;
|
||||
VTKM_TEST_ASSERT(test_equal(mult, correct_mult),"Tuples not multiplied correctly.");
|
||||
mult = aSrc * b;
|
||||
VTKM_TEST_ASSERT(test_equal(mult, correct_mult),"Tuples not multiplied correctly.");
|
||||
|
||||
VecT correct_div;
|
||||
for(vtkm::IdComponent i=0; i < Size; ++i)
|
||||
{
|
||||
correct_div[i] = ComponentType(a[i] / b[i]);
|
||||
}
|
||||
VecT div = a / bSrc;
|
||||
VTKM_TEST_ASSERT(test_equal(div,correct_div),"Tuples not divided correctly.");
|
||||
div = aSrc / b;
|
||||
VTKM_TEST_ASSERT(test_equal(div,correct_div),"Tuples not divided correctly.");
|
||||
|
||||
|
||||
ComponentType d = vtkm::dot(a, b);
|
||||
ComponentType correct_d = 0;
|
||||
for(vtkm::IdComponent i=0; i < Size; ++i)
|
||||
{
|
||||
correct_d = ComponentType(correct_d + a[i] * b[i]);
|
||||
}
|
||||
VTKM_TEST_ASSERT(test_equal(d, correct_d), "dot(Tuple) wrong");
|
||||
|
||||
VTKM_TEST_ASSERT(!(a < b), "operator< wrong");
|
||||
VTKM_TEST_ASSERT((b < a), "operator< wrong");
|
||||
VTKM_TEST_ASSERT(!(a < a), "operator< wrong");
|
||||
VTKM_TEST_ASSERT((a < plus), "operator< wrong");
|
||||
VTKM_TEST_ASSERT((minus < plus), "operator< wrong");
|
||||
VTKM_TEST_ASSERT((c < a), "operator< wrong");
|
||||
|
||||
VTKM_TEST_ASSERT(!(a == b), "operator== wrong");
|
||||
VTKM_TEST_ASSERT((a == a), "operator== wrong");
|
||||
|
||||
VTKM_TEST_ASSERT((a != b), "operator!= wrong");
|
||||
VTKM_TEST_ASSERT(!(a != a), "operator!= wrong");
|
||||
|
||||
//test against a tuple that shares some values
|
||||
VTKM_TEST_ASSERT( !(c == a), "operator == wrong");
|
||||
VTKM_TEST_ASSERT( !(a == c), "operator == wrong");
|
||||
|
||||
VTKM_TEST_ASSERT( (c != a), "operator != wrong");
|
||||
VTKM_TEST_ASSERT( (a != c), "operator != wrong");
|
||||
}
|
||||
|
||||
//general type test for VecC
|
||||
template<typename ComponentType, vtkm::IdComponent Size>
|
||||
void GeneralVecCConstTypeTest(const vtkm::Vec<ComponentType,Size> &)
|
||||
{
|
||||
std::cout << "Checking VecCConst functionality" << std::endl;
|
||||
|
||||
using T = vtkm::VecCConst<ComponentType>;
|
||||
using VecT = vtkm::Vec<ComponentType,Size>;
|
||||
|
||||
//grab the number of elements of T
|
||||
VecT aSrc, bSrc, cSrc;
|
||||
for(vtkm::IdComponent i=0; i < Size; ++i)
|
||||
{
|
||||
aSrc[i]=ComponentType((i+1)*2);
|
||||
bSrc[i]=ComponentType(i+1);
|
||||
}
|
||||
cSrc = aSrc;
|
||||
|
||||
T a(aSrc), b(bSrc), c(cSrc);
|
||||
|
||||
VTKM_TEST_ASSERT(a.GetNumberOfComponents() == Size,
|
||||
"GetNumberOfComponents returns wrong size.");
|
||||
|
||||
VTKM_TEST_ASSERT(test_equal(a, c), "Comparison not working.");
|
||||
|
||||
//make c nearly alike a to verify == and != are correct.
|
||||
cSrc = aSrc;
|
||||
cSrc[Size-1]=ComponentType(cSrc[Size-1]-1);
|
||||
|
||||
VecT correct_plus;
|
||||
for(vtkm::IdComponent i=0; i < Size; ++i)
|
||||
{
|
||||
correct_plus[i] = ComponentType(a[i] + b[i]);
|
||||
}
|
||||
VecT plus = a + bSrc;
|
||||
VTKM_TEST_ASSERT(test_equal(plus, correct_plus),"Tuples not added correctly.");
|
||||
plus = aSrc + b;
|
||||
VTKM_TEST_ASSERT(test_equal(plus, correct_plus),"Tuples not added correctly.");
|
||||
|
||||
VecT correct_minus;
|
||||
for(vtkm::IdComponent i=0; i < Size; ++i)
|
||||
{
|
||||
correct_minus[i] = ComponentType(a[i] - b[i]);
|
||||
}
|
||||
VecT minus = a - bSrc;
|
||||
VTKM_TEST_ASSERT(test_equal(minus, correct_minus),"Tuples not subtracted correctly.");
|
||||
minus = aSrc - b;
|
||||
VTKM_TEST_ASSERT(test_equal(minus, correct_minus),"Tuples not subtracted correctly.");
|
||||
|
||||
|
||||
VecT correct_mult;
|
||||
for(vtkm::IdComponent i=0; i < Size; ++i)
|
||||
{
|
||||
correct_mult[i] = ComponentType(a[i] * b[i]);
|
||||
}
|
||||
VecT mult = a * bSrc;
|
||||
VTKM_TEST_ASSERT(test_equal(mult, correct_mult),"Tuples not multiplied correctly.");
|
||||
mult = aSrc * b;
|
||||
VTKM_TEST_ASSERT(test_equal(mult, correct_mult),"Tuples not multiplied correctly.");
|
||||
|
||||
VecT correct_div;
|
||||
for(vtkm::IdComponent i=0; i < Size; ++i)
|
||||
{
|
||||
correct_div[i] = ComponentType(a[i] / b[i]);
|
||||
}
|
||||
VecT div = a / bSrc;
|
||||
VTKM_TEST_ASSERT(test_equal(div,correct_div),"Tuples not divided correctly.");
|
||||
div = aSrc / b;
|
||||
VTKM_TEST_ASSERT(test_equal(div,correct_div),"Tuples not divided correctly.");
|
||||
|
||||
|
||||
ComponentType d = vtkm::dot(a, b);
|
||||
ComponentType correct_d = 0;
|
||||
for(vtkm::IdComponent i=0; i < Size; ++i)
|
||||
{
|
||||
correct_d = ComponentType(correct_d + a[i] * b[i]);
|
||||
}
|
||||
VTKM_TEST_ASSERT(test_equal(d, correct_d), "dot(Tuple) wrong");
|
||||
|
||||
VTKM_TEST_ASSERT(!(a < b), "operator< wrong");
|
||||
VTKM_TEST_ASSERT((b < a), "operator< wrong");
|
||||
VTKM_TEST_ASSERT(!(a < a), "operator< wrong");
|
||||
VTKM_TEST_ASSERT((a < plus), "operator< wrong");
|
||||
VTKM_TEST_ASSERT((minus < plus), "operator< wrong");
|
||||
VTKM_TEST_ASSERT((c < a), "operator< wrong");
|
||||
|
||||
VTKM_TEST_ASSERT(!(a == b), "operator== wrong");
|
||||
VTKM_TEST_ASSERT((a == a), "operator== wrong");
|
||||
|
||||
VTKM_TEST_ASSERT((a != b), "operator!= wrong");
|
||||
VTKM_TEST_ASSERT(!(a != a), "operator!= wrong");
|
||||
|
||||
//test against a tuple that shares some values
|
||||
VTKM_TEST_ASSERT( !(c == a), "operator == wrong");
|
||||
VTKM_TEST_ASSERT( !(a == c), "operator == wrong");
|
||||
|
||||
VTKM_TEST_ASSERT( (c != a), "operator != wrong");
|
||||
VTKM_TEST_ASSERT( (a != c), "operator != wrong");
|
||||
}
|
||||
|
||||
//general type test for Vec
|
||||
template<typename ComponentType, vtkm::IdComponent Size>
|
||||
void GeneralVecTypeTest(const vtkm::Vec<ComponentType,Size> &)
|
||||
{
|
||||
std::cout << "Checking general Vec functionality." << std::endl;
|
||||
|
||||
typedef vtkm::Vec<ComponentType,Size> T;
|
||||
|
||||
VTKM_TEST_ASSERT(T::NUM_COMPONENTS == Size,
|
||||
@ -133,8 +356,12 @@ void GeneralVecTypeTest(const vtkm::Vec<ComponentType,Size> &)
|
||||
//verify prefix and postfix increment and decrement
|
||||
++c[T::NUM_COMPONENTS-1];
|
||||
c[T::NUM_COMPONENTS-1]++;
|
||||
VTKM_TEST_ASSERT(test_equal(c[T::NUM_COMPONENTS-1], a[T::NUM_COMPONENTS-1]+2),
|
||||
"Bad increment on component.");
|
||||
--c[T::NUM_COMPONENTS-1];
|
||||
c[T::NUM_COMPONENTS-1]--;
|
||||
VTKM_TEST_ASSERT(test_equal(c[T::NUM_COMPONENTS-1], a[T::NUM_COMPONENTS-1]),
|
||||
"Bad decrement on component.");
|
||||
|
||||
//make c nearly like a to verify == and != are correct.
|
||||
c[T::NUM_COMPONENTS-1]=ComponentType(c[T::NUM_COMPONENTS-1]-1);
|
||||
@ -218,6 +445,8 @@ void GeneralVecTypeTest(const vtkm::Vec<ComponentType,Size> &)
|
||||
VTKM_TEST_ASSERT( (a != c), "operator != wrong");
|
||||
|
||||
GeneralVecTypeTestNegate(T());
|
||||
GeneralVecCTypeTest(T());
|
||||
GeneralVecCConstTypeTest(T());
|
||||
}
|
||||
|
||||
template<typename ComponentType, vtkm::IdComponent Size>
|
||||
@ -425,6 +654,8 @@ void TypeTest(const vtkm::Vec<Scalar,4> &)
|
||||
template<typename Scalar>
|
||||
void TypeTest(Scalar)
|
||||
{
|
||||
std::cout << "Test functionality of scalar type." << std::endl;
|
||||
|
||||
Scalar a = 4;
|
||||
Scalar b = 2;
|
||||
|
||||
@ -475,18 +706,22 @@ struct TypeTestFunctor
|
||||
}
|
||||
};
|
||||
|
||||
struct TypesToTest
|
||||
: vtkm::ListTagJoin<
|
||||
vtkm::testing::Testing::TypeListTagExemplarTypes,
|
||||
vtkm::ListTagBase<
|
||||
vtkm::Vec<vtkm::FloatDefault,6>,
|
||||
vtkm::Vec<vtkm::Id,4>,
|
||||
vtkm::Vec<unsigned char,4>,
|
||||
vtkm::Vec<vtkm::Id,1>,
|
||||
vtkm::Vec<vtkm::Float64,1> > >
|
||||
{ };
|
||||
|
||||
void TestTypes()
|
||||
{
|
||||
CheckTypeSizes();
|
||||
|
||||
vtkm::testing::Testing::TryTypes(TypeTestFunctor());
|
||||
|
||||
//try with some custom tuple types
|
||||
TypeTestFunctor()( vtkm::Vec<vtkm::FloatDefault,6>() );
|
||||
TypeTestFunctor()( vtkm::Vec<vtkm::Id,4>() );
|
||||
TypeTestFunctor()( vtkm::Vec<unsigned char,4>() );
|
||||
TypeTestFunctor()( vtkm::Vec<vtkm::Id,1>() );
|
||||
TypeTestFunctor()( vtkm::Vec<vtkm::Float64,1>() );
|
||||
vtkm::testing::Testing::TryTypes(TypeTestFunctor(), TypesToTest());
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
@ -34,12 +34,19 @@ struct TestVecTypeFunctor
|
||||
typedef typename Traits::ComponentType ComponentType;
|
||||
VTKM_TEST_ASSERT(Traits::NUM_COMPONENTS <= MAX_VECTOR_SIZE,
|
||||
"Need to update test for larger vectors.");
|
||||
T vector;
|
||||
T inVector;
|
||||
for (vtkm::IdComponent index = 0; index < Traits::NUM_COMPONENTS; index++)
|
||||
{
|
||||
Traits::SetComponent(vector, index, ComponentType(VecInit[index]));
|
||||
Traits::SetComponent(inVector, index, ComponentType(VecInit[index]));
|
||||
}
|
||||
vtkm::testing::TestVecType<Traits::NUM_COMPONENTS>(vector);
|
||||
T outVector;
|
||||
vtkm::testing::TestVecType<Traits::NUM_COMPONENTS>(inVector, outVector);
|
||||
vtkm::VecC<ComponentType> outVecC(outVector);
|
||||
vtkm::testing::TestVecType<Traits::NUM_COMPONENTS>(
|
||||
vtkm::VecC<ComponentType>(inVector), outVecC);
|
||||
vtkm::VecCConst<ComponentType> outVecCConst(outVector);
|
||||
vtkm::testing::TestVecType<Traits::NUM_COMPONENTS>(
|
||||
vtkm::VecCConst<ComponentType>(inVector), outVecCConst);
|
||||
}
|
||||
};
|
||||
|
||||
@ -53,6 +60,8 @@ void TestVecTraits()
|
||||
vtkm::testing::TestVecComponentsTag<vtkm::Id3>();
|
||||
vtkm::testing::TestVecComponentsTag<vtkm::Vec<vtkm::FloatDefault,3> >();
|
||||
vtkm::testing::TestVecComponentsTag<vtkm::Vec<vtkm::FloatDefault,4> >();
|
||||
vtkm::testing::TestVecComponentsTag<vtkm::VecC<vtkm::FloatDefault> >();
|
||||
vtkm::testing::TestVecComponentsTag<vtkm::VecCConst<vtkm::Id> >();
|
||||
vtkm::testing::TestScalarComponentsTag<vtkm::Id>();
|
||||
vtkm::testing::TestScalarComponentsTag<vtkm::FloatDefault>();
|
||||
}
|
||||
|
@ -55,61 +55,92 @@ inline void CheckIsStatic(const T &, vtkm::VecTraitsTagSizeVariable)
|
||||
// If we are here, everything is fine.
|
||||
}
|
||||
|
||||
template<typename VecType>
|
||||
struct VecIsWritable
|
||||
{
|
||||
using type = std::true_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,
|
||||
const VecCopyType &vectorCopy,
|
||||
T &outVector,
|
||||
std::true_type)
|
||||
{
|
||||
using Traits = vtkm::VecTraits<T>;
|
||||
using ComponentType = typename Traits::ComponentType;
|
||||
|
||||
{
|
||||
const ComponentType multiplier = 4;
|
||||
for (vtkm::IdComponent i = 0; i < NUM_COMPONENTS; i++)
|
||||
{
|
||||
Traits::SetComponent(outVector,
|
||||
i,
|
||||
ComponentType(
|
||||
multiplier*Traits::GetComponent(inVector, i)));
|
||||
}
|
||||
vtkm::Vec<ComponentType,NUM_COMPONENTS> resultCopy;
|
||||
Traits::CopyInto(outVector, resultCopy);
|
||||
VTKM_TEST_ASSERT(test_equal(resultCopy, multiplier*vectorCopy),
|
||||
"Got bad result for scalar multiple");
|
||||
}
|
||||
|
||||
{
|
||||
const ComponentType multiplier = 7;
|
||||
for (vtkm::IdComponent i = 0; i < NUM_COMPONENTS; i++)
|
||||
{
|
||||
Traits::GetComponent(outVector, i)
|
||||
= ComponentType(multiplier * Traits::GetComponent(inVector, i));
|
||||
}
|
||||
vtkm::Vec<ComponentType,NUM_COMPONENTS> resultCopy;
|
||||
Traits::CopyInto(outVector, resultCopy);
|
||||
VTKM_TEST_ASSERT(test_equal(resultCopy, multiplier*vectorCopy),
|
||||
"Got bad result for scalar multiple");
|
||||
}
|
||||
}
|
||||
|
||||
template <vtkm::IdComponent NUM_COMPONENTS, typename T, typename VecCopyType>
|
||||
static void TestVecTypeWritableImpl(const T &vtkmNotUsed(inVector),
|
||||
const VecCopyType &vtkmNotUsed(vectorCopy),
|
||||
T &vtkmNotUsed(outVector),
|
||||
std::false_type)
|
||||
{
|
||||
// Skip writable functionality.
|
||||
}
|
||||
|
||||
/// Compares some manual arithmetic through type traits to arithmetic with
|
||||
/// the Tuple class.
|
||||
template <vtkm::IdComponent NUM_COMPONENTS, typename T>
|
||||
static void TestVecTypeImpl(
|
||||
const typename std::remove_const<T>::type &vector)
|
||||
const typename std::remove_const<T>::type &inVector,
|
||||
typename std::remove_const<T>::type &outVector)
|
||||
{
|
||||
typedef typename vtkm::VecTraits<T> Traits;
|
||||
typedef typename Traits::ComponentType ComponentType;
|
||||
typedef typename std::remove_const<T>::type NonConstT;
|
||||
using Traits = vtkm::VecTraits<T>;
|
||||
using ComponentType = typename Traits::ComponentType;
|
||||
using NonConstT = typename std::remove_const<T>::type;
|
||||
|
||||
CheckIsStatic<NUM_COMPONENTS>(vector, typename Traits::IsSizeStatic());
|
||||
CheckIsStatic<NUM_COMPONENTS>(inVector, typename Traits::IsSizeStatic());
|
||||
|
||||
VTKM_TEST_ASSERT(Traits::GetNumberOfComponents(vector) == NUM_COMPONENTS,
|
||||
VTKM_TEST_ASSERT(Traits::GetNumberOfComponents(inVector) == 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;
|
||||
for (vtkm::IdComponent i = 0; i < NUM_COMPONENTS; i++)
|
||||
{
|
||||
Traits::SetComponent(result,
|
||||
i,
|
||||
ComponentType(
|
||||
multiplier*Traits::GetComponent(vector, i)));
|
||||
}
|
||||
vtkm::Vec<ComponentType,NUM_COMPONENTS> resultCopy;
|
||||
Traits::CopyInto(result, resultCopy);
|
||||
VTKM_TEST_ASSERT(test_equal(resultCopy, multiplier*vectorCopy),
|
||||
"Got bad result for scalar multiple");
|
||||
}
|
||||
|
||||
{
|
||||
NonConstT result;
|
||||
const ComponentType multiplier = 7;
|
||||
for (vtkm::IdComponent i = 0; i < NUM_COMPONENTS; i++)
|
||||
{
|
||||
Traits::GetComponent(result, i)
|
||||
= ComponentType(multiplier * Traits::GetComponent(vector, i));
|
||||
}
|
||||
vtkm::Vec<ComponentType,NUM_COMPONENTS> resultCopy;
|
||||
Traits::CopyInto(result, resultCopy);
|
||||
VTKM_TEST_ASSERT(test_equal(resultCopy, multiplier*vectorCopy),
|
||||
"Got bad result for scalar multiple");
|
||||
}
|
||||
Traits::CopyInto(inVector, vectorCopy);
|
||||
VTKM_TEST_ASSERT(test_equal(vectorCopy, inVector), "CopyInto does not work.");
|
||||
|
||||
{
|
||||
ComponentType result = 0;
|
||||
for (vtkm::IdComponent i = 0; i < NUM_COMPONENTS; i++)
|
||||
{
|
||||
ComponentType component
|
||||
= Traits::GetComponent(vector, i);
|
||||
= Traits::GetComponent(inVector, i);
|
||||
result = ComponentType(result + (component * component));
|
||||
}
|
||||
VTKM_TEST_ASSERT(
|
||||
@ -121,6 +152,12 @@ static void TestVecTypeImpl(
|
||||
detail::CompareDimensionalityTags(
|
||||
typename vtkm::TypeTraits<T>::DimensionalityTag(),
|
||||
typename vtkm::VecTraits<T>::HasMultipleComponents());
|
||||
|
||||
TestVecTypeWritableImpl<NUM_COMPONENTS,NonConstT>(
|
||||
inVector,
|
||||
vectorCopy,
|
||||
outVector,
|
||||
typename VecIsWritable<NonConstT>::type());
|
||||
}
|
||||
|
||||
inline void CheckVecComponentsTag(vtkm::VecTraitsTagMultipleComponents)
|
||||
@ -155,10 +192,10 @@ inline void CheckScalarComponentsTag(vtkm::VecTraitsTagSingleComponent)
|
||||
/// Compares some manual arithmetic through type traits to arithmetic with
|
||||
/// the Tuple class.
|
||||
template <vtkm::IdComponent NUM_COMPONENTS, typename T>
|
||||
static void TestVecType(const T &vector)
|
||||
static void TestVecType(const T &inVector, T &outVector)
|
||||
{
|
||||
detail::TestVecTypeImpl<NUM_COMPONENTS, T>(vector);
|
||||
detail::TestVecTypeImpl<NUM_COMPONENTS, const T>(vector);
|
||||
detail::TestVecTypeImpl<NUM_COMPONENTS, T>(inVector, outVector);
|
||||
detail::TestVecTypeImpl<NUM_COMPONENTS, const T>(inVector, outVector);
|
||||
}
|
||||
|
||||
/// Checks to make sure that the HasMultipleComponents tag is actually for a
|
||||
|
Loading…
Reference in New Issue
Block a user