From 6da2dc0cda7c640468c84738c9b668be223ac96f Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Thu, 26 May 2016 08:23:27 -0400 Subject: [PATCH] ArrayPortalFromIterators now can be explicitly instantiated. Template instantiation is useful because when you are creating object files, as uninstantiated template definitions are not are not added. Fully supporting explicit instantiation like ITK does will require more code changes, but this is a very minor step towards that goal. --- vtkm/cont/internal/ArrayPortalFromIterators.h | 88 ++++++++++++++++++- 1 file changed, 86 insertions(+), 2 deletions(-) diff --git a/vtkm/cont/internal/ArrayPortalFromIterators.h b/vtkm/cont/internal/ArrayPortalFromIterators.h index c12a32092..00a90536a 100644 --- a/vtkm/cont/internal/ArrayPortalFromIterators.h +++ b/vtkm/cont/internal/ArrayPortalFromIterators.h @@ -29,15 +29,22 @@ #include #include +#include + namespace vtkm { namespace cont { namespace internal { +template +class ArrayPortalFromIterators; + /// This templated implementation of an ArrayPortal allows you to adapt a pair /// of begin/end iterators to an ArrayPortal interface. /// template -class ArrayPortalFromIterators +class ArrayPortalFromIterators::type > >::type> { public: typedef typename std::iterator_traits::value_type ValueType; @@ -94,7 +101,84 @@ public: VTKM_EXEC_CONT_EXPORT void Set(vtkm::Id index, const ValueType& value) const { - *this->IteratorAt(index) = value; + *(this->BeginIterator + index) = value; + } + + VTKM_SUPPRESS_EXEC_WARNINGS + VTKM_EXEC_CONT_EXPORT + IteratorT GetIteratorBegin() const { + return this->BeginIterator; + } + +private: + IteratorT BeginIterator; + vtkm::Id NumberOfValues; + + VTKM_SUPPRESS_EXEC_WARNINGS + VTKM_EXEC_CONT_EXPORT + IteratorT IteratorAt(vtkm::Id index) const + { + VTKM_ASSERT(index >= 0); + VTKM_ASSERT(index < this->GetNumberOfValues()); + + return this->BeginIterator + index; + } +}; + +template +class ArrayPortalFromIterators::type > >::type> +{ +public: + typedef typename std::iterator_traits::value_type ValueType; + typedef IteratorT IteratorType; + + VTKM_SUPPRESS_EXEC_WARNINGS + VTKM_CONT_EXPORT + ArrayPortalFromIterators() { } + + VTKM_SUPPRESS_EXEC_WARNINGS + VTKM_CONT_EXPORT + ArrayPortalFromIterators(IteratorT begin, IteratorT end) + : BeginIterator(begin) + { + typename std::iterator_traits::difference_type numberOfValues = + std::distance(begin, end); + VTKM_ASSERT(numberOfValues >= 0); +#ifndef VTKM_USE_64BIT_IDS + if (numberOfValues > std::numeric_limits::max()) + { + throw vtkm::cont::ErrorControlBadAllocation( + "Distance of iterators larger than maximum array size. " + "To support larger arrays, try turning on VTKM_USE_64BIT_IDS."); + } +#endif // !VTKM_USE_64BIT_IDS + this->NumberOfValues = static_cast(numberOfValues); + } + + /// Copy constructor for any other ArrayPortalFromIterators with an iterator + /// type that can be copied to this iterator type. This allows us to do any + /// type casting that the iterators do (like the non-const to const cast). + /// + template + VTKM_CONT_EXPORT + ArrayPortalFromIterators(const ArrayPortalFromIterators &src) + : BeginIterator(src.GetIteratorBegin()), NumberOfValues(src.GetNumberOfValues()) + { } + + VTKM_SUPPRESS_EXEC_WARNINGS + VTKM_EXEC_CONT_EXPORT + vtkm::Id GetNumberOfValues() const + { + return this->NumberOfValues; + } + + VTKM_SUPPRESS_EXEC_WARNINGS + VTKM_EXEC_CONT_EXPORT + ValueType Get(vtkm::Id index) const + { + return *this->IteratorAt(index); } VTKM_SUPPRESS_EXEC_WARNINGS