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