//============================================================================ // Copyright (c) Kitware, Inc. // All rights reserved. // See LICENSE.txt for details. // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. // // Copyright 2014 Sandia Corporation. // Copyright 2014 UT-Battelle, LLC. // Copyright 2014 Los Alamos National Security. // // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. // // Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National // Laboratory (LANL), the U.S. Government retains certain rights in // this software. //============================================================================ #ifndef vtk_m_VecTraits_h #define vtk_m_VecTraits_h #include VTKM_THIRDPARTY_PRE_INCLUDE #include VTKM_THIRDPARTY_POST_INCLUDE namespace vtkm { /// A tag for vectors that are "true" vectors (i.e. have more than one /// component). /// struct VecTraitsTagMultipleComponents { }; /// A tag for vectors that are really just scalars (i.e. have only one /// component) /// 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 struct VecTraitsMultipleComponentChooser { typedef VecTraitsTagMultipleComponents Type; }; template<> struct VecTraitsMultipleComponentChooser<1> { typedef VecTraitsTagSingleComponent Type; }; } // namespace detail /// The VecTraits class gives several static members that define how /// to use a given type as a vector. /// template struct VecTraits #ifdef VTKM_DOXYGEN_ONLY { /// Type of the components in the vector. /// typedef typename VecType::ComponentType ComponentType; /// \brief 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); /// \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. /// typedef typename internal::VecTraitsMultipleComponentChooser< NUM_COMPONENTS>::Type HasMultipleComponents; /// \brief 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( const typename boost::remove_const::type &vector, vtkm::IdComponent component); VTKM_EXEC_CONT_EXPORT static ComponentType &GetComponent( typename boost::remove_const::type &vector, vtkm::IdComponent component); /// Changes the value in a given component of the vector. /// VTKM_EXEC_CONT_EXPORT static void SetComponent(VecType &vector, vtkm::IdComponent component, ComponentType value); /// Copies the components in the given vector into a given Vec object. /// template VTKM_EXEC_CONT_EXPORT static void CopyInto(const VecType &src, vtkm::Vec &dest); }; #else // VTKM_DOXYGEN_ONLY ; #endif // VTKM_DOXYGEN_ONLY // This partial specialization allows you to define a non-const version of // VecTraits and have it still work for const version. // template struct VecTraits : VecTraits { }; template struct VecTraits > { typedef vtkm::Vec VecType; /// Type of the components in the vector. /// typedef typename VecType::ComponentType ComponentType; /// Number of components in the vector. /// static const vtkm::IdComponent NUM_COMPONENTS = VecType::NUM_COMPONENTS; /// Number of components in the given vector. /// VTKM_EXEC_CONT_EXPORT 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. /// 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(const VecType &vector, vtkm::IdComponent component) { return vector[component]; } VTKM_EXEC_CONT_EXPORT static ComponentType &GetComponent(VecType &vector, vtkm::IdComponent component) { return vector[component]; } /// Changes the value in a given component of the vector. /// VTKM_EXEC_CONT_EXPORT 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_EXEC_CONT_EXPORT static void CopyInto(const VecType &src, vtkm::Vec &dest) { src.CopyInto(dest); } }; namespace internal { /// Used for overriding VecTraits for basic scalar types. /// template 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, vtkm::IdComponent) { return vector; } VTKM_EXEC_CONT_EXPORT static ComponentType &GetComponent(ScalarType &vector, vtkm::IdComponent) { return vector; } VTKM_EXEC_CONT_EXPORT static void SetComponent(ScalarType &vector, vtkm::IdComponent, ComponentType value) { vector = value; } template VTKM_EXEC_CONT_EXPORT static void CopyInto(const ScalarType &src, vtkm::Vec &dest) { dest[0] = src; } }; } // namespace internal /// \brief VecTraits for Pair types /// /// Although a pair woudl 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 struct VecTraits > : public vtkm::internal::VecTraitsBasic > { }; } // anonymous namespace #define VTKM_BASIC_TYPE_VECTOR(type) \ namespace vtkm { \ template<> \ struct VecTraits \ : public vtkm::internal::VecTraitsBasic { }; \ } /// 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(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