10 #ifndef vtk_m_cont_ArrayHandleMultiplexer_h
11 #define vtk_m_cont_ArrayHandleMultiplexer_h
34 struct ArrayPortalMultiplexerGetNumberOfValuesFunctor
36 template <
typename PortalType>
39 return portal.GetNumberOfValues();
43 struct ArrayPortalMultiplexerGetFunctor
46 template <
typename PortalType>
47 VTKM_EXEC_CONT typename PortalType::ValueType operator()(
const PortalType& portal,
50 return portal.Get(index);
54 struct ArrayPortalMultiplexerSetFunctor
56 template <
typename PortalType>
59 const typename PortalType::ValueType& value)
const noexcept
62 portal, index, value,
typename vtkm::internal::PortalSupportsSets<PortalType>::type{});
67 template <
typename PortalType>
70 const typename PortalType::ValueType& value,
71 std::true_type)
const noexcept
73 portal.Set(index, value);
77 template <
typename PortalType>
80 const typename PortalType::ValueType&,
81 std::false_type)
const noexcept
84 VTKM_ASSERT(
false &&
"Calling Set on a portal that does not support it.");
90 template <
typename... PortalTypes>
91 struct ArrayPortalMultiplexer
93 using PortalVariantType = vtkm::exec::Variant<PortalTypes...>;
94 PortalVariantType PortalVariant;
96 using ValueType =
typename PortalVariantType::template TypeAt<0>::ValueType;
98 ArrayPortalMultiplexer() =
default;
99 ~ArrayPortalMultiplexer() =
default;
100 ArrayPortalMultiplexer(ArrayPortalMultiplexer&&) =
default;
101 ArrayPortalMultiplexer(
const ArrayPortalMultiplexer&) =
default;
102 ArrayPortalMultiplexer& operator=(ArrayPortalMultiplexer&&) =
default;
103 ArrayPortalMultiplexer& operator=(
const ArrayPortalMultiplexer&) =
default;
105 template <
typename Portal>
111 template <
typename Portal>
112 VTKM_EXEC_CONT ArrayPortalMultiplexer& operator=(
const Portal& src) noexcept
114 this->PortalVariant = src;
120 return this->PortalVariant.CastAndCall(
121 detail::ArrayPortalMultiplexerGetNumberOfValuesFunctor{});
126 return this->PortalVariant.CastAndCall(detail::ArrayPortalMultiplexerGetFunctor{}, index);
131 this->PortalVariant.CastAndCall(detail::ArrayPortalMultiplexerSetFunctor{}, index, value);
140 template <
typename... StorageTags>
151 struct MultiplexerGetNumberOfValuesFunctor
153 template <
typename StorageType>
155 const std::vector<vtkm::cont::internal::Buffer>& buffers)
const
157 return StorageType::GetNumberOfValues(buffers);
161 struct MultiplexerResizeBuffersFunctor
163 template <
typename StorageType>
166 const std::vector<vtkm::cont::internal::Buffer>& buffers,
170 StorageType::ResizeBuffers(numValues, buffers, preserve, token);
174 struct MultiplexerFillFunctor
176 template <
typename ValueType,
typename StorageType>
178 const std::vector<vtkm::cont::internal::Buffer>& buffers,
179 const ValueType& fillValue,
184 StorageType::Fill(buffers, fillValue, startIndex, endIndex, token);
188 template <
typename ReadPortalType>
189 struct MultiplexerCreateReadPortalFunctor
191 template <
typename StorageType>
192 VTKM_CONT ReadPortalType operator()(StorageType,
193 const std::vector<vtkm::cont::internal::Buffer>& buffers,
197 return ReadPortalType(StorageType::CreateReadPortal(buffers, device, token));
201 template <
typename WritePortalType>
202 struct MultiplexerCreateWritePortalFunctor
204 template <
typename StorageType>
205 VTKM_CONT WritePortalType operator()(StorageType,
206 const std::vector<vtkm::cont::internal::Buffer>& buffers,
210 return WritePortalType(StorageType::CreateWritePortal(buffers, device, token));
214 template <
typename T,
typename... Ss>
215 struct MultiplexerArrayHandleVariantFunctor
217 using VariantType = vtkm::cont::Variant<vtkm::cont::ArrayHandle<T, Ss>...>;
219 template <
typename StorageTag>
220 VTKM_CONT VariantType operator()(vtkm::cont::internal::Storage<T, StorageTag>,
221 const std::vector<vtkm::cont::internal::Buffer>& buffers)
229 template <
typename ValueType,
typename... StorageTags>
230 class Storage<ValueType, StorageTagMultiplexer<StorageTags...>>
232 template <
typename S>
233 using StorageFor = vtkm::cont::internal::Storage<ValueType, S>;
235 using StorageVariant = vtkm::cont::Variant<StorageFor<StorageTags>...>;
237 VTKM_CONT static StorageVariant Variant(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
239 return buffers[0].GetMetaData<StorageVariant>();
242 VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> ArrayBuffers(
243 const std::vector<vtkm::cont::internal::Buffer>& buffers)
245 return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1, buffers.end());
249 using ReadPortalType =
250 vtkm::internal::ArrayPortalMultiplexer<typename StorageFor<StorageTags>::ReadPortalType...>;
251 using WritePortalType =
252 vtkm::internal::ArrayPortalMultiplexer<typename StorageFor<StorageTags>::WritePortalType...>;
255 const std::vector<vtkm::cont::internal::Buffer>& buffers)
257 return Variant(buffers).CastAndCall(detail::MultiplexerGetNumberOfValuesFunctor{},
258 ArrayBuffers(buffers));
262 const std::vector<vtkm::cont::internal::Buffer>& buffers,
266 Variant(buffers).CastAndCall(
267 detail::MultiplexerResizeBuffersFunctor{}, numValues, ArrayBuffers(buffers), preserve, token);
270 VTKM_CONT static void Fill(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
271 const ValueType& fillValue,
276 Variant(buffers).CastAndCall(detail::MultiplexerFillFunctor{},
277 ArrayBuffers(buffers),
284 VTKM_CONT static ReadPortalType CreateReadPortal(
285 const std::vector<vtkm::cont::internal::Buffer>& buffers,
289 return Variant(buffers).CastAndCall(
290 detail::MultiplexerCreateReadPortalFunctor<ReadPortalType>{},
291 ArrayBuffers(buffers),
296 VTKM_CONT static WritePortalType CreateWritePortal(
297 const std::vector<vtkm::cont::internal::Buffer>& buffers,
301 return Variant(buffers).CastAndCall(
302 detail::MultiplexerCreateWritePortalFunctor<WritePortalType>{},
303 ArrayBuffers(buffers),
308 VTKM_CONT static bool IsValid(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
310 return Variant(buffers).IsValid();
313 template <
typename ArrayType>
314 VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
const ArrayType& array)
317 return vtkm::cont::internal::CreateBuffers(StorageVariant{ array.GetStorage() }, array);
320 VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
322 return vtkm::cont::internal::CreateBuffers(StorageVariant{});
326 typename detail::MultiplexerArrayHandleVariantFunctor<ValueType, StorageTags...>::VariantType
327 GetArrayHandleVariant(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
329 return Variant(buffers).CastAndCall(
330 detail::MultiplexerArrayHandleVariantFunctor<ValueType, StorageTags...>{},
331 ArrayBuffers(buffers));
340 template <
typename... ArrayHandleTypes>
341 struct ArrayHandleMultiplexerTraits
345 using ValueType =
typename ArrayHandleType0::ValueType;
351 template <
typename ArrayHandle>
352 struct CheckArrayHandleTransform
355 VTKM_STATIC_ASSERT((std::is_same<ValueType, typename ArrayHandle::ValueType>::value));
364 template <
typename ArrayHandle>
365 struct ArrayHandleToStorageTagImpl
369 template <
typename ArrayHandle>
370 using ArrayHandleToStorageTag =
typename ArrayHandleToStorageTagImpl<ArrayHandle>::Type;
374 using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
397 template <
typename... ArrayHandleTypes>
400 typename detail::ArrayHandleMultiplexerTraits<ArrayHandleTypes...>::ValueType,
401 typename detail::ArrayHandleMultiplexerTraits<ArrayHandleTypes...>::StorageTag>
403 using Traits = detail::ArrayHandleMultiplexerTraits<ArrayHandleTypes...>;
412 using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
415 template <
typename RealStorageTag>
423 template <
typename S>
426 this->
SetBuffers(StorageType::CreateBuffers(src));
432 return StorageType::GetArrayHandleVariant(this->
GetBuffers());
442 template <
typename List>
451 struct ArrayExtractComponentMultiplexerFunctor
453 template <
typename ArrayType>
454 auto operator()(
const ArrayType& array,
459 return vtkm::cont::internal::ArrayExtractComponentImpl<typename ArrayType::StorageTag>{}(
460 array, componentIndex, allowCopy);
466 template <
typename... Ss>
469 template <
typename T>
476 return array.GetArrayHandleVariant().CastAndCall(
477 detail::ArrayExtractComponentMultiplexerFunctor{}, componentIndex, allowCopy);
487 #endif //vtk_m_cont_ArrayHandleMultiplexer_h