18 #ifndef viskores_cont_ArrayHandleMultiplexer_h
19 #define viskores_cont_ArrayHandleMultiplexer_h
42 struct ArrayPortalMultiplexerGetNumberOfValuesFunctor
44 template <
typename PortalType>
47 return portal.GetNumberOfValues();
51 struct ArrayPortalMultiplexerGetFunctor
54 template <
typename PortalType>
58 return portal.Get(index);
62 struct ArrayPortalMultiplexerSetFunctor
64 template <
typename PortalType>
67 const typename PortalType::ValueType& value)
const noexcept
70 portal, index, value,
typename viskores::internal::PortalSupportsSets<PortalType>::type{});
75 template <
typename PortalType>
78 const typename PortalType::ValueType& value,
79 std::true_type)
const noexcept
81 portal.Set(index, value);
85 template <
typename PortalType>
88 const typename PortalType::ValueType&,
89 std::false_type)
const noexcept
92 VISKORES_ASSERT(
false &&
"Calling Set on a portal that does not support it.");
98 template <
typename... PortalTypes>
99 struct ArrayPortalMultiplexer
101 using PortalVariantType = viskores::exec::Variant<PortalTypes...>;
102 PortalVariantType PortalVariant;
104 using ValueType =
typename PortalVariantType::template TypeAt<0>::ValueType;
106 ArrayPortalMultiplexer() =
default;
107 ~ArrayPortalMultiplexer() =
default;
108 ArrayPortalMultiplexer(ArrayPortalMultiplexer&&) =
default;
109 ArrayPortalMultiplexer(
const ArrayPortalMultiplexer&) =
default;
110 ArrayPortalMultiplexer& operator=(ArrayPortalMultiplexer&&) =
default;
111 ArrayPortalMultiplexer& operator=(
const ArrayPortalMultiplexer&) =
default;
113 template <
typename Portal>
119 template <
typename Portal>
122 this->PortalVariant = src;
128 return this->PortalVariant.CastAndCall(
129 detail::ArrayPortalMultiplexerGetNumberOfValuesFunctor{});
134 return this->PortalVariant.CastAndCall(detail::ArrayPortalMultiplexerGetFunctor{}, index);
139 this->PortalVariant.CastAndCall(detail::ArrayPortalMultiplexerSetFunctor{}, index, value);
148 template <
typename... StorageTags>
159 struct MultiplexerGetNumberOfComponentsFlatFunctor
161 template <
typename StorageType>
164 const std::vector<viskores::cont::internal::Buffer>& buffers)
const
166 return StorageType::GetNumberOfComponentsFlat(buffers);
170 struct MultiplexerGetNumberOfValuesFunctor
172 template <
typename StorageType>
175 const std::vector<viskores::cont::internal::Buffer>& buffers)
const
177 return StorageType::GetNumberOfValues(buffers);
181 struct MultiplexerResizeBuffersFunctor
183 template <
typename StorageType>
186 const std::vector<viskores::cont::internal::Buffer>& buffers,
190 StorageType::ResizeBuffers(numValues, buffers, preserve, token);
194 struct MultiplexerFillFunctor
196 template <
typename ValueType,
typename StorageType>
198 const std::vector<viskores::cont::internal::Buffer>& buffers,
199 const ValueType& fillValue,
204 StorageType::Fill(buffers, fillValue, startIndex, endIndex, token);
208 template <
typename ReadPortalType>
209 struct MultiplexerCreateReadPortalFunctor
211 template <
typename StorageType>
213 operator()(StorageType,
214 const std::vector<viskores::cont::internal::Buffer>& buffers,
218 return ReadPortalType(StorageType::CreateReadPortal(buffers, device, token));
222 template <
typename WritePortalType>
223 struct MultiplexerCreateWritePortalFunctor
225 template <
typename StorageType>
227 operator()(StorageType,
228 const std::vector<viskores::cont::internal::Buffer>& buffers,
232 return WritePortalType(StorageType::CreateWritePortal(buffers, device, token));
236 template <
typename T,
typename... Ss>
237 struct MultiplexerArrayHandleVariantFunctor
239 using VariantType = viskores::cont::Variant<viskores::cont::ArrayHandle<T, Ss>...>;
241 template <
typename StorageTag>
242 VISKORES_CONT VariantType operator()(viskores::cont::internal::Storage<T, StorageTag>,
243 const std::vector<viskores::cont::internal::Buffer>& buffers)
251 template <
typename ValueType,
typename... StorageTags>
252 class Storage<ValueType, StorageTagMultiplexer<StorageTags...>>
254 template <
typename S>
255 using StorageFor = viskores::cont::internal::Storage<ValueType, S>;
257 using StorageVariant = viskores::cont::Variant<StorageFor<StorageTags>...>;
260 const std::vector<viskores::cont::internal::Buffer>& buffers)
262 return buffers[0].GetMetaData<StorageVariant>();
265 VISKORES_CONT static std::vector<viskores::cont::internal::Buffer> ArrayBuffers(
266 const std::vector<viskores::cont::internal::Buffer>& buffers)
268 return std::vector<viskores::cont::internal::Buffer>(buffers.begin() + 1, buffers.end());
272 using ReadPortalType =
273 viskores::internal::ArrayPortalMultiplexer<typename StorageFor<StorageTags>::ReadPortalType...>;
274 using WritePortalType = viskores::internal::ArrayPortalMultiplexer<
275 typename StorageFor<StorageTags>::WritePortalType...>;
278 const std::vector<viskores::cont::internal::Buffer>& buffers)
280 return Variant(buffers).CastAndCall(detail::MultiplexerGetNumberOfComponentsFlatFunctor{},
281 ArrayBuffers(buffers));
285 const std::vector<viskores::cont::internal::Buffer>& buffers)
287 return Variant(buffers).CastAndCall(detail::MultiplexerGetNumberOfValuesFunctor{},
288 ArrayBuffers(buffers));
293 const std::vector<viskores::cont::internal::Buffer>& buffers,
297 Variant(buffers).CastAndCall(
298 detail::MultiplexerResizeBuffersFunctor{}, numValues, ArrayBuffers(buffers), preserve, token);
301 VISKORES_CONT static void Fill(
const std::vector<viskores::cont::internal::Buffer>& buffers,
302 const ValueType& fillValue,
307 Variant(buffers).CastAndCall(detail::MultiplexerFillFunctor{},
308 ArrayBuffers(buffers),
316 const std::vector<viskores::cont::internal::Buffer>& buffers,
320 return Variant(buffers).CastAndCall(
321 detail::MultiplexerCreateReadPortalFunctor<ReadPortalType>{},
322 ArrayBuffers(buffers),
328 const std::vector<viskores::cont::internal::Buffer>& buffers,
332 return Variant(buffers).CastAndCall(
333 detail::MultiplexerCreateWritePortalFunctor<WritePortalType>{},
334 ArrayBuffers(buffers),
339 VISKORES_CONT static bool IsValid(
const std::vector<viskores::cont::internal::Buffer>& buffers)
341 return Variant(buffers).IsValid();
344 template <
typename ArrayType>
345 VISKORES_CONT static std::vector<viskores::cont::internal::Buffer> CreateBuffers(
346 const ArrayType& array)
349 return viskores::cont::internal::CreateBuffers(StorageVariant{ array.GetStorage() }, array);
352 VISKORES_CONT static std::vector<viskores::cont::internal::Buffer> CreateBuffers()
354 return viskores::cont::internal::CreateBuffers(StorageVariant{});
358 typename detail::MultiplexerArrayHandleVariantFunctor<ValueType, StorageTags...>::VariantType
359 GetArrayHandleVariant(
const std::vector<viskores::cont::internal::Buffer>& buffers)
361 return Variant(buffers).CastAndCall(
362 detail::MultiplexerArrayHandleVariantFunctor<ValueType, StorageTags...>{},
363 ArrayBuffers(buffers));
372 template <
typename... ArrayHandleTypes>
373 struct ArrayHandleMultiplexerTraits
377 using ValueType =
typename ArrayHandleType0::ValueType;
383 template <
typename ArrayHandle>
384 struct CheckArrayHandleTransform
396 template <
typename ArrayHandle>
397 struct ArrayHandleToStorageTagImpl
401 template <
typename ArrayHandle>
402 using ArrayHandleToStorageTag =
typename ArrayHandleToStorageTagImpl<ArrayHandle>::Type;
406 using StorageType = viskores::cont::internal::Storage<ValueType, StorageTag>;
429 template <
typename... ArrayHandleTypes>
432 typename detail::ArrayHandleMultiplexerTraits<ArrayHandleTypes...>::ValueType,
433 typename detail::ArrayHandleMultiplexerTraits<ArrayHandleTypes...>::StorageTag>
435 using Traits = detail::ArrayHandleMultiplexerTraits<ArrayHandleTypes...>;
443 template <
typename RealStorageTag>
452 template <
typename S>
455 this->
SetBuffers(StorageType::CreateBuffers(src));
461 return StorageType::GetArrayHandleVariant(this->
GetBuffers());
471 template <
typename List>
480 struct ArrayExtractComponentMultiplexerFunctor
482 template <
typename ArrayType>
483 auto operator()(
const ArrayType& array,
488 return viskores::cont::internal::ArrayExtractComponentImpl<typename ArrayType::StorageTag>{}(
489 array, componentIndex, allowCopy);
495 template <
typename... Ss>
498 template <
typename T>
505 return array.GetArrayHandleVariant().CastAndCall(
506 detail::ArrayExtractComponentMultiplexerFunctor{}, componentIndex, allowCopy);
516 #endif //viskores_cont_ArrayHandleMultiplexer_h