//============================================================================ // 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_ArrayHandleReverse_h #define vtk_m_cont_ArrayHandleReverse_h #include #include #include #include namespace vtkm { namespace cont { namespace internal { template class VTKM_ALWAYS_EXPORT ArrayPortalReverse { using Writable = vtkm::internal::PortalSupportsSets; public: using ValueType = typename PortalType::ValueType; VTKM_EXEC_CONT ArrayPortalReverse() : portal() { } VTKM_EXEC_CONT ArrayPortalReverse(const PortalType& p) : portal(p) { } template VTKM_EXEC_CONT ArrayPortalReverse(const ArrayPortalReverse& src) : portal(src.GetPortal()) { } VTKM_EXEC_CONT vtkm::Id GetNumberOfValues() const { return this->portal.GetNumberOfValues(); } VTKM_EXEC_CONT ValueType Get(vtkm::Id index) const { return this->portal.Get(portal.GetNumberOfValues() - index - 1); } template ::type> VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const { this->portal.Set(portal.GetNumberOfValues() - index - 1, value); } private: PortalType portal; }; } template class VTKM_ALWAYS_EXPORT StorageTagReverse { }; namespace internal { namespace detail { template struct ReverseTypeArgImpl; template struct ReverseTypeArgImpl { using StorageTag = Storage; using ArrayHandle = vtkm::cont::ArrayHandle; }; template struct ReverseTypeArgImpl { VTKM_STATIC_ASSERT_MSG((std::is_same::value), "Used array with wrong type in ArrayHandleReverse."); using StorageTag VTKM_DEPRECATED( 1.6, "Use storage tag instead of array handle in StorageTagReverse.") = typename Array::StorageTag; using ArrayHandle VTKM_DEPRECATED( 1.6, "Use storage tag instead of array handle in StorageTagReverse.") = vtkm::cont::ArrayHandle; }; template struct ReverseTypeArg : ReverseTypeArgImpl::type::value> { }; } // namespace detail template class Storage> { using SourceStorage = Storage::StorageTag>; public: using ArrayHandleType = typename detail::ReverseTypeArg::ArrayHandle; using ReadPortalType = ArrayPortalReverse; using WritePortalType = ArrayPortalReverse; VTKM_CONT static vtkm::IdComponent GetNumberOfBuffers() { return SourceStorage::GetNumberOfBuffers(); } VTKM_CONT static void ResizeBuffers(vtkm::Id numValues, vtkm::cont::internal::Buffer* buffers, vtkm::CopyFlag preserve, vtkm::cont::Token& token) { SourceStorage::ResizeBuffers(numValues, buffers, preserve, token); } VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers) { return SourceStorage::GetNumberOfValues(buffers); } VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers, vtkm::cont::DeviceAdapterId device, vtkm::cont::Token& token) { return ReadPortalType(SourceStorage::CreateReadPortal(buffers, device, token)); } VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers, vtkm::cont::DeviceAdapterId device, vtkm::cont::Token& token) { return WritePortalType(SourceStorage::CreateWritePortal(buffers, device, token)); } }; // class storage } // namespace internal template VTKM_ARRAY_HANDLE_NEW_STYLE(T, vtkm::cont::StorageTagReverse); /// \brief Reverse the order of an array, on demand. /// /// ArrayHandleReverse is a specialization of ArrayHandle. Given an ArrayHandle, /// it creates a new handle that returns the elements of the array in reverse /// order (i.e. from end to beginning). /// template class ArrayHandleReverse : public vtkm::cont::ArrayHandle> { public: VTKM_ARRAY_HANDLE_SUBCLASS( ArrayHandleReverse, (ArrayHandleReverse), (vtkm::cont::ArrayHandle>)); public: ArrayHandleReverse(const ArrayHandleType& handle) : Superclass(handle.GetBuffers()) { } VTKM_CONT ArrayHandleType GetSourceArray() const { return vtkm::cont::ArrayHandle( this->GetBuffers()); } }; /// make_ArrayHandleReverse is convenience function to generate an /// ArrayHandleReverse. /// template VTKM_CONT ArrayHandleReverse make_ArrayHandleReverse(const HandleType& handle) { return ArrayHandleReverse(handle); } } } // 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_Reverse<" + SerializableTypeString::Get() + ">"; return name; } }; template struct SerializableTypeString>> : SerializableTypeString>> { }; } } // vtkm::cont namespace mangled_diy_namespace { template struct Serialization> { private: using Type = vtkm::cont::ArrayHandleReverse; using BaseType = vtkm::cont::ArrayHandle; public: static VTKM_CONT void save(BinaryBuffer& bb, const Type& obj) { vtkmdiy::save(bb, obj.GetSourceArray()); } static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj) { AH array; vtkmdiy::load(bb, array); obj = vtkm::cont::make_ArrayHandleReverse(array); } }; template struct Serialization>> : Serialization>> { }; } // diy /// @endcond SERIALIZATION #endif // vtk_m_cont_ArrayHandleReverse_h