Viskores  1.0
VecFlat.h
Go to the documentation of this file.
1 //============================================================================
2 // The contents of this file are covered by the Viskores license. See
3 // LICENSE.txt for details.
4 //
5 // By contributing to this file, all contributors agree to the Developer
6 // Certificate of Origin Version 1.1 (DCO 1.1) as stated in DCO.txt.
7 //============================================================================
8 
9 //============================================================================
10 // Copyright (c) Kitware, Inc.
11 // All rights reserved.
12 // See LICENSE.txt for details.
13 //
14 // This software is distributed WITHOUT ANY WARRANTY; without even
15 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 // PURPOSE. See the above copyright notice for more information.
17 //============================================================================
18 #ifndef viskores_VecFlat_h
19 #define viskores_VecFlat_h
20 
21 #include <viskores/StaticAssert.h>
22 #include <viskores/TypeTraits.h>
23 #include <viskores/Types.h>
24 #include <viskores/VecTraits.h>
25 
26 namespace viskores
27 {
28 
29 namespace internal
30 {
31 
32 template <typename T,
33  typename MultipleComponents = typename viskores::VecTraits<T>::HasMultipleComponents>
34 struct TotalNumComponents;
35 
36 template <typename T>
37 struct TotalNumComponents<T, viskores::VecTraitsTagMultipleComponents>
38 {
40  (std::is_same<typename viskores::VecTraits<T>::IsSizeStatic,
42  "viskores::VecFlat can only be used with Vec types with a static number of components.");
43  using ComponentType = typename viskores::VecTraits<T>::ComponentType;
44  static constexpr viskores::IdComponent value =
45  viskores::VecTraits<T>::NUM_COMPONENTS * TotalNumComponents<ComponentType>::value;
46 };
47 
48 template <typename T>
49 struct TotalNumComponents<T, viskores::VecTraitsTagSingleComponent>
50 {
51  static constexpr viskores::IdComponent value = 1;
52 };
53 
54 template <typename T>
56  viskores::internal::TotalNumComponents<T>::value>;
57 
58 template <typename T>
59 using IsFlatVec = typename std::is_same<T, FlattenVec<T>>::type;
60 
61 namespace detail
62 {
63 
64 template <typename T>
65 VISKORES_EXEC_CONT T GetFlatVecComponentImpl(const T& component,
67  std::true_type viskoresNotUsed(isBase))
68 {
69  VISKORES_ASSERT(index == 0);
70  return component;
71 }
72 
73 template <typename T>
74 VISKORES_EXEC_CONT typename viskores::VecTraits<T>::BaseComponentType GetFlatVecComponentImpl(
75  const T& vec,
77  std::false_type viskoresNotUsed(isBase))
78 {
79  using Traits = viskores::VecTraits<T>;
80  using ComponentType = typename Traits::ComponentType;
81  using BaseComponentType = typename Traits::BaseComponentType;
82 
83  constexpr viskores::IdComponent subSize = TotalNumComponents<ComponentType>::value;
84  return GetFlatVecComponentImpl(Traits::GetComponent(vec, index / subSize),
85  index % subSize,
86  typename std::is_same<ComponentType, BaseComponentType>::type{});
87 }
88 
89 } // namespace detail
90 
91 template <typename T>
93  const T& vec,
95 {
96  return detail::GetFlatVecComponentImpl(vec, index, std::false_type{});
97 }
98 
99 namespace detail
100 {
101 
102 template <typename T, viskores::IdComponent N>
103 VISKORES_EXEC_CONT void CopyVecNestedToFlatImpl(T nestedVec,
104  viskores::Vec<T, N>& flatVec,
105  viskores::IdComponent flatOffset)
106 {
107  flatVec[flatOffset] = nestedVec;
108 }
109 
110 template <typename T, viskores::IdComponent NFlat, viskores::IdComponent NNest>
111 VISKORES_EXEC_CONT void CopyVecNestedToFlatImpl(const viskores::Vec<T, NNest>& nestedVec,
112  viskores::Vec<T, NFlat>& flatVec,
113  viskores::IdComponent flatOffset)
114 {
115  for (viskores::IdComponent nestedIndex = 0; nestedIndex < NNest; ++nestedIndex)
116  {
117  flatVec[nestedIndex + flatOffset] = nestedVec[nestedIndex];
118  }
119 }
120 
121 template <typename T, viskores::IdComponent N, typename NestedVecType>
122 VISKORES_EXEC_CONT void CopyVecNestedToFlatImpl(const NestedVecType& nestedVec,
123  viskores::Vec<T, N>& flatVec,
124  viskores::IdComponent flatOffset)
125 {
126  using Traits = viskores::VecTraits<NestedVecType>;
127  using ComponentType = typename Traits::ComponentType;
128  constexpr viskores::IdComponent subSize = TotalNumComponents<ComponentType>::value;
129 
130  viskores::IdComponent flatIndex = flatOffset;
131  for (viskores::IdComponent nestIndex = 0; nestIndex < Traits::NUM_COMPONENTS; ++nestIndex)
132  {
133  CopyVecNestedToFlatImpl(Traits::GetComponent(nestedVec, nestIndex), flatVec, flatIndex);
134  flatIndex += subSize;
135  }
136 }
137 
138 } // namespace detail
139 
140 template <typename T, viskores::IdComponent N, typename NestedVecType>
141 VISKORES_EXEC_CONT void CopyVecNestedToFlat(const NestedVecType& nestedVec,
142  viskores::Vec<T, N>& flatVec)
143 {
144  detail::CopyVecNestedToFlatImpl(nestedVec, flatVec, 0);
145 }
146 
147 namespace detail
148 {
149 
150 template <typename T, viskores::IdComponent N>
151 VISKORES_EXEC_CONT void CopyVecFlatToNestedImpl(const viskores::Vec<T, N>& flatVec,
152  viskores::IdComponent flatOffset,
153  T& nestedVec)
154 {
155  nestedVec = flatVec[flatOffset];
156 }
157 
158 template <typename T, viskores::IdComponent NFlat, viskores::IdComponent NNest>
159 VISKORES_EXEC_CONT void CopyVecFlatToNestedImpl(const viskores::Vec<T, NFlat>& flatVec,
160  viskores::IdComponent flatOffset,
161  viskores::Vec<T, NNest>& nestedVec)
162 {
163  for (viskores::IdComponent nestedIndex = 0; nestedIndex < NNest; ++nestedIndex)
164  {
165  nestedVec[nestedIndex] = flatVec[nestedIndex + flatOffset];
166  }
167 }
168 
169 template <typename T,
170  viskores::IdComponent NFlat,
171  typename ComponentType,
172  viskores::IdComponent NNest>
173 VISKORES_EXEC_CONT void CopyVecFlatToNestedImpl(const viskores::Vec<T, NFlat>& flatVec,
174  viskores::IdComponent flatOffset,
176 {
177  constexpr viskores::IdComponent subSize = TotalNumComponents<ComponentType>::value;
178 
179  viskores::IdComponent flatIndex = flatOffset;
180  for (viskores::IdComponent nestIndex = 0; nestIndex < NNest; ++nestIndex)
181  {
182  CopyVecFlatToNestedImpl(flatVec, flatIndex, nestedVec[nestIndex]);
183  flatIndex += subSize;
184  }
185 }
186 
187 template <typename T, viskores::IdComponent N, typename NestedVecType>
188 VISKORES_EXEC_CONT void CopyVecFlatToNestedImpl(const viskores::Vec<T, N>& flatVec,
189  viskores::IdComponent flatOffset,
190  NestedVecType& nestedVec)
191 {
192  using Traits = viskores::VecTraits<NestedVecType>;
193  using ComponentType = typename Traits::ComponentType;
194  constexpr viskores::IdComponent subSize = TotalNumComponents<ComponentType>::value;
195 
196  viskores::IdComponent flatIndex = flatOffset;
197  for (viskores::IdComponent nestIndex = 0; nestIndex < Traits::NUM_COMPONENTS; ++nestIndex)
198  {
199  ComponentType component;
200  CopyVecFlatToNestedImpl(flatVec, flatIndex, component);
201  Traits::SetComponent(nestedVec, nestIndex, component);
202  flatIndex += subSize;
203  }
204 }
205 
206 } // namespace detail
207 
208 template <typename T, viskores::IdComponent N, typename NestedVecType>
209 VISKORES_EXEC_CONT void CopyVecFlatToNested(const viskores::Vec<T, N>& flatVec,
210  NestedVecType& nestedVec)
211 {
212  detail::CopyVecFlatToNestedImpl(flatVec, 0, nestedVec);
213 }
214 
215 } // namespace internal
216 
239 template <typename T, bool = internal::IsFlatVec<T>::value>
240 class VecFlat;
241 
242 // Case where T is not a viskores::Vec<T, N> where T is not a Vec.
243 template <typename T>
244 class VecFlat<T, false> : public internal::FlattenVec<T>
245 {
247 
248 public:
249  using Superclass::Superclass;
250  VecFlat() = default;
251 
252  VISKORES_EXEC_CONT VecFlat(const T& src) { *this = src; }
253 
255  {
256  internal::CopyVecNestedToFlat(src, *this);
257  return *this;
258  }
259 
260  VISKORES_EXEC_CONT operator T() const
261  {
262  T nestedVec;
263  internal::CopyVecFlatToNested(*this, nestedVec);
264  return nestedVec;
265  }
266 };
267 
268 // Specialization of VecFlat where the Vec is already flat Vec
269 template <typename T>
270 class VecFlat<T, true> : public T
271 {
272 public:
273  using T::T;
274  VecFlat() = default;
275 
277  : T(src)
278  {
279  }
280 
282  {
283  this->T::operator=(src);
284  return *this;
285  }
286 
288  {
289  this->T::operator=(std::move(src));
290  return *this;
291  }
292 };
293 
296 template <typename T>
298 {
299  return viskores::VecFlat<T>(vec);
300 }
301 
302 template <typename T>
303 struct TypeTraits<viskores::VecFlat<T>> : TypeTraits<internal::FlattenVec<T>>
304 {
305 };
306 
307 template <typename T>
308 struct VecTraits<viskores::VecFlat<T>> : VecTraits<internal::FlattenVec<T>>
309 {
310 };
311 
312 } // namespace viskores
313 
314 #endif //viskores_VecFlat_h
viskores::VecFlat
Treat a Vec or Vec-like object as a flat Vec.
Definition: VecFlat.h:240
Types.h
viskores::Vec::Superclass
detail::VecBase< T, Size, Vec< T, Size > > Superclass
Definition: Types.h:819
viskores::VecTraitsTagSizeStatic
A tag for vectors where the number of components are known at compile time.
Definition: VecTraits.h:44
viskoresNotUsed
#define viskoresNotUsed(parameter_name)
Simple macro to identify a parameter as unused.
Definition: ExportMacros.h:136
viskores::VecTraitsTagSingleComponent
A tag for vectors that are really just scalars (i.e.
Definition: VecTraits.h:38
viskores::IdComponent
viskores::Int32 IdComponent
Base type to use to index small lists.
Definition: Types.h:202
VISKORES_EXEC_CONT
#define VISKORES_EXEC_CONT
Definition: ExportMacros.h:60
viskores::VecFlat< T, false >::operator=
VecFlat & operator=(const T &src)
Definition: VecFlat.h:254
viskores::VecFlat< T, false >::VecFlat
VecFlat(const T &src)
Definition: VecFlat.h:252
TypeTraits.h
viskores::TypeTraits
The TypeTraits class provides helpful compile-time information about the basic types used in Viskores...
Definition: TypeTraits.h:69
viskores
Groups connected points that have the same field value.
Definition: Atomic.h:27
viskores::VecTraits
Traits that can be queried to treat any type as a Vec.
Definition: VecTraits.h:69
VISKORES_ASSERT
#define VISKORES_ASSERT(condition)
Definition: Assert.h:51
VISKORES_STATIC_ASSERT_MSG
#define VISKORES_STATIC_ASSERT_MSG(condition, message)
Definition: StaticAssert.h:26
viskores::make_VecFlat
viskores::VecFlat< T > make_VecFlat(const T &vec)
Converts a Vec-like object to a VecFlat.
Definition: VecFlat.h:297
StaticAssert.h
viskores::VecTraits::ComponentType
T ComponentType
Type of the components in the vector.
Definition: VecTraits.h:79
viskores::VecFlat< T, true >::operator=
VecFlat & operator=(T &&src)
Definition: VecFlat.h:287
viskores::VecTraits::BaseComponentType
T BaseComponentType
Base component type in the vector.
Definition: VecTraits.h:86
viskores::VecFlat< T, true >::operator=
VecFlat & operator=(const T &src)
Definition: VecFlat.h:281
viskores::Vec
A short fixed-length array.
Definition: Types.h:365
viskores::VecFlat< T, true >::VecFlat
VecFlat(const T &src)
Definition: VecFlat.h:276
VecTraits.h