2019-07-15 04:51:28 +00:00
|
|
|
//============================================================================
|
|
|
|
// Copyright (c) Kitware, Inc.
|
|
|
|
// All rights reserved.
|
|
|
|
// See LICENSE.txt for details.
|
|
|
|
//
|
|
|
|
// This software is distributed WITHOUT ANY WARRANTY; without even
|
|
|
|
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
|
|
// PURPOSE. See the above copyright notice for more information.
|
|
|
|
//============================================================================
|
|
|
|
#ifndef vtk_m_cont_ArrayHandleMultiplexer_h
|
|
|
|
#define vtk_m_cont_ArrayHandleMultiplexer_h
|
|
|
|
|
2019-10-25 05:16:57 +00:00
|
|
|
#include <vtkm/Assert.h>
|
2019-07-15 04:51:28 +00:00
|
|
|
#include <vtkm/TypeTraits.h>
|
|
|
|
|
2020-09-10 23:54:12 +00:00
|
|
|
#include <vtkm/cont/ArrayExtractComponent.h>
|
2019-07-15 04:51:28 +00:00
|
|
|
#include <vtkm/cont/ArrayHandle.h>
|
|
|
|
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
|
|
|
|
#include <vtkm/cont/ArrayHandleCast.h>
|
|
|
|
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
|
|
|
|
|
2022-11-01 13:52:41 +00:00
|
|
|
#include <vtkm/cont/Variant.h>
|
|
|
|
#include <vtkm/exec/Variant.h>
|
2020-10-06 21:57:04 +00:00
|
|
|
|
2019-07-15 04:51:28 +00:00
|
|
|
namespace vtkm
|
|
|
|
{
|
|
|
|
|
|
|
|
namespace internal
|
|
|
|
{
|
|
|
|
|
|
|
|
namespace detail
|
|
|
|
{
|
|
|
|
|
|
|
|
struct ArrayPortalMultiplexerGetNumberOfValuesFunctor
|
|
|
|
{
|
|
|
|
template <typename PortalType>
|
2019-07-25 21:25:29 +00:00
|
|
|
VTKM_EXEC_CONT vtkm::Id operator()(const PortalType& portal) const noexcept
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
|
|
|
return portal.GetNumberOfValues();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ArrayPortalMultiplexerGetFunctor
|
|
|
|
{
|
2019-09-10 00:33:38 +00:00
|
|
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
2019-07-15 04:51:28 +00:00
|
|
|
template <typename PortalType>
|
|
|
|
VTKM_EXEC_CONT typename PortalType::ValueType operator()(const PortalType& portal,
|
2019-07-25 21:25:29 +00:00
|
|
|
vtkm::Id index) const noexcept
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
|
|
|
return portal.Get(index);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ArrayPortalMultiplexerSetFunctor
|
|
|
|
{
|
|
|
|
template <typename PortalType>
|
|
|
|
VTKM_EXEC_CONT void operator()(const PortalType& portal,
|
|
|
|
vtkm::Id index,
|
2019-07-25 21:25:29 +00:00
|
|
|
const typename PortalType::ValueType& value) const noexcept
|
2019-10-25 05:16:57 +00:00
|
|
|
{
|
|
|
|
this->DoSet(
|
|
|
|
portal, index, value, typename vtkm::internal::PortalSupportsSets<PortalType>::type{});
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
|
|
|
template <typename PortalType>
|
|
|
|
VTKM_EXEC_CONT void DoSet(const PortalType& portal,
|
|
|
|
vtkm::Id index,
|
|
|
|
const typename PortalType::ValueType& value,
|
|
|
|
std::true_type) const noexcept
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
|
|
|
portal.Set(index, value);
|
|
|
|
}
|
2019-10-25 05:16:57 +00:00
|
|
|
|
|
|
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
|
|
|
template <typename PortalType>
|
|
|
|
VTKM_EXEC_CONT void DoSet(const PortalType&,
|
|
|
|
vtkm::Id,
|
|
|
|
const typename PortalType::ValueType&,
|
|
|
|
std::false_type) const noexcept
|
|
|
|
{
|
|
|
|
// This is an error but whatever.
|
|
|
|
VTKM_ASSERT(false && "Calling Set on a portal that does not support it.");
|
|
|
|
}
|
2019-07-15 04:51:28 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace detail
|
|
|
|
|
|
|
|
template <typename... PortalTypes>
|
|
|
|
struct ArrayPortalMultiplexer
|
|
|
|
{
|
2022-11-01 13:52:41 +00:00
|
|
|
using PortalVariantType = vtkm::exec::Variant<PortalTypes...>;
|
2019-07-15 04:51:28 +00:00
|
|
|
PortalVariantType PortalVariant;
|
|
|
|
|
|
|
|
using ValueType = typename PortalVariantType::template TypeAt<0>::ValueType;
|
|
|
|
|
2019-07-16 21:41:27 +00:00
|
|
|
ArrayPortalMultiplexer() = default;
|
|
|
|
~ArrayPortalMultiplexer() = default;
|
|
|
|
ArrayPortalMultiplexer(ArrayPortalMultiplexer&&) = default;
|
|
|
|
ArrayPortalMultiplexer(const ArrayPortalMultiplexer&) = default;
|
|
|
|
ArrayPortalMultiplexer& operator=(ArrayPortalMultiplexer&&) = default;
|
|
|
|
ArrayPortalMultiplexer& operator=(const ArrayPortalMultiplexer&) = default;
|
2019-07-15 04:51:28 +00:00
|
|
|
|
|
|
|
template <typename Portal>
|
2020-08-17 14:18:24 +00:00
|
|
|
VTKM_EXEC_CONT ArrayPortalMultiplexer(const Portal& src) noexcept
|
|
|
|
: PortalVariant(src)
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename Portal>
|
2019-07-25 21:25:29 +00:00
|
|
|
VTKM_EXEC_CONT ArrayPortalMultiplexer& operator=(const Portal& src) noexcept
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
|
|
|
this->PortalVariant = src;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2019-07-25 21:25:29 +00:00
|
|
|
VTKM_EXEC_CONT vtkm::Id GetNumberOfValues() const noexcept
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
|
|
|
return this->PortalVariant.CastAndCall(
|
|
|
|
detail::ArrayPortalMultiplexerGetNumberOfValuesFunctor{});
|
|
|
|
}
|
|
|
|
|
2019-07-25 21:25:29 +00:00
|
|
|
VTKM_EXEC_CONT ValueType Get(vtkm::Id index) const noexcept
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
|
|
|
return this->PortalVariant.CastAndCall(detail::ArrayPortalMultiplexerGetFunctor{}, index);
|
|
|
|
}
|
|
|
|
|
2019-07-25 21:25:29 +00:00
|
|
|
VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const noexcept
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
|
|
|
this->PortalVariant.CastAndCall(detail::ArrayPortalMultiplexerSetFunctor{}, index, value);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace internal
|
|
|
|
|
|
|
|
namespace cont
|
|
|
|
{
|
|
|
|
|
|
|
|
template <typename... StorageTags>
|
|
|
|
struct StorageTagMultiplexer
|
|
|
|
{
|
|
|
|
};
|
|
|
|
|
|
|
|
namespace internal
|
|
|
|
{
|
|
|
|
|
|
|
|
namespace detail
|
|
|
|
{
|
|
|
|
|
2023-10-03 14:31:38 +00:00
|
|
|
struct MultiplexerGetNumberOfComponentsFlatFunctor
|
|
|
|
{
|
|
|
|
template <typename StorageType>
|
|
|
|
VTKM_CONT vtkm::IdComponent operator()(
|
|
|
|
StorageType,
|
|
|
|
const std::vector<vtkm::cont::internal::Buffer>& buffers) const
|
|
|
|
{
|
|
|
|
return StorageType::GetNumberOfComponentsFlat(buffers);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-07-15 04:51:28 +00:00
|
|
|
struct MultiplexerGetNumberOfValuesFunctor
|
|
|
|
{
|
2020-11-23 19:16:47 +00:00
|
|
|
template <typename StorageType>
|
2022-06-28 20:26:38 +00:00
|
|
|
VTKM_CONT vtkm::Id operator()(StorageType,
|
|
|
|
const std::vector<vtkm::cont::internal::Buffer>& buffers) const
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
2020-11-23 19:16:47 +00:00
|
|
|
return StorageType::GetNumberOfValues(buffers);
|
2019-07-15 04:51:28 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-11-23 19:16:47 +00:00
|
|
|
struct MultiplexerResizeBuffersFunctor
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
2020-11-23 19:16:47 +00:00
|
|
|
template <typename StorageType>
|
|
|
|
VTKM_CONT void operator()(StorageType,
|
|
|
|
vtkm::Id numValues,
|
2022-06-28 20:26:38 +00:00
|
|
|
const std::vector<vtkm::cont::internal::Buffer>& buffers,
|
2020-11-23 19:16:47 +00:00
|
|
|
vtkm::CopyFlag preserve,
|
|
|
|
vtkm::cont::Token& token) const
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
2020-11-23 19:16:47 +00:00
|
|
|
StorageType::ResizeBuffers(numValues, buffers, preserve, token);
|
2019-07-15 04:51:28 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-01-04 16:29:12 +00:00
|
|
|
struct MultiplexerFillFunctor
|
|
|
|
{
|
|
|
|
template <typename ValueType, typename StorageType>
|
|
|
|
VTKM_CONT void operator()(StorageType,
|
2022-06-28 20:26:38 +00:00
|
|
|
const std::vector<vtkm::cont::internal::Buffer>& buffers,
|
2022-01-04 16:29:12 +00:00
|
|
|
const ValueType& fillValue,
|
|
|
|
vtkm::Id startIndex,
|
2022-01-11 14:15:41 +00:00
|
|
|
vtkm::Id endIndex,
|
2022-01-04 16:29:12 +00:00
|
|
|
vtkm::cont::Token& token) const
|
|
|
|
{
|
2022-01-11 14:15:41 +00:00
|
|
|
StorageType::Fill(buffers, fillValue, startIndex, endIndex, token);
|
2022-01-04 16:29:12 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-11-23 19:16:47 +00:00
|
|
|
template <typename ReadPortalType>
|
|
|
|
struct MultiplexerCreateReadPortalFunctor
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
2020-11-23 19:16:47 +00:00
|
|
|
template <typename StorageType>
|
|
|
|
VTKM_CONT ReadPortalType operator()(StorageType,
|
2022-06-28 20:26:38 +00:00
|
|
|
const std::vector<vtkm::cont::internal::Buffer>& buffers,
|
2020-11-23 19:16:47 +00:00
|
|
|
vtkm::cont::DeviceAdapterId device,
|
|
|
|
vtkm::cont::Token& token) const
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
2020-11-23 19:16:47 +00:00
|
|
|
return ReadPortalType(StorageType::CreateReadPortal(buffers, device, token));
|
2019-07-15 04:51:28 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-11-23 19:16:47 +00:00
|
|
|
template <typename WritePortalType>
|
|
|
|
struct MultiplexerCreateWritePortalFunctor
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
2020-11-23 19:16:47 +00:00
|
|
|
template <typename StorageType>
|
|
|
|
VTKM_CONT WritePortalType operator()(StorageType,
|
2022-06-28 20:26:38 +00:00
|
|
|
const std::vector<vtkm::cont::internal::Buffer>& buffers,
|
2020-11-23 19:16:47 +00:00
|
|
|
vtkm::cont::DeviceAdapterId device,
|
|
|
|
vtkm::cont::Token& token) const
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
2020-11-23 19:16:47 +00:00
|
|
|
return WritePortalType(StorageType::CreateWritePortal(buffers, device, token));
|
2019-07-15 04:51:28 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-11-23 19:16:47 +00:00
|
|
|
template <typename T, typename... Ss>
|
|
|
|
struct MultiplexerArrayHandleVariantFunctor
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
2022-11-01 13:52:41 +00:00
|
|
|
using VariantType = vtkm::cont::Variant<vtkm::cont::ArrayHandle<T, Ss>...>;
|
2020-11-23 19:16:47 +00:00
|
|
|
|
|
|
|
template <typename StorageTag>
|
|
|
|
VTKM_CONT VariantType operator()(vtkm::cont::internal::Storage<T, StorageTag>,
|
2022-06-28 20:26:38 +00:00
|
|
|
const std::vector<vtkm::cont::internal::Buffer>& buffers)
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
2020-11-23 19:16:47 +00:00
|
|
|
return VariantType(vtkm::cont::ArrayHandle<T, StorageTag>(buffers));
|
2019-07-15 04:51:28 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace detail
|
|
|
|
|
2020-11-23 19:16:47 +00:00
|
|
|
template <typename ValueType, typename... StorageTags>
|
|
|
|
class Storage<ValueType, StorageTagMultiplexer<StorageTags...>>
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
|
|
|
template <typename S>
|
2020-11-23 19:16:47 +00:00
|
|
|
using StorageFor = vtkm::cont::internal::Storage<ValueType, S>;
|
2019-07-15 04:51:28 +00:00
|
|
|
|
2022-11-01 13:52:41 +00:00
|
|
|
using StorageVariant = vtkm::cont::Variant<StorageFor<StorageTags>...>;
|
2019-07-15 04:51:28 +00:00
|
|
|
|
2022-06-28 20:26:38 +00:00
|
|
|
VTKM_CONT static StorageVariant Variant(const std::vector<vtkm::cont::internal::Buffer>& buffers)
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
2020-11-23 19:16:47 +00:00
|
|
|
return buffers[0].GetMetaData<StorageVariant>();
|
2019-07-15 04:51:28 +00:00
|
|
|
}
|
|
|
|
|
2022-06-28 20:26:38 +00:00
|
|
|
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> ArrayBuffers(
|
|
|
|
const std::vector<vtkm::cont::internal::Buffer>& buffers)
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
2022-06-28 20:26:38 +00:00
|
|
|
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1, buffers.end());
|
2019-07-15 04:51:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2020-11-23 19:16:47 +00:00
|
|
|
using ReadPortalType =
|
|
|
|
vtkm::internal::ArrayPortalMultiplexer<typename StorageFor<StorageTags>::ReadPortalType...>;
|
|
|
|
using WritePortalType =
|
|
|
|
vtkm::internal::ArrayPortalMultiplexer<typename StorageFor<StorageTags>::WritePortalType...>;
|
2019-07-15 04:51:28 +00:00
|
|
|
|
2023-10-03 14:31:38 +00:00
|
|
|
VTKM_CONT static vtkm::IdComponent GetNumberOfComponentsFlat(
|
|
|
|
const std::vector<vtkm::cont::internal::Buffer>& buffers)
|
|
|
|
{
|
|
|
|
return Variant(buffers).CastAndCall(detail::MultiplexerGetNumberOfComponentsFlatFunctor{},
|
|
|
|
ArrayBuffers(buffers));
|
|
|
|
}
|
|
|
|
|
2022-06-28 20:26:38 +00:00
|
|
|
VTKM_CONT static vtkm::Id GetNumberOfValues(
|
|
|
|
const std::vector<vtkm::cont::internal::Buffer>& buffers)
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
2020-11-23 19:16:47 +00:00
|
|
|
return Variant(buffers).CastAndCall(detail::MultiplexerGetNumberOfValuesFunctor{},
|
|
|
|
ArrayBuffers(buffers));
|
2019-07-15 04:51:28 +00:00
|
|
|
}
|
|
|
|
|
2020-11-23 19:16:47 +00:00
|
|
|
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
|
2022-06-28 20:26:38 +00:00
|
|
|
const std::vector<vtkm::cont::internal::Buffer>& buffers,
|
2020-11-23 19:16:47 +00:00
|
|
|
vtkm::CopyFlag preserve,
|
|
|
|
vtkm::cont::Token& token)
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
2020-11-23 19:16:47 +00:00
|
|
|
Variant(buffers).CastAndCall(
|
|
|
|
detail::MultiplexerResizeBuffersFunctor{}, numValues, ArrayBuffers(buffers), preserve, token);
|
2019-07-15 04:51:28 +00:00
|
|
|
}
|
|
|
|
|
2022-06-28 20:26:38 +00:00
|
|
|
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
|
2022-01-04 16:29:12 +00:00
|
|
|
const ValueType& fillValue,
|
|
|
|
vtkm::Id startIndex,
|
2022-01-11 14:15:41 +00:00
|
|
|
vtkm::Id endIndex,
|
2022-01-04 16:29:12 +00:00
|
|
|
vtkm::cont::Token& token)
|
|
|
|
{
|
2022-01-11 14:15:41 +00:00
|
|
|
Variant(buffers).CastAndCall(detail::MultiplexerFillFunctor{},
|
|
|
|
ArrayBuffers(buffers),
|
|
|
|
fillValue,
|
|
|
|
startIndex,
|
|
|
|
endIndex,
|
|
|
|
token);
|
2022-01-04 16:29:12 +00:00
|
|
|
}
|
|
|
|
|
2022-06-28 20:26:38 +00:00
|
|
|
VTKM_CONT static ReadPortalType CreateReadPortal(
|
|
|
|
const std::vector<vtkm::cont::internal::Buffer>& buffers,
|
|
|
|
vtkm::cont::DeviceAdapterId device,
|
|
|
|
vtkm::cont::Token& token)
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
2020-11-23 19:16:47 +00:00
|
|
|
return Variant(buffers).CastAndCall(
|
|
|
|
detail::MultiplexerCreateReadPortalFunctor<ReadPortalType>{},
|
|
|
|
ArrayBuffers(buffers),
|
|
|
|
device,
|
|
|
|
token);
|
2019-07-15 04:51:28 +00:00
|
|
|
}
|
|
|
|
|
2022-06-28 20:26:38 +00:00
|
|
|
VTKM_CONT static WritePortalType CreateWritePortal(
|
|
|
|
const std::vector<vtkm::cont::internal::Buffer>& buffers,
|
|
|
|
vtkm::cont::DeviceAdapterId device,
|
|
|
|
vtkm::cont::Token& token)
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
2020-11-23 19:16:47 +00:00
|
|
|
return Variant(buffers).CastAndCall(
|
|
|
|
detail::MultiplexerCreateWritePortalFunctor<WritePortalType>{},
|
|
|
|
ArrayBuffers(buffers),
|
|
|
|
device,
|
|
|
|
token);
|
2019-07-15 04:51:28 +00:00
|
|
|
}
|
|
|
|
|
2022-06-28 20:26:38 +00:00
|
|
|
VTKM_CONT static bool IsValid(const std::vector<vtkm::cont::internal::Buffer>& buffers)
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
2020-11-23 19:16:47 +00:00
|
|
|
return Variant(buffers).IsValid();
|
2019-07-15 04:51:28 +00:00
|
|
|
}
|
|
|
|
|
2020-11-23 19:16:47 +00:00
|
|
|
template <typename ArrayType>
|
|
|
|
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(const ArrayType& array)
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
2020-11-23 19:16:47 +00:00
|
|
|
VTKM_IS_ARRAY_HANDLE(ArrayType);
|
2022-06-28 20:26:38 +00:00
|
|
|
return vtkm::cont::internal::CreateBuffers(StorageVariant{ array.GetStorage() }, array);
|
|
|
|
}
|
2019-07-15 04:51:28 +00:00
|
|
|
|
2022-06-28 20:26:38 +00:00
|
|
|
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
|
|
|
|
{
|
|
|
|
return vtkm::cont::internal::CreateBuffers(StorageVariant{});
|
2019-07-15 04:51:28 +00:00
|
|
|
}
|
|
|
|
|
2020-11-23 19:16:47 +00:00
|
|
|
VTKM_CONT static
|
|
|
|
typename detail::MultiplexerArrayHandleVariantFunctor<ValueType, StorageTags...>::VariantType
|
2022-06-28 20:26:38 +00:00
|
|
|
GetArrayHandleVariant(const std::vector<vtkm::cont::internal::Buffer>& buffers)
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
2020-11-23 19:16:47 +00:00
|
|
|
return Variant(buffers).CastAndCall(
|
|
|
|
detail::MultiplexerArrayHandleVariantFunctor<ValueType, StorageTags...>{},
|
|
|
|
ArrayBuffers(buffers));
|
2019-07-15 04:51:28 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace internal
|
|
|
|
|
|
|
|
namespace detail
|
|
|
|
{
|
|
|
|
|
2019-07-30 20:43:52 +00:00
|
|
|
template <typename... ArrayHandleTypes>
|
2019-07-15 04:51:28 +00:00
|
|
|
struct ArrayHandleMultiplexerTraits
|
|
|
|
{
|
2022-02-02 22:51:25 +00:00
|
|
|
using ArrayHandleType0 = vtkm::ListAt<vtkm::List<ArrayHandleTypes...>, 0>;
|
2019-07-30 20:43:52 +00:00
|
|
|
VTKM_IS_ARRAY_HANDLE(ArrayHandleType0);
|
|
|
|
using ValueType = typename ArrayHandleType0::ValueType;
|
|
|
|
|
|
|
|
// If there is a compile error in this group of lines, then one of the array types given to
|
|
|
|
// ArrayHandleMultiplexer must contain an invalid ArrayHandle. That could mean that it is not an
|
|
|
|
// ArrayHandle type or it could mean that the value type does not match the appropriate value
|
|
|
|
// type.
|
2019-07-15 04:51:28 +00:00
|
|
|
template <typename ArrayHandle>
|
|
|
|
struct CheckArrayHandleTransform
|
|
|
|
{
|
|
|
|
VTKM_IS_ARRAY_HANDLE(ArrayHandle);
|
|
|
|
VTKM_STATIC_ASSERT((std::is_same<ValueType, typename ArrayHandle::ValueType>::value));
|
|
|
|
};
|
2022-02-02 22:51:25 +00:00
|
|
|
using CheckArrayHandle = vtkm::List<CheckArrayHandleTransform<ArrayHandleTypes>...>;
|
2019-07-15 04:51:28 +00:00
|
|
|
|
2019-07-17 20:31:06 +00:00
|
|
|
// Note that this group of code could be simplified as the pair of lines:
|
|
|
|
// template <typename ArrayHandle>
|
|
|
|
// using ArrayHandleToStorageTag = typename ArrayHandle::StorageTag;
|
|
|
|
// However, there are issues with older Visual Studio compilers that is not working
|
|
|
|
// correctly with that form.
|
2019-07-15 04:51:28 +00:00
|
|
|
template <typename ArrayHandle>
|
2019-07-17 20:31:06 +00:00
|
|
|
struct ArrayHandleToStorageTagImpl
|
|
|
|
{
|
|
|
|
using Type = typename ArrayHandle::StorageTag;
|
|
|
|
};
|
|
|
|
template <typename ArrayHandle>
|
|
|
|
using ArrayHandleToStorageTag = typename ArrayHandleToStorageTagImpl<ArrayHandle>::Type;
|
2019-07-15 04:51:28 +00:00
|
|
|
|
|
|
|
using StorageTag =
|
|
|
|
vtkm::cont::StorageTagMultiplexer<ArrayHandleToStorageTag<ArrayHandleTypes>...>;
|
|
|
|
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
|
|
|
};
|
2020-11-23 19:16:47 +00:00
|
|
|
} // namespace detail
|
|
|
|
|
2019-07-15 04:51:28 +00:00
|
|
|
/// \brief An ArrayHandle that can behave like several other handles.
|
|
|
|
///
|
|
|
|
/// An \c ArrayHandleMultiplexer simply redirects its calls to another \c ArrayHandle. However
|
|
|
|
/// the type of that \c ArrayHandle does not need to be (completely) known at runtime. Rather,
|
|
|
|
/// \c ArrayHandleMultiplexer is defined over a set of possible \c ArrayHandle types. Any
|
|
|
|
/// one of these \c ArrayHandles may be assigned to the \c ArrayHandleMultiplexer.
|
|
|
|
///
|
|
|
|
/// When a value is retreived from the \c ArrayHandleMultiplexer, the multiplexer checks to
|
|
|
|
/// see which type of array is currently stored in it. It then redirects to the \c ArrayHandle
|
|
|
|
/// of the appropriate type.
|
|
|
|
///
|
2019-07-30 20:43:52 +00:00
|
|
|
/// The \c ArrayHandleMultiplexer template parameters are all the ArrayHandle types it
|
|
|
|
/// should support.
|
|
|
|
///
|
2019-07-15 04:51:28 +00:00
|
|
|
/// If only one template parameter is given, it is assumed to be the \c ValueType of the
|
|
|
|
/// array. A default list of supported arrays is supported (see
|
|
|
|
/// \c vtkm::cont::internal::ArrayHandleMultiplexerDefaultArrays.) If multiple template
|
|
|
|
/// parameters are given, they are all considered possible \c ArrayHandle types.
|
|
|
|
///
|
2019-07-30 20:43:52 +00:00
|
|
|
template <typename... ArrayHandleTypes>
|
|
|
|
class ArrayHandleMultiplexer
|
|
|
|
: public vtkm::cont::ArrayHandle<
|
|
|
|
typename detail::ArrayHandleMultiplexerTraits<ArrayHandleTypes...>::ValueType,
|
|
|
|
typename detail::ArrayHandleMultiplexerTraits<ArrayHandleTypes...>::StorageTag>
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
2019-07-30 20:43:52 +00:00
|
|
|
using Traits = detail::ArrayHandleMultiplexerTraits<ArrayHandleTypes...>;
|
2019-07-15 04:51:28 +00:00
|
|
|
|
2019-07-30 20:43:52 +00:00
|
|
|
public:
|
|
|
|
VTKM_ARRAY_HANDLE_SUBCLASS(
|
|
|
|
ArrayHandleMultiplexer,
|
|
|
|
(ArrayHandleMultiplexer<ArrayHandleTypes...>),
|
|
|
|
(vtkm::cont::ArrayHandle<typename Traits::ValueType, typename Traits::StorageTag>));
|
2019-07-15 04:51:28 +00:00
|
|
|
|
2019-07-30 20:43:52 +00:00
|
|
|
template <typename RealStorageTag>
|
|
|
|
VTKM_CONT ArrayHandleMultiplexer(const vtkm::cont::ArrayHandle<ValueType, RealStorageTag>& src)
|
2020-11-23 19:16:47 +00:00
|
|
|
: Superclass(StorageType::CreateBuffers(src))
|
2019-07-15 04:51:28 +00:00
|
|
|
{
|
|
|
|
}
|
2019-09-05 14:57:58 +00:00
|
|
|
|
2020-11-23 19:16:47 +00:00
|
|
|
VTKM_CONT bool IsValid() const { return StorageType::IsValid(this->GetBuffers()); }
|
2019-09-05 14:57:58 +00:00
|
|
|
|
|
|
|
template <typename S>
|
2020-11-23 19:16:47 +00:00
|
|
|
VTKM_CONT void SetArray(const vtkm::cont::ArrayHandle<ValueType, S>& src)
|
2019-09-05 14:57:58 +00:00
|
|
|
{
|
2020-11-23 19:16:47 +00:00
|
|
|
this->SetBuffers(StorageType::CreateBuffers(src));
|
2019-09-05 14:57:58 +00:00
|
|
|
}
|
|
|
|
|
2020-11-23 19:16:47 +00:00
|
|
|
VTKM_CONT auto GetArrayHandleVariant() const
|
|
|
|
-> decltype(StorageType::GetArrayHandleVariant(this->GetBuffers()))
|
2019-09-05 14:57:58 +00:00
|
|
|
{
|
2020-11-23 19:16:47 +00:00
|
|
|
return StorageType::GetArrayHandleVariant(this->GetBuffers());
|
2019-09-05 14:57:58 +00:00
|
|
|
}
|
2019-07-15 04:51:28 +00:00
|
|
|
};
|
|
|
|
|
2019-12-05 02:17:19 +00:00
|
|
|
/// \brief Converts a`vtkm::List` to an `ArrayHandleMultiplexer`
|
|
|
|
///
|
|
|
|
/// The argument of this template must be a `vtkm::List` and furthermore all the types in
|
|
|
|
/// the list tag must be some type of \c ArrayHandle. The templated type gets aliased to
|
|
|
|
/// an \c ArrayHandleMultiplexer that can store any of these ArrayHandle types.
|
|
|
|
///
|
|
|
|
template <typename List>
|
|
|
|
using ArrayHandleMultiplexerFromList = vtkm::ListApply<List, ArrayHandleMultiplexer>;
|
2019-09-05 16:41:52 +00:00
|
|
|
|
2020-09-10 23:54:12 +00:00
|
|
|
namespace internal
|
|
|
|
{
|
|
|
|
|
|
|
|
namespace detail
|
|
|
|
{
|
|
|
|
|
|
|
|
struct ArrayExtractComponentMultiplexerFunctor
|
|
|
|
{
|
|
|
|
template <typename ArrayType>
|
|
|
|
auto operator()(const ArrayType& array,
|
|
|
|
vtkm::IdComponent componentIndex,
|
|
|
|
vtkm::CopyFlag allowCopy) const
|
|
|
|
-> decltype(vtkm::cont::ArrayExtractComponent(array, componentIndex, allowCopy))
|
|
|
|
{
|
|
|
|
return vtkm::cont::internal::ArrayExtractComponentImpl<typename ArrayType::StorageTag>{}(
|
|
|
|
array, componentIndex, allowCopy);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace detail
|
|
|
|
|
|
|
|
template <typename... Ss>
|
|
|
|
struct ArrayExtractComponentImpl<vtkm::cont::StorageTagMultiplexer<Ss...>>
|
|
|
|
{
|
|
|
|
template <typename T>
|
|
|
|
vtkm::cont::ArrayHandleStride<typename vtkm::VecTraits<T>::BaseComponentType> operator()(
|
|
|
|
const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagMultiplexer<Ss...>>& src,
|
|
|
|
vtkm::IdComponent componentIndex,
|
|
|
|
vtkm::CopyFlag allowCopy)
|
|
|
|
{
|
|
|
|
vtkm::cont::ArrayHandleMultiplexer<vtkm::cont::ArrayHandle<T, Ss>...> array(src);
|
|
|
|
return array.GetArrayHandleVariant().CastAndCall(
|
|
|
|
detail::ArrayExtractComponentMultiplexerFunctor{}, componentIndex, allowCopy);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace internal
|
|
|
|
|
2019-07-15 04:51:28 +00:00
|
|
|
} // namespace cont
|
|
|
|
|
|
|
|
} // namespace vtkm
|
|
|
|
|
|
|
|
#endif //vtk_m_cont_ArrayHandleMultiplexer_h
|