1 //============================================================================
2 //  Copyright (c) Kitware, Inc.
3 //  All rights reserved.
4 //  See LICENSE.txt for details.
5 //
6 //  This software is distributed WITHOUT ANY WARRANTY; without even
7 //  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 //  PURPOSE.  See the above copyright notice for more information.
9 //============================================================================
10 #ifndef vtk_m_cont_internal_IteratorFromArrayPortal_h
11 #define vtk_m_cont_internal_IteratorFromArrayPortal_h
12 
13 #include <vtkm/Assert.h>
14 #include <vtkm/cont/ArrayPortal.h>
15 #include <vtkm/internal/ArrayPortalValueReference.h>
16 
17 namespace vtkm
18 {
19 namespace cont
20 {
21 namespace internal
22 {
23 
24 template <class ArrayPortalType>
25 class IteratorFromArrayPortal
26 {
27 public:
28   using value_type = typename std::remove_const<typename ArrayPortalType::ValueType>::type;
29   using reference = vtkm::internal::ArrayPortalValueReference<ArrayPortalType>;
30   using pointer = typename std::add_pointer<value_type>::type;
31 
32   using difference_type = std::ptrdiff_t;
33 
34   using iterator_category = std::random_access_iterator_tag;
35 
36   using iter = IteratorFromArrayPortal<ArrayPortalType>;
37 
38   VTKM_SUPPRESS_EXEC_WARNINGS
39   VTKM_EXEC_CONT
IteratorFromArrayPortal()40   IteratorFromArrayPortal()
41     : Portal()
42     , Index(0)
43   {
44   }
45 
46   VTKM_SUPPRESS_EXEC_WARNINGS
47   VTKM_EXEC_CONT
48   explicit IteratorFromArrayPortal(const ArrayPortalType& portal, vtkm::Id index = 0)
Portal(portal)49     : Portal(portal)
50     , Index(index)
51   {
52     VTKM_ASSERT(index >= 0);
53     VTKM_ASSERT(index <= portal.GetNumberOfValues());
54   }
55 
56   VTKM_EXEC_CONT
57   reference operator*() const { return reference(this->Portal, this->Index); }
58 
59   VTKM_EXEC_CONT
60   reference operator->() const { return reference(this->Portal, this->Index); }
61 
62   VTKM_EXEC_CONT
63   reference operator[](difference_type idx) const
64   {
65     return reference(this->Portal, this->Index + static_cast<vtkm::Id>(idx));
66   }
67 
68   VTKM_EXEC_CONT
69   iter& operator++()
70   {
71     this->Index++;
72     VTKM_ASSERT(this->Index <= this->Portal.GetNumberOfValues());
73     return *this;
74   }
75 
76   VTKM_EXEC_CONT
77   iter operator++(int) { return iter(this->Portal, this->Index++); }
78 
79   VTKM_EXEC_CONT
80   iter& operator--()
81   {
82     this->Index--;
83     VTKM_ASSERT(this->Index >= 0);
84     return *this;
85   }
86 
87   VTKM_EXEC_CONT
88   iter operator--(int) { return iter(this->Portal, this->Index--); }
89 
90   VTKM_EXEC_CONT
91   iter& operator+=(difference_type n)
92   {
93     this->Index += static_cast<vtkm::Id>(n);
94     VTKM_ASSERT(this->Index <= this->Portal.GetNumberOfValues());
95     return *this;
96   }
97 
98   VTKM_EXEC_CONT
99   iter& operator-=(difference_type n)
100   {
101     this->Index += static_cast<vtkm::Id>(n);
102     VTKM_ASSERT(this->Index >= 0);
103     return *this;
104   }
105 
106   VTKM_EXEC_CONT
107   iter operator-(difference_type n) const
108   {
109     return iter(this->Portal, this->Index - static_cast<vtkm::Id>(n));
110   }
111 
112   ArrayPortalType Portal;
113   vtkm::Id Index;
114 };
115 
116 template <class ArrayPortalType>
make_IteratorBegin(const ArrayPortalType & portal)117 VTKM_EXEC_CONT IteratorFromArrayPortal<ArrayPortalType> make_IteratorBegin(
118   const ArrayPortalType& portal)
119 {
120   return IteratorFromArrayPortal<ArrayPortalType>(portal, 0);
121 }
122 
123 template <class ArrayPortalType>
make_IteratorEnd(const ArrayPortalType & portal)124 VTKM_EXEC_CONT IteratorFromArrayPortal<ArrayPortalType> make_IteratorEnd(
125   const ArrayPortalType& portal)
126 {
127   return IteratorFromArrayPortal<ArrayPortalType>(portal, portal.GetNumberOfValues());
128 }
129 
130 template <typename PortalType>
131 VTKM_EXEC_CONT bool operator==(vtkm::cont::internal::IteratorFromArrayPortal<PortalType> const& lhs,
132                                vtkm::cont::internal::IteratorFromArrayPortal<PortalType> const& rhs)
133 {
134   return lhs.Index == rhs.Index;
135 }
136 
137 template <typename PortalType>
138 VTKM_EXEC_CONT bool operator!=(vtkm::cont::internal::IteratorFromArrayPortal<PortalType> const& lhs,
139                                vtkm::cont::internal::IteratorFromArrayPortal<PortalType> const& rhs)
140 {
141   return lhs.Index != rhs.Index;
142 }
143 
144 template <typename PortalType>
145 VTKM_EXEC_CONT bool operator<(vtkm::cont::internal::IteratorFromArrayPortal<PortalType> const& lhs,
146                               vtkm::cont::internal::IteratorFromArrayPortal<PortalType> const& rhs)
147 {
148   return lhs.Index < rhs.Index;
149 }
150 
151 template <typename PortalType>
152 VTKM_EXEC_CONT bool operator<=(vtkm::cont::internal::IteratorFromArrayPortal<PortalType> const& lhs,
153                                vtkm::cont::internal::IteratorFromArrayPortal<PortalType> const& rhs)
154 {
155   return lhs.Index <= rhs.Index;
156 }
157 
158 template <typename PortalType>
159 VTKM_EXEC_CONT bool operator>(vtkm::cont::internal::IteratorFromArrayPortal<PortalType> const& lhs,
160                               vtkm::cont::internal::IteratorFromArrayPortal<PortalType> const& rhs)
161 {
162   return lhs.Index > rhs.Index;
163 }
164 
165 template <typename PortalType>
166 VTKM_EXEC_CONT bool operator>=(vtkm::cont::internal::IteratorFromArrayPortal<PortalType> const& lhs,
167                                vtkm::cont::internal::IteratorFromArrayPortal<PortalType> const& rhs)
168 {
169   return lhs.Index >= rhs.Index;
170 }
171 
172 template <typename PortalType>
173 VTKM_EXEC_CONT std::ptrdiff_t operator-(
174   vtkm::cont::internal::IteratorFromArrayPortal<PortalType> const& lhs,
175   vtkm::cont::internal::IteratorFromArrayPortal<PortalType> const& rhs)
176 {
177   return lhs.Index - rhs.Index;
178 }
179 
180 template <typename PortalType>
181 VTKM_EXEC_CONT vtkm::cont::internal::IteratorFromArrayPortal<PortalType> operator+(
182   vtkm::cont::internal::IteratorFromArrayPortal<PortalType> const& iter,
183   std::ptrdiff_t n)
184 {
185   return vtkm::cont::internal::IteratorFromArrayPortal<PortalType>(
186     iter.Portal, iter.Index + static_cast<vtkm::Id>(n));
187 }
188 
189 template <typename PortalType>
190 VTKM_EXEC_CONT vtkm::cont::internal::IteratorFromArrayPortal<PortalType> operator+(
191   std::ptrdiff_t n,
192   vtkm::cont::internal::IteratorFromArrayPortal<PortalType> const& iter)
193 {
194   return vtkm::cont::internal::IteratorFromArrayPortal<PortalType>(
195     iter.Portal, iter.Index + static_cast<vtkm::Id>(n));
196 }
197 }
198 }
199 } // namespace vtkm::cont::internal
200 
201 #endif //vtk_m_cont_internal_IteratorFromArrayPortal_h
202