VTK-m  2.0
VecFlat.h
Go to the documentation of this file.
1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10 #ifndef vtk_m_VecFlat_h
11 #define vtk_m_VecFlat_h
12 
13 #include <vtkm/StaticAssert.h>
14 #include <vtkm/TypeTraits.h>
15 #include <vtkm/Types.h>
16 #include <vtkm/VecTraits.h>
17 
18 namespace vtkm
19 {
20 
21 namespace internal
22 {
23 
24 template <typename T,
25  typename MultipleComponents = typename vtkm::VecTraits<T>::HasMultipleComponents>
26 struct TotalNumComponents;
27 
28 template <typename T>
29 struct TotalNumComponents<T, vtkm::VecTraitsTagMultipleComponents>
30 {
32  (std::is_same<typename vtkm::VecTraits<T>::IsSizeStatic, vtkm::VecTraitsTagSizeStatic>::value),
33  "vtkm::VecFlat can only be used with Vec types with a static number of components.");
34  using ComponentType = typename vtkm::VecTraits<T>::ComponentType;
35  static constexpr vtkm::IdComponent value =
36  vtkm::VecTraits<T>::NUM_COMPONENTS * TotalNumComponents<ComponentType>::value;
37 };
38 
39 template <typename T>
40 struct TotalNumComponents<T, vtkm::VecTraitsTagSingleComponent>
41 {
42  static constexpr vtkm::IdComponent value = 1;
43 };
44 
45 template <typename T>
47  vtkm::internal::TotalNumComponents<T>::value>;
48 
49 template <typename T>
50 using IsFlatVec = typename std::is_same<T, FlattenVec<T>>::type;
51 
52 namespace detail
53 {
54 
55 template <typename T>
56 VTKM_EXEC_CONT T GetFlatVecComponentImpl(const T& component,
57  vtkm::IdComponent index,
58  std::true_type vtkmNotUsed(isBase))
59 {
60  VTKM_ASSERT(index == 0);
61  return component;
62 }
63 
64 template <typename T>
66 GetFlatVecComponentImpl(const T& vec, vtkm::IdComponent index, std::false_type vtkmNotUsed(isBase))
67 {
68  using Traits = vtkm::VecTraits<T>;
69  using ComponentType = typename Traits::ComponentType;
70  using BaseComponentType = typename Traits::BaseComponentType;
71 
72  constexpr vtkm::IdComponent subSize = TotalNumComponents<ComponentType>::value;
73  return GetFlatVecComponentImpl(Traits::GetComponent(vec, index / subSize),
74  index % subSize,
75  typename std::is_same<ComponentType, BaseComponentType>::type{});
76 }
77 
78 } // namespace detail
79 
80 template <typename T>
81 VTKM_EXEC_CONT typename vtkm::VecTraits<T>::BaseComponentType GetFlatVecComponent(
82  const T& vec,
83  vtkm::IdComponent index)
84 {
85  return detail::GetFlatVecComponentImpl(vec, index, std::false_type{});
86 }
87 
88 namespace detail
89 {
90 
91 template <typename T, vtkm::IdComponent N>
92 VTKM_EXEC_CONT void CopyVecNestedToFlatImpl(T nestedVec,
93  vtkm::Vec<T, N>& flatVec,
94  vtkm::IdComponent flatOffset)
95 {
96  flatVec[flatOffset] = nestedVec;
97 }
98 
99 template <typename T, vtkm::IdComponent NFlat, vtkm::IdComponent NNest>
100 VTKM_EXEC_CONT void CopyVecNestedToFlatImpl(const vtkm::Vec<T, NNest>& nestedVec,
101  vtkm::Vec<T, NFlat>& flatVec,
102  vtkm::IdComponent flatOffset)
103 {
104  for (vtkm::IdComponent nestedIndex = 0; nestedIndex < NNest; ++nestedIndex)
105  {
106  flatVec[nestedIndex + flatOffset] = nestedVec[nestedIndex];
107  }
108 }
109 
110 template <typename T, vtkm::IdComponent N, typename NestedVecType>
111 VTKM_EXEC_CONT void CopyVecNestedToFlatImpl(const NestedVecType& nestedVec,
112  vtkm::Vec<T, N>& flatVec,
113  vtkm::IdComponent flatOffset)
114 {
115  using Traits = vtkm::VecTraits<NestedVecType>;
116  using ComponentType = typename Traits::ComponentType;
117  constexpr vtkm::IdComponent subSize = TotalNumComponents<ComponentType>::value;
118 
119  vtkm::IdComponent flatIndex = flatOffset;
120  for (vtkm::IdComponent nestIndex = 0; nestIndex < Traits::NUM_COMPONENTS; ++nestIndex)
121  {
122  CopyVecNestedToFlatImpl(Traits::GetComponent(nestedVec, nestIndex), flatVec, flatIndex);
123  flatIndex += subSize;
124  }
125 }
126 
127 } // namespace detail
128 
129 template <typename T, vtkm::IdComponent N, typename NestedVecType>
130 VTKM_EXEC_CONT void CopyVecNestedToFlat(const NestedVecType& nestedVec, vtkm::Vec<T, N>& flatVec)
131 {
132  detail::CopyVecNestedToFlatImpl(nestedVec, flatVec, 0);
133 }
134 
135 namespace detail
136 {
137 
138 template <typename T, vtkm::IdComponent N>
139 VTKM_EXEC_CONT void CopyVecFlatToNestedImpl(const vtkm::Vec<T, N>& flatVec,
140  vtkm::IdComponent flatOffset,
141  T& nestedVec)
142 {
143  nestedVec = flatVec[flatOffset];
144 }
145 
146 template <typename T, vtkm::IdComponent NFlat, vtkm::IdComponent NNest>
147 VTKM_EXEC_CONT void CopyVecFlatToNestedImpl(const vtkm::Vec<T, NFlat>& flatVec,
148  vtkm::IdComponent flatOffset,
149  vtkm::Vec<T, NNest>& nestedVec)
150 {
151  for (vtkm::IdComponent nestedIndex = 0; nestedIndex < NNest; ++nestedIndex)
152  {
153  nestedVec[nestedIndex] = flatVec[nestedIndex + flatOffset];
154  }
155 }
156 
157 template <typename T, vtkm::IdComponent NFlat, typename ComponentType, vtkm::IdComponent NNest>
158 VTKM_EXEC_CONT void CopyVecFlatToNestedImpl(const vtkm::Vec<T, NFlat>& flatVec,
159  vtkm::IdComponent flatOffset,
161 {
162  constexpr vtkm::IdComponent subSize = TotalNumComponents<ComponentType>::value;
163 
164  vtkm::IdComponent flatIndex = flatOffset;
165  for (vtkm::IdComponent nestIndex = 0; nestIndex < NNest; ++nestIndex)
166  {
167  CopyVecFlatToNestedImpl(flatVec, flatIndex, nestedVec[nestIndex]);
168  flatIndex += subSize;
169  }
170 }
171 
172 template <typename T, vtkm::IdComponent N, typename NestedVecType>
173 VTKM_EXEC_CONT void CopyVecFlatToNestedImpl(const vtkm::Vec<T, N>& flatVec,
174  vtkm::IdComponent flatOffset,
175  NestedVecType& nestedVec)
176 {
177  using Traits = vtkm::VecTraits<NestedVecType>;
178  using ComponentType = typename Traits::ComponentType;
179  constexpr vtkm::IdComponent subSize = TotalNumComponents<ComponentType>::value;
180 
181  vtkm::IdComponent flatIndex = flatOffset;
182  for (vtkm::IdComponent nestIndex = 0; nestIndex < Traits::NUM_COMPONENTS; ++nestIndex)
183  {
184  ComponentType component;
185  CopyVecFlatToNestedImpl(flatVec, flatIndex, component);
186  Traits::SetComponent(nestedVec, nestIndex, component);
187  flatIndex += subSize;
188  }
189 }
190 
191 } // namespace detail
192 
193 template <typename T, vtkm::IdComponent N, typename NestedVecType>
194 VTKM_EXEC_CONT void CopyVecFlatToNested(const vtkm::Vec<T, N>& flatVec, NestedVecType& nestedVec)
195 {
196  detail::CopyVecFlatToNestedImpl(flatVec, 0, nestedVec);
197 }
198 
199 } // namespace internal
200 
223 template <typename T, bool = internal::IsFlatVec<T>::value>
224 class VecFlat;
225 
226 // Case where T is not a vtkm::Vec<T, N> where T is not a Vec.
227 template <typename T>
228 class VecFlat<T, false> : public internal::FlattenVec<T>
229 {
231 
232 public:
233  using Superclass::Superclass;
234  VecFlat() = default;
235 
236  VTKM_EXEC_CONT VecFlat(const T& src) { *this = src; }
237 
239  {
240  internal::CopyVecNestedToFlat(src, *this);
241  return *this;
242  }
243 
244  VTKM_EXEC_CONT operator T() const
245  {
246  T nestedVec;
247  internal::CopyVecFlatToNested(*this, nestedVec);
248  return nestedVec;
249  }
250 };
251 
252 // Specialization of VecFlat where the Vec is already flat Vec
253 template <typename T>
254 class VecFlat<T, true> : public T
255 {
256 public:
257  using T::T;
258  VecFlat() = default;
259 
260  VTKM_EXEC_CONT VecFlat(const T& src)
261  : T(src)
262  {
263  }
264 
266  {
267  this->T::operator=(src);
268  return *this;
269  }
270 
272  {
273  this->T::operator=(std::move(src));
274  return *this;
275  }
276 };
277 
280 template <typename T>
282 {
283  return vtkm::VecFlat<T>(vec);
284 }
285 
286 template <typename T>
287 struct TypeTraits<vtkm::VecFlat<T>> : TypeTraits<internal::FlattenVec<T>>
288 {
289 };
290 
291 template <typename T>
292 struct VecTraits<vtkm::VecFlat<T>> : VecTraits<internal::FlattenVec<T>>
293 {
294 };
295 
296 } // namespace vtkm
297 
298 #endif //vtk_m_VecFlat_h
vtkm::VecFlat< T, true >::operator=
VTKM_EXEC_CONT VecFlat & operator=(T &&src)
Definition: VecFlat.h:271
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::TypeTraits
The TypeTraits class provides helpful compile-time information about the basic types used in VTKm (an...
Definition: TypeTraits.h:61
Types.h
VTKM_ASSERT
#define VTKM_ASSERT(condition)
Definition: Assert.h:43
VTKM_EXEC_CONT
#define VTKM_EXEC_CONT
Definition: ExportMacros.h:52
vtkm::IdComponent
vtkm::Int32 IdComponent
Represents a component ID (index of component in a vector).
Definition: Types.h:168
vtkm::VecTraits::BaseComponentType
typename vtkm::VecTraits< ComponentType >::BaseComponentType BaseComponentType
Base component type in the vector.
Definition: VecTraits.h:80
vtkm::Vec::Superclass
detail::VecBase< T, Size, Vec< T, Size > > Superclass
Definition: Types.h:769
vtkm::VecFlat< T, true >::VecFlat
VTKM_EXEC_CONT VecFlat(const T &src)
Definition: VecFlat.h:260
TypeTraits.h
vtkm::VecTraits::HasMultipleComponents
typename internal::VecTraitsMultipleComponentChooser< NUM_COMPONENTS >::Type HasMultipleComponents
A tag specifying whether this vector has multiple components (i.e.
Definition: VecTraits.h:98
vtkm::VecFlat< T, true >::operator=
VTKM_EXEC_CONT VecFlat & operator=(const T &src)
Definition: VecFlat.h:265
VTKM_STATIC_ASSERT_MSG
#define VTKM_STATIC_ASSERT_MSG(condition, message)
Definition: StaticAssert.h:18
vtkm::VecFlat
Treat a Vec or Vec-like object as a flat Vec.
Definition: VecFlat.h:224
vtkmNotUsed
#define vtkmNotUsed(parameter_name)
Simple macro to identify a parameter as unused.
Definition: ExportMacros.h:128
vtkm::VecFlat< T, false >::VecFlat
VTKM_EXEC_CONT VecFlat(const T &src)
Definition: VecFlat.h:236
vtkm::Vec
A short fixed-length array.
Definition: Types.h:767
vtkm::VecTraitsTagSizeStatic
A tag for vectors where the number of components are known at compile time.
Definition: VecTraits.h:34
StaticAssert.h
vtkm::make_VecFlat
VTKM_EXEC_CONT vtkm::VecFlat< T > make_VecFlat(const T &vec)
Converts a Vec-like object to a VecFlat.
Definition: VecFlat.h:281
vtkm::VecTraits::ComponentType
typename VecType::ComponentType ComponentType
Type of the components in the vector.
Definition: VecTraits.h:73
vtkm::VecFlat< T, false >::operator=
VTKM_EXEC_CONT VecFlat & operator=(const T &src)
Definition: VecFlat.h:238
vtkm::VecTraits
The VecTraits class gives several static members that define how to use a given type as a vector.
Definition: VecTraits.h:66
VecTraits.h