//============================================================================ // 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_ArrayHandleCounting_h #define vtk_m_cont_ArrayHandleCounting_h #include #include #include namespace vtkm { namespace cont { struct VTKM_ALWAYS_EXPORT StorageTagCounting { }; namespace internal { /// \brief An implicit array portal that returns an counting value. template class VTKM_ALWAYS_EXPORT ArrayPortalCounting { using ComponentType = typename vtkm::VecTraits::ComponentType; public: using ValueType = CountingValueType; VTKM_EXEC_CONT ArrayPortalCounting() : Start(0) , Step(1) , NumberOfValues(0) { } VTKM_EXEC_CONT ArrayPortalCounting(ValueType start, ValueType step, vtkm::Id numValues) : Start(start) , Step(step) , NumberOfValues(numValues) { } VTKM_EXEC_CONT ValueType GetStart() const { return this->Start; } VTKM_EXEC_CONT ValueType GetStep() const { return this->Step; } VTKM_EXEC_CONT vtkm::Id GetNumberOfValues() const { return this->NumberOfValues; } VTKM_EXEC_CONT ValueType Get(vtkm::Id index) const { return ValueType(this->Start + this->Step * ValueType(static_cast(index))); } private: ValueType Start; ValueType Step; vtkm::Id NumberOfValues; }; namespace detail { template > struct CanCountImpl; template struct CanCountImpl { using TTraits = vtkm::TypeTraits; static constexpr bool IsNumeric = !std::is_same::value; static constexpr bool value = IsNumeric; }; template struct CanCountImpl { using VTraits = vtkm::VecTraits; using BaseType = typename VTraits::BaseComponentType; static constexpr bool IsBool = std::is_same::value; static constexpr bool value = CanCountImpl::value && !IsBool; }; } // namespace detail // Not all types can be counted. template struct CanCount { static constexpr bool value = detail::CanCountImpl::value; }; template using StorageTagCountingSuperclass = vtkm::cont::StorageTagImplicit>; template struct Storage::value, vtkm::cont::StorageTagCounting>::type> : Storage> { }; } // namespace internal /// ArrayHandleCounting is a specialization of ArrayHandle. By default it /// contains a increment value, that is increment for each step between zero /// and the passed in length template class ArrayHandleCounting : public vtkm::cont::ArrayHandle { public: VTKM_ARRAY_HANDLE_SUBCLASS(ArrayHandleCounting, (ArrayHandleCounting), (vtkm::cont::ArrayHandle)); VTKM_CONT ArrayHandleCounting(CountingValueType start, CountingValueType step, vtkm::Id length) : Superclass(internal::PortalToArrayHandleImplicitBuffers( internal::ArrayPortalCounting(start, step, length))) { } }; /// A convenience function for creating an ArrayHandleCounting. It takes the /// value to start counting from and and the number of times to increment. template VTKM_CONT vtkm::cont::ArrayHandleCounting make_ArrayHandleCounting(CountingValueType start, CountingValueType step, vtkm::Id length) { return vtkm::cont::ArrayHandleCounting(start, step, length); } } } // 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_Counting<" + SerializableTypeString::Get() + ">"; return name; } }; template struct SerializableTypeString> : SerializableTypeString> { }; } } // vtkm::cont namespace mangled_diy_namespace { template struct Serialization> { private: using Type = vtkm::cont::ArrayHandleCounting; using BaseType = vtkm::cont::ArrayHandle; public: static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj) { auto portal = obj.ReadPortal(); vtkmdiy::save(bb, portal.GetStart()); vtkmdiy::save(bb, portal.GetStep()); vtkmdiy::save(bb, portal.GetNumberOfValues()); } static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj) { T start{}, step{}; vtkm::Id count = 0; vtkmdiy::load(bb, start); vtkmdiy::load(bb, step); vtkmdiy::load(bb, count); obj = vtkm::cont::make_ArrayHandleCounting(start, step, count); } }; template struct Serialization> : Serialization> { }; } // diy /// @endcond SERIALIZATION #endif //vtk_m_cont_ArrayHandleCounting_h