Viskores  1.0
ArrayHandleSwizzle.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_cont_ArrayHandleSwizzle_h
19 #define viskores_cont_ArrayHandleSwizzle_h
20 
22 
23 #include <viskores/VecTraits.h>
24 
25 #include <viskoresstd/integer_sequence.h>
26 
27 namespace viskores
28 {
29 namespace internal
30 {
31 
32 template <typename InType, typename OutType>
33 class SwizzleFunctor
34 {
35  using InTraits = viskores::VecTraits<InType>;
36  using InComponentType = typename InTraits::ComponentType;
37  static constexpr viskores::IdComponent NUM_IN_COMPONENTS = InTraits::NUM_COMPONENTS;
38 
39  using OutTraits = viskores::VecTraits<OutType>;
40  using OutComponentType = typename OutTraits::ComponentType;
41  static constexpr viskores::IdComponent NUM_OUT_COMPONENTS = OutTraits::NUM_COMPONENTS;
42 
43  template <viskores::IdComponent... Is>
44  using IndexSequence = viskoresstd::integer_sequence<viskores::IdComponent, Is...>;
45  using IndexList = viskoresstd::make_integer_sequence<viskores::IdComponent, NUM_OUT_COMPONENTS>;
46 
47 public:
49 
50  VISKORES_CONT SwizzleFunctor(const MapType& map)
51  : Map(map)
52  {
53  }
54 
55  VISKORES_CONT SwizzleFunctor() = default;
56 
57  VISKORES_EXEC_CONT OutType operator()(const InType& vec) const
58  {
59  return this->Swizzle(vec, IndexList{});
60  }
61 
62  VISKORES_CONT static MapType InitMap() { return IndexListAsMap(IndexList{}); }
63 
64 private:
65  template <viskores::IdComponent... Is>
66  VISKORES_CONT static MapType IndexListAsMap(IndexSequence<Is...>)
67  {
68  return { Is... };
69  }
70 
71  template <viskores::IdComponent... Is>
72  VISKORES_EXEC_CONT OutType Swizzle(const InType& vec, IndexSequence<Is...>) const
73  {
74  return { InTraits::GetComponent(vec, this->Map[Is])... };
75  }
76 
77  MapType Map = InitMap();
78 };
79 
80 namespace detail
81 {
82 
83 template <typename InType, typename OutType, typename Invertible>
84 struct GetInverseSwizzleImpl;
85 
86 template <typename InType, typename OutType>
87 struct GetInverseSwizzleImpl<InType, OutType, std::true_type>
88 {
89  using Type = viskores::internal::SwizzleFunctor<OutType, InType>;
90  template <typename ForwardMapType>
91  VISKORES_CONT static Type Value(const ForwardMapType& forwardMap)
92  {
93  // Note that when reversing the map, if the forwardMap repeats any indices, then
94  // the map is not 1:1 and is not invertible. We cannot check that at compile time.
95  // In this case, results can become unpredictible.
96  using InverseMapType = typename Type::MapType;
97  InverseMapType inverseMap = Type::InitMap();
98  for (viskores::IdComponent inIndex = 0; inIndex < ForwardMapType::NUM_COMPONENTS; ++inIndex)
99  {
100  inverseMap[forwardMap[inIndex]] = inIndex;
101  }
102 
103  return Type(inverseMap);
104  }
105 };
106 
107 template <typename InType, typename OutType>
108 struct GetInverseSwizzleImpl<InType, OutType, std::false_type>
109 {
110  using Type = viskores::cont::internal::NullFunctorType;
111  template <typename ForwardMapType>
112  VISKORES_CONT static Type Value(const ForwardMapType&)
113  {
114  return Type{};
115  }
116 };
117 
118 template <typename InType, typename OutType>
119 using SwizzleInvertible = std::integral_constant<bool,
122 
123 } // namespace detail
124 
125 template <typename InType, typename OutType>
126 VISKORES_CONT viskores::internal::SwizzleFunctor<InType, OutType> GetSwizzleFunctor(
128 {
129  return viskores::internal::SwizzleFunctor<InType, OutType>(forwardMap);
130 }
131 
132 template <typename InType, typename OutType>
133 using InverseSwizzleType = typename detail::
134  GetInverseSwizzleImpl<InType, OutType, detail::SwizzleInvertible<InType, OutType>>::Type;
135 
136 template <typename InType, typename OutType>
137 VISKORES_CONT InverseSwizzleType<InType, OutType> GetInverseSwizzleFunctor(
139 {
140  return detail::
141  GetInverseSwizzleImpl<InType, OutType, detail::SwizzleInvertible<InType, OutType>>::Value(
142  forwardMap);
143 }
144 
145 }
146 } // namespace viskores::internal
147 
148 namespace viskores
149 {
150 namespace cont
151 {
152 
153 namespace detail
154 {
155 
156 template <typename ArrayHandleType, viskores::IdComponent OutSize>
157 struct ArrayHandleSwizzleTraits
158 {
159  VISKORES_IS_ARRAY_HANDLE(ArrayHandleType);
160 
161  using InType = typename ArrayHandleType::ValueType;
163  using SwizzleFunctor = viskores::internal::SwizzleFunctor<InType, OutType>;
164  using InverseSwizzleFunctor = viskores::internal::InverseSwizzleType<InType, OutType>;
165  using MapType = typename SwizzleFunctor::MapType;
166 
167  static SwizzleFunctor GetFunctor(const MapType& forwardMap)
168  {
169  return viskores::internal::GetSwizzleFunctor<InType, OutType>(forwardMap);
170  }
171 
172  static InverseSwizzleFunctor GetInverseFunctor(const MapType& forwardMap)
173  {
174  return viskores::internal::GetInverseSwizzleFunctor<InType, OutType>(forwardMap);
175  }
176 
177  using Superclass =
179 };
180 
181 } // namespace detail
182 
200 template <typename ArrayHandleType, viskores::IdComponent OutSize>
202  : public detail::ArrayHandleSwizzleTraits<ArrayHandleType, OutSize>::Superclass
203 {
204  VISKORES_IS_ARRAY_HANDLE(ArrayHandleType);
205 
206  using Traits = detail::ArrayHandleSwizzleTraits<ArrayHandleType, OutSize>;
207 
208 public:
211  (typename Traits::Superclass));
212 
213  using MapType = typename Traits::MapType;
214 
220  VISKORES_CONT ArrayHandleSwizzle(const ArrayHandleType& array, const MapType& map)
221  : Superclass(array, Traits::GetFunctor(map), Traits::GetInverseFunctor(map))
222  {
223  }
224 };
225 
231 template <typename ArrayHandleType, viskores::IdComponent OutSize>
233  const ArrayHandleType& array,
235 {
237 }
238 
243 template <typename ArrayHandleType, typename... SwizzleIndexTypes>
244 VISKORES_CONT auto make_ArrayHandleSwizzle(const ArrayHandleType& array,
245  viskores::IdComponent swizzleIndex0,
246  SwizzleIndexTypes... swizzleIndices)
247 {
248  return make_ArrayHandleSwizzle(array, viskores::make_Vec(swizzleIndex0, swizzleIndices...));
249 }
250 }
251 } // namespace viskores::cont
252 
253 //=============================================================================
254 // Specializations of serialization related classes
256 namespace viskores
257 {
258 namespace cont
259 {
260 
261 template <typename InType, typename OutType>
262 struct SerializableTypeString<viskores::internal::SwizzleFunctor<InType, OutType>>
263 {
264  static VISKORES_CONT const std::string& Get()
265  {
266  static std::string name = "Swizzle<" + SerializableTypeString<InType>::Get() + "," +
268  return name;
269  }
270 };
271 
272 template <typename AH, viskores::IdComponent NComps>
273 struct SerializableTypeString<viskores::cont::ArrayHandleSwizzle<AH, NComps>>
274  : SerializableTypeString<typename viskores::cont::ArrayHandleSwizzle<AH, NComps>::Superclass>
275 {
276 };
277 }
278 } // viskores::cont
279 
280 namespace mangled_diy_namespace
281 {
282 
283 template <typename AH, viskores::IdComponent NComps>
284 struct Serialization<viskores::cont::ArrayHandleSwizzle<AH, NComps>>
285  : Serialization<typename viskores::cont::ArrayHandleSwizzle<AH, NComps>::Superclass>
286 {
287 };
288 
289 } // diy
291 
292 #endif // viskores_cont_ArrayHandleSwizzle_h
viskores::cont::ArrayHandleTransform::GetInverseFunctor
InverseFunctorType GetInverseFunctor() const
Returns the inverse functor transforming the ArrayHandle
Definition: ArrayHandleTransform.h:544
viskores::cont::ArrayHandleTransform::GetFunctor
FunctorType GetFunctor() const
Returns the functor transforming the ArrayHandle.
Definition: ArrayHandleTransform.h:540
VISKORES_IS_ARRAY_HANDLE
#define VISKORES_IS_ARRAY_HANDLE(T)
Checks that the given type is a viskores::cont::ArrayHandle.
Definition: ArrayHandle.h:145
ArrayHandleTransform.h
viskores::cont::ArrayHandleSwizzle::MapType
typename Traits::MapType MapType
Definition: ArrayHandleSwizzle.h:213
viskores::cont::ArrayHandleSwizzle::ArrayHandleSwizzle
ArrayHandleSwizzle(const ArrayHandleType &array, const MapType &map)
Construct an ArrayHandleSwizzle with a source array and a swizzle map.
Definition: ArrayHandleSwizzle.h:220
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
mangled_diy_namespace
Definition: Particle.h:373
viskores::VecTraits::GetComponent
static const ComponentType & GetComponent(const T &vector, viskores::IdComponent)
Returns the value in a given component of the vector.
Definition: VecTraits.h:125
viskores::cont::ArrayHandleSwizzle::Traits
detail::ArrayHandleSwizzleTraits< ArrayHandleType, OutSize > Traits
Definition: ArrayHandleSwizzle.h:206
VISKORES_CONT
#define VISKORES_CONT
Definition: ExportMacros.h:65
viskores
Groups connected points that have the same field value.
Definition: Atomic.h:27
viskores::VecTraits::NUM_COMPONENTS
static constexpr viskores::IdComponent NUM_COMPONENTS
Number of components in the vector.
Definition: VecTraits.h:93
viskores::VecTraits
Traits that can be queried to treat any type as a Vec.
Definition: VecTraits.h:69
viskores::cont::ArrayHandleSwizzle::Superclass
typename viskores::cont::detail::GetTypeInParentheses< void(typename Traits::Superclass) >::type Superclass
Definition: ArrayHandleSwizzle.h:211
viskores::cont::ArrayHandleSwizzle
Swizzle the components of the values in an ArrayHandle.
Definition: ArrayHandleSwizzle.h:201
viskores::make_Vec
constexpr viskores::Vec< T, viskores::IdComponent(sizeof...(Ts)+1)> make_Vec(T value0, Ts &&... args)
Initializes and returns a Vec containing all the arguments.
Definition: Types.h:1262
VISKORES_ARRAY_HANDLE_SUBCLASS
#define VISKORES_ARRAY_HANDLE_SUBCLASS(classname, fullclasstype, superclass)
Macro to make default methods in ArrayHandle subclasses.
Definition: ArrayHandle.h:256
viskores::VecTraits::ComponentType
T ComponentType
Type of the components in the vector.
Definition: VecTraits.h:79
viskores::Get
auto Get(const viskores::Tuple< Ts... > &tuple)
Retrieve the object from a viskores::Tuple at the given index.
Definition: Tuple.h:89
viskores::cont::ArrayHandleTransform
Implicitly transform values of one array to another with a functor.
Definition: ArrayHandleTransform.h:461
viskores::cont::make_ArrayHandleSwizzle
ArrayHandleSwizzle< ArrayHandleType, OutSize > make_ArrayHandleSwizzle(const ArrayHandleType &array, const viskores::Vec< viskores::IdComponent, OutSize > &map)
Construct an ArrayHandleSwizzle from a provided array and swizzle map.
Definition: ArrayHandleSwizzle.h:232
viskores::Vec
A short fixed-length array.
Definition: Types.h:365
VecTraits.h