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 MultiplexerGetNumberOfComponentsFlatFunctor
153 template <
typename StorageType>
156 const std::vector<vtkm::cont::internal::Buffer>& buffers)
const
158 return StorageType::GetNumberOfComponentsFlat(buffers);
162 struct MultiplexerGetNumberOfValuesFunctor
164 template <
typename StorageType>
166 const std::vector<vtkm::cont::internal::Buffer>& buffers)
const
168 return StorageType::GetNumberOfValues(buffers);
172 struct MultiplexerResizeBuffersFunctor
174 template <
typename StorageType>
177 const std::vector<vtkm::cont::internal::Buffer>& buffers,
181 StorageType::ResizeBuffers(numValues, buffers, preserve, token);
185 struct MultiplexerFillFunctor
187 template <
typename ValueType,
typename StorageType>
189 const std::vector<vtkm::cont::internal::Buffer>& buffers,
190 const ValueType& fillValue,
195 StorageType::Fill(buffers, fillValue, startIndex, endIndex, token);
199 template <
typename ReadPortalType>
200 struct MultiplexerCreateReadPortalFunctor
202 template <
typename StorageType>
203 VTKM_CONT ReadPortalType operator()(StorageType,
204 const std::vector<vtkm::cont::internal::Buffer>& buffers,
208 return ReadPortalType(StorageType::CreateReadPortal(buffers, device, token));
212 template <
typename WritePortalType>
213 struct MultiplexerCreateWritePortalFunctor
215 template <
typename StorageType>
216 VTKM_CONT WritePortalType operator()(StorageType,
217 const std::vector<vtkm::cont::internal::Buffer>& buffers,
221 return WritePortalType(StorageType::CreateWritePortal(buffers, device, token));
225 template <
typename T,
typename... Ss>
226 struct MultiplexerArrayHandleVariantFunctor
228 using VariantType = vtkm::cont::Variant<vtkm::cont::ArrayHandle<T, Ss>...>;
230 template <
typename StorageTag>
231 VTKM_CONT VariantType operator()(vtkm::cont::internal::Storage<T, StorageTag>,
232 const std::vector<vtkm::cont::internal::Buffer>& buffers)
240 template <
typename ValueType,
typename... StorageTags>
241 class Storage<ValueType, StorageTagMultiplexer<StorageTags...>>
243 template <
typename S>
244 using StorageFor = vtkm::cont::internal::Storage<ValueType, S>;
246 using StorageVariant = vtkm::cont::Variant<StorageFor<StorageTags>...>;
248 VTKM_CONT static StorageVariant Variant(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
250 return buffers[0].GetMetaData<StorageVariant>();
253 VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> ArrayBuffers(
254 const std::vector<vtkm::cont::internal::Buffer>& buffers)
256 return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1, buffers.end());
260 using ReadPortalType =
261 vtkm::internal::ArrayPortalMultiplexer<typename StorageFor<StorageTags>::ReadPortalType...>;
262 using WritePortalType =
263 vtkm::internal::ArrayPortalMultiplexer<typename StorageFor<StorageTags>::WritePortalType...>;
266 const std::vector<vtkm::cont::internal::Buffer>& buffers)
268 return Variant(buffers).CastAndCall(detail::MultiplexerGetNumberOfComponentsFlatFunctor{},
269 ArrayBuffers(buffers));
273 const std::vector<vtkm::cont::internal::Buffer>& buffers)
275 return Variant(buffers).CastAndCall(detail::MultiplexerGetNumberOfValuesFunctor{},
276 ArrayBuffers(buffers));
280 const std::vector<vtkm::cont::internal::Buffer>& buffers,
284 Variant(buffers).CastAndCall(
285 detail::MultiplexerResizeBuffersFunctor{}, numValues, ArrayBuffers(buffers), preserve, token);
288 VTKM_CONT static void Fill(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
289 const ValueType& fillValue,
294 Variant(buffers).CastAndCall(detail::MultiplexerFillFunctor{},
295 ArrayBuffers(buffers),
302 VTKM_CONT static ReadPortalType CreateReadPortal(
303 const std::vector<vtkm::cont::internal::Buffer>& buffers,
307 return Variant(buffers).CastAndCall(
308 detail::MultiplexerCreateReadPortalFunctor<ReadPortalType>{},
309 ArrayBuffers(buffers),
314 VTKM_CONT static WritePortalType CreateWritePortal(
315 const std::vector<vtkm::cont::internal::Buffer>& buffers,
319 return Variant(buffers).CastAndCall(
320 detail::MultiplexerCreateWritePortalFunctor<WritePortalType>{},
321 ArrayBuffers(buffers),
326 VTKM_CONT static bool IsValid(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
328 return Variant(buffers).IsValid();
331 template <
typename ArrayType>
332 VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
const ArrayType& array)
335 return vtkm::cont::internal::CreateBuffers(StorageVariant{ array.GetStorage() }, array);
338 VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
340 return vtkm::cont::internal::CreateBuffers(StorageVariant{});
344 typename detail::MultiplexerArrayHandleVariantFunctor<ValueType, StorageTags...>::VariantType
345 GetArrayHandleVariant(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
347 return Variant(buffers).CastAndCall(
348 detail::MultiplexerArrayHandleVariantFunctor<ValueType, StorageTags...>{},
349 ArrayBuffers(buffers));
358 template <
typename... ArrayHandleTypes>
359 struct ArrayHandleMultiplexerTraits
363 using ValueType =
typename ArrayHandleType0::ValueType;
369 template <
typename ArrayHandle>
370 struct CheckArrayHandleTransform
373 VTKM_STATIC_ASSERT((std::is_same<ValueType, typename ArrayHandle::ValueType>::value));
382 template <
typename ArrayHandle>
383 struct ArrayHandleToStorageTagImpl
387 template <
typename ArrayHandle>
388 using ArrayHandleToStorageTag =
typename ArrayHandleToStorageTagImpl<ArrayHandle>::Type;
392 using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
415 template <
typename... ArrayHandleTypes>
418 typename detail::ArrayHandleMultiplexerTraits<ArrayHandleTypes...>::ValueType,
419 typename detail::ArrayHandleMultiplexerTraits<ArrayHandleTypes...>::StorageTag>
421 using Traits = detail::ArrayHandleMultiplexerTraits<ArrayHandleTypes...>;
429 template <
typename RealStorageTag>
437 template <
typename S>
440 this->
SetBuffers(StorageType::CreateBuffers(src));
446 return StorageType::GetArrayHandleVariant(this->
GetBuffers());
456 template <
typename List>
465 struct ArrayExtractComponentMultiplexerFunctor
467 template <
typename ArrayType>
468 auto operator()(
const ArrayType& array,
473 return vtkm::cont::internal::ArrayExtractComponentImpl<typename ArrayType::StorageTag>{}(
474 array, componentIndex, allowCopy);
480 template <
typename... Ss>
483 template <
typename T>
490 return array.GetArrayHandleVariant().CastAndCall(
491 detail::ArrayExtractComponentMultiplexerFunctor{}, componentIndex, allowCopy);
501 #endif //vtk_m_cont_ArrayHandleMultiplexer_h