18 #ifndef viskores_Types_h
19 #define viskores_Types_h
29 #include <type_traits>
209 #if (VISKORES_SIZE_LONG_LONG == 8) || defined(VISKORES_DOXYGEN_ONLY)
210 using Int64 =
signed long long;
216 #define VISKORES_UNUSED_INT_TYPE long
217 #elif VISKORES_SIZE_LONG == 8
218 using Int64 =
signed long;
223 using UInt64 =
unsigned long;
224 #define VISKORES_UNUSED_INT_TYPE long long
226 #error Could not find a 64-bit integer.
234 #ifdef VISKORES_USE_64BIT_IDS
241 #ifdef VISKORES_USE_DOUBLE_PRECISION
264 #if (defined(VISKORES_GCC) || defined(VISKORES_CLANG))
265 #pragma GCC diagnostic push
266 #pragma GCC diagnostic ignored "-Wconversion"
267 #endif // gcc || clang
270 template <
typename T,
typename U>
279 template <
typename T>
281 typename std::enable_if<std::is_integral<T>::value &&
sizeof(T) <
sizeof(
int), T>::type
284 return static_cast<T
>(a + b);
290 template <
typename T,
typename U>
299 template <
typename T>
301 typename std::enable_if<std::is_integral<T>::value &&
sizeof(T) <
sizeof(
int), T>::type
304 return static_cast<T
>(a - b);
310 template <
typename T,
typename U>
319 template <
typename T>
321 typename std::enable_if<std::is_integral<T>::value &&
sizeof(T) <
sizeof(
int), T>::type
324 return static_cast<T
>(a * b);
330 template <
typename T,
typename U>
339 template <
typename T>
341 typename std::enable_if<std::is_integral<T>::value &&
sizeof(T) <
sizeof(
int), T>::type
344 return static_cast<T
>(a / b);
350 template <
typename T>
357 #if (defined(VISKORES_GCC) || defined(VISKORES_CLANG))
358 #pragma GCC diagnostic pop
359 #endif // gcc || clang
364 template <
typename T, viskores::IdComponent Size>
365 class VISKORES_ALWAYS_EXPORT
Vec;
367 template <
typename T>
368 class VISKORES_ALWAYS_EXPORT
VecC;
370 template <
typename T>
388 #if (defined(VISKORES_CUDA) && (__CUDACC_VER_MAJOR__ < 8))
389 #if (defined(VISKORES_GCC) || defined(VISKORES_CLANG))
390 #pragma GCC diagnostic push
391 #pragma GCC diagnostic ignored "-Wunknown-pragmas"
392 #pragma GCC diagnostic ignored "-Wpragmas"
393 #pragma GCC diagnostic ignored "-Wconversion"
394 #pragma GCC diagnostic ignored "-Wfloat-conversion"
395 #endif // gcc || clang
396 #endif // use cuda < 8
397 template <
typename T,
typename DerivedClass>
398 class VISKORES_ALWAYS_EXPORT VecBaseCommon
404 constexpr VecBaseCommon() =
default;
407 constexpr
const DerivedClass& Derived()
const {
return *
static_cast<const DerivedClass*
>(
this); }
410 constexpr DerivedClass& Derived() {
return *
static_cast<DerivedClass*
>(
this); }
417 return this->Derived().GetNumberOfComponents();
429 template <viskores::IdComponent OtherSize>
435 dest[index] = this->Component(index);
440 template <
typename OtherVecType>
446 this->Component(i) = src[i];
448 return this->Derived();
452 bool operator==(
const DerivedClass& other)
const
457 equal = (this->Component(i) == other[i]);
463 bool operator<(
const DerivedClass& other)
const
468 if (this->Component(i) < other[i])
472 else if (other[i] < this->Component(i))
484 #if (!(defined(VISKORES_CUDA) && (__CUDACC_VER_MAJOR__ < 8)))
485 #if (defined(VISKORES_GCC) || defined(VISKORES_CLANG))
486 #pragma GCC diagnostic push
487 #pragma GCC diagnostic ignored "-Wunknown-pragmas"
488 #pragma GCC diagnostic ignored "-Wpragmas"
489 #pragma GCC diagnostic ignored "-Wconversion"
490 #pragma GCC diagnostic ignored "-Wfloat-conversion"
491 #endif // gcc || clang
492 #endif // not using cuda < 8
494 template <viskores::IdComponent Size>
502 result[i] = this->Component(i) + other[i];
507 template <
typename OtherClass>
510 VISKORES_ASSERT(this->NumComponents() == other.GetNumberOfComponents());
513 this->Component(i) += other[i];
515 return this->Derived();
518 template <viskores::IdComponent Size>
526 result[i] = this->Component(i) - other[i];
531 template <
typename OtherClass>
534 VISKORES_ASSERT(this->NumComponents() == other.GetNumberOfComponents());
537 this->Component(i) -= other[i];
539 return this->Derived();
542 template <viskores::IdComponent Size>
549 result[i] = this->Component(i) * other[i];
554 template <
typename OtherClass>
557 VISKORES_ASSERT(this->NumComponents() == other.GetNumberOfComponents());
560 this->Component(i) *= other[i];
562 return this->Derived();
565 template <viskores::IdComponent Size>
572 result[i] = this->Component(i) / other[i];
577 template <
typename OtherClass>
580 VISKORES_ASSERT(this->NumComponents() == other.GetNumberOfComponents());
583 this->Component(i) /= other[i];
585 return this->Derived();
588 #if (!(defined(VISKORES_CUDA) && (__CUDACC_VER_MAJOR__ < 8)))
589 #if (defined(VISKORES_GCC) || defined(VISKORES_CLANG))
590 #pragma GCC diagnostic pop
591 #endif // gcc || clang
592 #endif // not using cuda < 8
595 constexpr ComponentType* GetPointer() {
return &this->Component(0); }
598 constexpr
const ComponentType* GetPointer()
const {
return &this->Component(0); }
604 template <
typename T, viskores::IdComponent Size,
typename DerivedClass>
605 class VISKORES_ALWAYS_EXPORT VecBase :
public viskores::detail::VecBaseCommon<T, DerivedClass>
608 using ComponentType = T;
616 template <viskores::IdComponent Size2 = Size, typename std::enable_if<Size2 != 1, int>::type = 0>
621 this->Components[i] = value;
626 template <
typename... Ts>
628 : Components{ value0, values... }
635 VecBase(std::initializer_list<ComponentType> values)
637 ComponentType* dest = this->Components;
638 auto src = values.begin();
639 if (values.size() == 1)
643 this->Components[i] = *src;
650 "Vec object initialized wrong number of components.");
651 for (; src != values.end(); ++src)
659 #if (!(defined(VISKORES_CUDA) && (__CUDACC_VER_MAJOR__ < 8)))
660 #if (defined(VISKORES_GCC) || defined(VISKORES_CLANG))
661 #pragma GCC diagnostic push
662 #pragma GCC diagnostic ignored "-Wunknown-pragmas"
663 #pragma GCC diagnostic ignored "-Wpragmas"
664 #pragma GCC diagnostic ignored "-Wconversion"
665 #pragma GCC diagnostic ignored "-Wfloat-conversion"
666 #endif // gcc || clang
667 #endif //not using cuda < 8
668 #if defined(VISKORES_MSVC)
669 #pragma warning(push)
670 #pragma warning(disable : 4244)
674 template <
typename OtherValueType,
typename OtherDerivedType>
675 VISKORES_EXEC_CONT explicit VecBase(
const VecBase<OtherValueType, Size, OtherDerivedType>& src)
681 this->Components[i] = src[i];
688 return NUM_COMPONENTS;
694 return this->Components[idx];
701 return this->Components[idx];
705 template <
typename OtherComponentType,
typename OtherClass>
707 operator+(
const VecBaseCommon<OtherComponentType, OtherClass>& other)
const
709 const OtherClass& other_derived =
static_cast<const OtherClass&
>(other);
710 VISKORES_ASSERT(NUM_COMPONENTS == other_derived.GetNumberOfComponents());
715 result[i] = this->Components[i] +
static_cast<ComponentType
>(other_derived[i]);
721 template <
typename OtherComponentType,
typename OtherClass>
723 operator-(
const VecBaseCommon<OtherComponentType, OtherClass>& other)
const
725 const OtherClass& other_derived =
static_cast<const OtherClass&
>(other);
726 VISKORES_ASSERT(NUM_COMPONENTS == other_derived.GetNumberOfComponents());
731 result[i] = this->Components[i] -
static_cast<ComponentType
>(other_derived[i]);
737 template <
typename OtherComponentType,
typename OtherClass>
739 operator*(
const VecBaseCommon<OtherComponentType, OtherClass>& other)
const
741 const OtherClass& other_derived =
static_cast<const OtherClass&
>(other);
742 VISKORES_ASSERT(NUM_COMPONENTS == other_derived.GetNumberOfComponents());
747 result[i] = this->Components[i] *
static_cast<ComponentType
>(other_derived[i]);
753 template <
typename OtherComponentType,
typename OtherClass>
755 operator/(
const VecBaseCommon<OtherComponentType, OtherClass>& other)
const
757 const OtherClass& other_derived =
static_cast<const OtherClass&
>(other);
758 VISKORES_ASSERT(NUM_COMPONENTS == other_derived.GetNumberOfComponents());
763 result[i] = this->Components[i] /
static_cast<ComponentType
>(other_derived[i]);
768 #if (!(defined(VISKORES_CUDA) && (__CUDACC_VER_MAJOR__ < 8)))
769 #if (defined(VISKORES_GCC) || defined(VISKORES_CLANG))
770 #pragma GCC diagnostic pop
771 #endif // gcc || clang
772 #endif // not using cuda < 8
773 #if defined(VISKORES_MSVC)
778 ComponentType Components[NUM_COMPONENTS];
781 #if (defined(VISKORES_CUDA) && (__CUDACC_VER_MAJOR__ < 8))
782 #if (defined(VISKORES_GCC) || defined(VISKORES_CLANG))
783 #pragma GCC diagnostic pop
784 #endif // gcc || clang
785 #endif // use cuda < 8
789 template <
typename T,
typename DerivedClass>
790 class VISKORES_ALWAYS_EXPORT VecCBase :
public viskores::detail::VecBaseCommon<T, DerivedClass>
794 constexpr VecCBase() {}
816 template <
typename T, viskores::IdComponent Size>
817 class VISKORES_ALWAYS_EXPORT Vec :
public detail::VecBase<T, Size, Vec<T, Size>>
822 #ifdef VISKORES_DOXYGEN_ONLY
827 using Superclass::Superclass;
828 constexpr
Vec() =
default;
829 #if defined(_MSC_VER) && _MSC_VER < 1910
830 template <
typename... Ts>
831 constexpr
Vec(T value, Ts&&... values)
832 :
Superclass(value, std::forward<Ts>(values)...)
846 template <
typename T>
847 class VISKORES_ALWAYS_EXPORT
Vec<T, 0>
853 constexpr
Vec() =
default;
856 template <
typename OtherType>
869 return NUM_COMPONENTS;
886 template <
typename T>
887 class VISKORES_ALWAYS_EXPORT
Vec<T, 1> :
public detail::VecBase<T, 1, Vec<T, 1>>
898 template <
typename OtherType>
908 template <
typename T>
909 class VISKORES_ALWAYS_EXPORT
Vec<T, 2> :
public detail::VecBase<T, 2, Vec<T, 2>>
914 constexpr
Vec() =
default;
920 template <
typename OtherType>
927 constexpr
Vec(
const T& x,
const T& y)
994 #ifdef VISKORES_USE_64BIT_IDS
1024 template <
typename T>
1025 class VISKORES_ALWAYS_EXPORT
Vec<T, 3> :
public detail::VecBase<T, 3, Vec<T, 3>>
1030 constexpr
Vec() =
default;
1036 template <
typename OtherType>
1043 constexpr
Vec(
const T& x,
const T& y,
const T& z)
1112 #ifdef VISKORES_USE_64BIT_IDS
1142 template <
typename T>
1143 class VISKORES_ALWAYS_EXPORT
Vec<T, 4> :
public detail::VecBase<T, 4, Vec<T, 4>>
1148 constexpr
Vec() =
default;
1154 template <
typename OtherType>
1161 constexpr
Vec(
const T& x,
const T& y,
const T& z,
const T& w)
1228 #ifdef VISKORES_USE_64BIT_IDS
1261 template <
typename T,
typename... Ts>
1287 template <
typename T>
1288 class VISKORES_ALWAYS_EXPORT VecC :
public detail::VecCBase<T, VecC<T>>
1293 "You cannot use VecC with a const type as its template argument. "
1294 "Use either const VecC or VecCConst.");
1297 #ifdef VISKORES_DOXYGEN_ONLY
1303 : Components(nullptr)
1304 , NumberOfComponents(0)
1311 , NumberOfComponents(size)
1315 template <viskores::IdComponent Size>
1317 : Components(src.GetPointer())
1318 , NumberOfComponents(Size)
1325 , NumberOfComponents(1)
1331 : Components(src.Components)
1332 , NumberOfComponents(src.NumberOfComponents)
1340 return this->Components[index];
1347 return this->Components[index];
1352 return this->NumberOfComponents;
1361 (*this)[index] = src[index];
1381 template <
typename T>
1382 class VISKORES_ALWAYS_EXPORT
VecCConst :
public detail::VecCBase<T, VecCConst<T>>
1387 "You cannot use VecCConst with a const type as its template argument. "
1388 "Remove the const from the type.");
1391 #ifdef VISKORES_DOXYGEN_ONLY
1397 : Components(nullptr)
1398 , NumberOfComponents(0)
1405 , NumberOfComponents(size)
1409 template <viskores::IdComponent Size>
1411 : Components(src.GetPointer())
1412 , NumberOfComponents(Size)
1419 , NumberOfComponents(1)
1425 : Components(src.Components)
1426 , NumberOfComponents(src.NumberOfComponents)
1432 : Components(src.Components)
1433 , NumberOfComponents(src.NumberOfComponents)
1441 return this->Components[index];
1446 return this->NumberOfComponents;
1464 template <
typename T>
1473 template <
typename T>
1484 template <
typename T>
1487 auto result = a[0] * b[0];
1490 result = result + a[i] * b[i];
1494 template <
typename T, viskores::IdComponent Size>
1498 auto result = a[0] * b[0];
1501 result = result + a[i] * b[i];
1508 template <
typename T>
1511 return detail::vec_dot(a, b);
1514 template <
typename T>
1518 return (a[0] * b[0]) + (a[1] * b[1]);
1520 template <
typename T>
1524 return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]);
1526 template <
typename T>
1530 return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]) + (a[3] * b[3]);
1534 #define VISKORES_SCALAR_DOT(stype) \
1535 static inline VISKORES_EXEC_CONT auto dot(stype a, stype b) \
1539 static inline VISKORES_EXEC_CONT auto Dot(stype a, stype b) \
1555 template <
typename T>
1556 static inline VISKORES_EXEC_CONT auto dot(
const T& a,
const T& b) -> decltype(detail::vec_dot(a, b))
1558 return viskores::Dot(a, b);
1560 template <
typename T>
1564 return viskores::Dot(a, b);
1566 template <
typename T>
1570 return viskores::Dot(a, b);
1572 template <
typename T>
1576 return viskores::Dot(a, b);
1580 template <
typename T, viskores::IdComponent Size>
1591 template <
typename T>
1597 template <
typename T>
1600 return a[0] + a[1] + a[2];
1603 template <
typename T>
1606 return a[0] + a[1] + a[2] + a[3];
1609 template <
typename T, viskores::IdComponent Size>
1620 template <
typename T>
1626 template <
typename T>
1629 return a[0] * a[1] * a[2];
1632 template <
typename T>
1635 return a[0] * a[1] * a[2] * a[3];
1640 template <
typename U,
typename V>
1645 template <
typename T, viskores::IdComponent Size>
1652 stream << vec[component] <<
",";
1654 return stream << vec[Size - 1] <<
"]";
1659 template <
typename T,
typename U>
1663 return stream <<
"[" << vec.
first <<
"," << vec.
second <<
"]";
1670 #endif //viskores_Types_h