//============================================================================ // 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_ArrayHandleConcatenate_h #define vtk_m_cont_ArrayHandleConcatenate_h #include #include #include namespace vtkm { namespace internal { template class VTKM_ALWAYS_EXPORT ArrayPortalConcatenate { using WritableP1 = vtkm::internal::PortalSupportsSets; using WritableP2 = vtkm::internal::PortalSupportsSets; using Writable = std::integral_constant; public: using ValueType = typename PortalType1::ValueType; VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_CONT ArrayPortalConcatenate() : portal1() , portal2() { } VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_CONT ArrayPortalConcatenate(const PortalType1& p1, const PortalType2& p2) : portal1(p1) , portal2(p2) { } // Copy constructor VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT ArrayPortalConcatenate(const ArrayPortalConcatenate& src) : portal1(src.GetPortal1()) , portal2(src.GetPortal2()) { } VTKM_EXEC_CONT vtkm::Id GetNumberOfValues() const { return this->portal1.GetNumberOfValues() + this->portal2.GetNumberOfValues(); } VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_CONT ValueType Get(vtkm::Id index) const { if (index < this->portal1.GetNumberOfValues()) { return this->portal1.Get(index); } else { return this->portal2.Get(index - this->portal1.GetNumberOfValues()); } } VTKM_SUPPRESS_EXEC_WARNINGS template ::type> VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const { if (index < this->portal1.GetNumberOfValues()) { this->portal1.Set(index, value); } else { this->portal2.Set(index - this->portal1.GetNumberOfValues(), value); } } VTKM_EXEC_CONT const PortalType1& GetPortal1() const { return this->portal1; } VTKM_EXEC_CONT const PortalType2& GetPortal2() const { return this->portal2; } private: PortalType1 portal1; PortalType2 portal2; }; // class ArrayPortalConcatenate } } // namespace vtkm::internal namespace vtkm { namespace cont { template class VTKM_ALWAYS_EXPORT StorageTagConcatenate { }; namespace internal { namespace detail { template struct ConcatinateTypeArgImpl; template struct ConcatinateTypeArgImpl { using StorageTag = StorageTag_; using Storage = vtkm::cont::internal::Storage; using ArrayHandle = vtkm::cont::ArrayHandle; }; template struct ConcatinateTypeArgImpl { VTKM_STATIC_ASSERT_MSG((std::is_same::value), "Used array with wrong type in ArrayHandleConcatinate."); using StorageTag VTKM_DEPRECATED( 1.6, "Use storage tags instead of array handles in StorageTagConcatenate.") = typename Array::StorageTag; using Storage VTKM_DEPRECATED( 1.6, "Use storage tags instead of array handles in StorageTagConcatenate.") = vtkm::cont::internal::Storage; using ArrayHandle VTKM_DEPRECATED( 1.6, "Use storage tags instead of array handles in StorageTagConcatenate.") = vtkm::cont::ArrayHandle; }; template struct ConcatinateTypeArg : ConcatinateTypeArgImpl::type::value> { }; } // namespace detail template class Storage> { using SourceStorage1 = typename detail::ConcatinateTypeArg::Storage; using SourceStorage2 = typename detail::ConcatinateTypeArg::Storage; using ArrayHandleType1 = typename detail::ConcatinateTypeArg::ArrayHandle; using ArrayHandleType2 = typename detail::ConcatinateTypeArg::ArrayHandle; template VTKM_CONT static Buff* Buffers1(Buff* buffers) { return buffers; } template VTKM_CONT static Buff* Buffers2(Buff* buffers) { return buffers + SourceStorage1::GetNumberOfBuffers(); } public: VTKM_STORAGE_NO_RESIZE; using ReadPortalType = vtkm::internal::ArrayPortalConcatenate; using WritePortalType = vtkm::internal::ArrayPortalConcatenate; VTKM_CONT static constexpr vtkm::IdComponent GetNumberOfBuffers() { return (SourceStorage1::GetNumberOfBuffers() + SourceStorage2::GetNumberOfBuffers()); } VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers) { return (SourceStorage1::GetNumberOfValues(Buffers1(buffers)) + SourceStorage2::GetNumberOfValues(Buffers2(buffers))); } VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers, vtkm::cont::DeviceAdapterId device, vtkm::cont::Token& token) { return ReadPortalType(SourceStorage1::CreateReadPortal(Buffers1(buffers), device, token), SourceStorage2::CreateReadPortal(Buffers2(buffers), device, token)); } VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers, vtkm::cont::DeviceAdapterId device, vtkm::cont::Token& token) { return WritePortalType(SourceStorage1::CreateWritePortal(Buffers1(buffers), device, token), SourceStorage2::CreateWritePortal(Buffers2(buffers), device, token)); } VTKM_CONT static auto CreateBuffers(const ArrayHandleType1& array1, const ArrayHandleType2& array2) -> decltype(vtkm::cont::internal::CreateBuffers()) { return vtkm::cont::internal::CreateBuffers(array1, array2); } VTKM_CONT static const ArrayHandleType1& GetArray1(const vtkm::cont::internal::Buffer* buffers) { return ArrayHandleType1(Buffers1(buffers)); } VTKM_CONT static const ArrayHandleType2& GetArray2(const vtkm::cont::internal::Buffer* buffers) { return ArrayHandleType2(Buffers2(buffers)); } }; // class Storage } } } // namespace vtkm::cont::internal namespace vtkm { namespace cont { template class ArrayHandleConcatenate : public vtkm::cont::ArrayHandle> { public: VTKM_ARRAY_HANDLE_SUBCLASS( ArrayHandleConcatenate, (ArrayHandleConcatenate), (vtkm::cont::ArrayHandle>)); protected: using StorageType = vtkm::cont::internal::Storage; public: VTKM_CONT ArrayHandleConcatenate(const ArrayHandleType1& array1, const ArrayHandleType2& array2) : Superclass(StorageType::CreateBuffers(array1, array2)) { } }; template VTKM_CONT ArrayHandleConcatenate make_ArrayHandleConcatenate( const ArrayHandleType1& array1, const ArrayHandleType2& array2) { return ArrayHandleConcatenate(array1, array2); } } } // namespace vtkm::cont //============================================================================= // Specializations of serialization related classes /// @cond SERIALIZATION namespace vtkm { namespace cont { template struct SerializableTypeString> { static VTKM_CONT const std::string& Get() { static std::string name = "AH_Concatenate<" + SerializableTypeString::Get() + "," + SerializableTypeString::Get() + ">"; return name; } }; template struct SerializableTypeString< vtkm::cont::ArrayHandle>> : SerializableTypeString::ArrayHandle, typename internal::detail::ConcatinateTypeArg::ArrayHandle>> { }; } } // vtkm::cont namespace mangled_diy_namespace { template struct Serialization> { private: using Type = vtkm::cont::ArrayHandleConcatenate; using BaseType = vtkm::cont::ArrayHandle; public: static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj) { auto storage = obj.GetStorage(); vtkmdiy::save(bb, storage.GetArray1()); vtkmdiy::save(bb, storage.GetArray2()); } static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj) { AH1 array1; AH2 array2; vtkmdiy::load(bb, array1); vtkmdiy::load(bb, array2); obj = vtkm::cont::make_ArrayHandleConcatenate(array1, array2); } }; template struct Serialization>> : Serialization::ArrayHandle, typename vtkm::cont::internal::detail::ConcatinateTypeArg::ArrayHandle>> { }; } // diy /// @endcond SERIALIZATION #endif //vtk_m_cont_ArrayHandleConcatenate_h