1 //============================================================================
2 //  Copyright (c) Kitware, Inc.
3 //  All rights reserved.
4 //  See LICENSE.txt for details.
5 //  This software is distributed WITHOUT ANY WARRANTY; without even
6 //  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
7 //  PURPOSE.  See the above copyright notice for more information.
8 //
9 //  Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
10 //  Copyright 2014 UT-Battelle, LLC.
11 //  Copyright 2014 Los Alamos National Security.
12 //
13 //  Under the terms of Contract DE-NA0003525 with NTESS,
14 //  the U.S. Government retains certain rights in this software.
15 //
16 //  Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
17 //  Laboratory (LANL), the U.S. Government retains certain rights in
18 //  this software.
19 //============================================================================
20 #ifndef vtk_m_TypeTraits_h
21 #define vtk_m_TypeTraits_h
22 
23 #include <vtkm/Types.h>
24 
25 namespace vtkm
26 {
27 
28 /// Tag used to identify types that aren't Real, Integer, Scalar or Vector.
29 ///
30 struct TypeTraitsUnknownTag
31 {
32 };
33 
34 /// Tag used to identify types that store real (floating-point) numbers. A
35 /// TypeTraits class will typedef this class to NumericTag if it stores real
36 /// numbers (or vectors of real numbers).
37 ///
38 struct TypeTraitsRealTag
39 {
40 };
41 
42 /// Tag used to identify types that store integer numbers. A TypeTraits class
43 /// will typedef this class to NumericTag if it stores integer numbers (or
44 /// vectors of integers).
45 ///
46 struct TypeTraitsIntegerTag
47 {
48 };
49 
50 /// Tag used to identify 0 dimensional types (scalars). Scalars can also be
51 /// treated like vectors when used with VecTraits. A TypeTraits class will
52 /// typedef this class to DimensionalityTag.
53 ///
54 struct TypeTraitsScalarTag
55 {
56 };
57 
58 /// Tag used to identify 1 dimensional types (vectors). A TypeTraits class will
59 /// typedef this class to DimensionalityTag.
60 ///
61 struct TypeTraitsVectorTag
62 {
63 };
64 
65 /// The TypeTraits class provides helpful compile-time information about the
66 /// basic types used in VTKm (and a few others for convenience). The majority
67 /// of TypeTraits contents are typedefs to tags that can be used to easily
68 /// override behavior of called functions.
69 ///
70 template <typename T>
71 class TypeTraits
72 {
73 public:
74   /// \brief A tag to determine whether the type is integer or real.
75   ///
76   /// This tag is either TypeTraitsRealTag or TypeTraitsIntegerTag.
77   using NumericTag = vtkm::TypeTraitsUnknownTag;
78 
79   /// \brief A tag to determine whether the type has multiple components.
80   ///
81   /// This tag is either TypeTraitsScalarTag or TypeTraitsVectorTag. Scalars can
82   /// also be treated as vectors.
83   using DimensionalityTag = vtkm::TypeTraitsUnknownTag;
84 
ZeroInitialization()85   VTKM_EXEC_CONT static T ZeroInitialization() { return T(); }
86 };
87 
88 // Const types should have the same traits as their non-const counterparts.
89 //
90 template <typename T>
91 struct TypeTraits<const T> : TypeTraits<T>
92 {
93 };
94 
95 #define VTKM_BASIC_REAL_TYPE(T)                                                                    \
96   template <>                                                                                      \
97   struct TypeTraits<T>                                                                             \
98   {                                                                                                \
99     using NumericTag = TypeTraitsRealTag;                                                          \
100     using DimensionalityTag = TypeTraitsScalarTag;                                                 \
101     VTKM_EXEC_CONT static T ZeroInitialization() { return T(); }                                   \
102   };
103 
104 #define VTKM_BASIC_INTEGER_TYPE(T)                                                                 \
105   template <>                                                                                      \
106   struct TypeTraits<T>                                                                             \
107   {                                                                                                \
108     using NumericTag = TypeTraitsIntegerTag;                                                       \
109     using DimensionalityTag = TypeTraitsScalarTag;                                                 \
110     VTKM_EXEC_CONT static T ZeroInitialization()                                                   \
111     {                                                                                              \
112       using ReturnType = T;                                                                        \
113       return ReturnType();                                                                         \
114     }                                                                                              \
115   };
116 
117 /// Traits for basic C++ types.
118 ///
119 
120 VTKM_BASIC_REAL_TYPE(float)
121 VTKM_BASIC_REAL_TYPE(double)
122 
123 VTKM_BASIC_INTEGER_TYPE(char)
124 VTKM_BASIC_INTEGER_TYPE(signed char)
125 VTKM_BASIC_INTEGER_TYPE(unsigned char)
126 VTKM_BASIC_INTEGER_TYPE(short)
127 VTKM_BASIC_INTEGER_TYPE(unsigned short)
128 VTKM_BASIC_INTEGER_TYPE(int)
129 VTKM_BASIC_INTEGER_TYPE(unsigned int)
130 VTKM_BASIC_INTEGER_TYPE(long)
131 VTKM_BASIC_INTEGER_TYPE(unsigned long)
132 VTKM_BASIC_INTEGER_TYPE(long long)
133 VTKM_BASIC_INTEGER_TYPE(unsigned long long)
134 
135 #undef VTKM_BASIC_REAL_TYPE
136 #undef VTKM_BASIC_INTEGER_TYPE
137 
138 /// Traits for Vec types.
139 ///
140 template <typename T, vtkm::IdComponent Size>
141 struct TypeTraits<vtkm::Vec<T, Size>>
142 {
143   using NumericTag = typename vtkm::TypeTraits<T>::NumericTag;
144   using DimensionalityTag = vtkm::TypeTraitsVectorTag;
145 
146   VTKM_EXEC_CONT
147   static vtkm::Vec<T, Size> ZeroInitialization()
148   {
149     return vtkm::Vec<T, Size>(vtkm::TypeTraits<T>::ZeroInitialization());
150   }
151 };
152 
153 /// Traits for VecCConst types.
154 ///
155 template <typename T>
156 struct TypeTraits<vtkm::VecCConst<T>>
157 {
158   using NumericTag = typename vtkm::TypeTraits<T>::NumericTag;
159   using DimensionalityTag = TypeTraitsVectorTag;
160 
161   VTKM_EXEC_CONT
162   static vtkm::VecCConst<T> ZeroInitialization() { return vtkm::VecCConst<T>(); }
163 };
164 
165 /// Traits for VecC types.
166 ///
167 template <typename T>
168 struct TypeTraits<vtkm::VecC<T>>
169 {
170   using NumericTag = typename vtkm::TypeTraits<T>::NumericTag;
171   using DimensionalityTag = TypeTraitsVectorTag;
172 
173   VTKM_EXEC_CONT
174   static vtkm::VecC<T> ZeroInitialization() { return vtkm::VecC<T>(); }
175 };
176 
177 /// \brief Traits for Pair types.
178 ///
179 template <typename T, typename U>
180 struct TypeTraits<vtkm::Pair<T, U>>
181 {
182   using NumericTag = vtkm::TypeTraitsUnknownTag;
183   using DimensionalityTag = vtkm::TypeTraitsScalarTag;
184 
185   VTKM_EXEC_CONT
186   static vtkm::Pair<T, U> ZeroInitialization()
187   {
188     return vtkm::Pair<T, U>(TypeTraits<T>::ZeroInitialization(),
189                             TypeTraits<U>::ZeroInitialization());
190   }
191 };
192 
193 } // namespace vtkm
194 
195 #endif //vtk_m_TypeTraits_h
196