DGtal 1.4.0
Loading...
Searching...
No Matches
ArrayImageIterator.ih
1/**
2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU Lesser General Public License as
4 * published by the Free Software Foundation, either version 3 of the
5 * License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 *
15 **/
16
17/*
18 * @file ArrayImageIterator.ih
19 * @author Roland Denis (\c roland.denis@univ-smb.fr )
20 * LAboratory of MAthematics - LAMA (CNRS, UMR 5127), University of Savoie, France
21 *
22 * @date 2015/06/19
23 *
24 * This file is part of the DGtal library.
25 */
26
27
28//////////////////////////////////////////////////////////////////////////////
29#include <DGtal/base/Assert.h>
30//////////////////////////////////////////////////////////////////////////////
31
32///////////////////////////////////////////////////////////////////////////////
33// IMPLEMENTATION of inline methods.
34///////////////////////////////////////////////////////////////////////////////
35
36///////////////////////////////////////////////////////////////////////////////
37// ----------------------- Standard services ------------------------------
38
39
40//------------------------------------------------------------------------------
41/// Default constructor.
42template <typename TIterableClass>
43DGtal::ArrayImageIterator<TIterableClass>::
44ArrayImageIterator()
45 : myIterableClassPtr(nullptr)
46{}
47
48//------------------------------------------------------------------------------
49/// Iterator from a point.
50template <typename TIterableClass>
51DGtal::ArrayImageIterator<TIterableClass>::
52ArrayImageIterator( IterableClass* anIterableClassPtr, Domain const& aFullDomain, Domain const& aViewDomain, Point const& aPoint )
53 : myIterableClassPtr( anIterableClassPtr )
54 , myFullDomain{ aFullDomain }
55 , myViewDomain{ aViewDomain }
56 , myFullExtent( myFullDomain.upperBound() - myFullDomain.lowerBound() + Point::diagonal(1) )
57 , myViewExtent( myViewDomain.upperBound() - myViewDomain.lowerBound() + Point::diagonal(1) )
58 , myPoint{ aPoint }
59 , myFullIndex( Self::Linearizer::getIndex( myPoint - myFullDomain.lowerBound(), myFullExtent ) )
60{
61 ASSERT_MSG(
62 myFullDomain.lowerBound().isLower( myViewDomain.lowerBound() )
63 && myFullDomain.upperBound().isUpper( myViewDomain.upperBound() ),
64 "The viewable domain must be included into the full domain."
65 );
66 ASSERT_MSG(
67 myViewDomain.isInside(aPoint),
68 "The point is outside the viewable domain !"
69 );
70}
71
72//------------------------------------------------------------------------------
73/// Iterator pointing to the first value.
74template <typename TIterableClass>
75DGtal::ArrayImageIterator<TIterableClass>::
76ArrayImageIterator( IterableClass* anIterableClassPtr, Domain const& aFullDomain, Domain const& aViewDomain )
77 : ArrayImageIterator{ anIterableClassPtr, aFullDomain, aViewDomain, aViewDomain.lowerBound() }
78{}
79
80//------------------------------------------------------------------------------
81/// Iterator pointing to the first value and spanning the whole domain.
82template <typename TIterableClass>
83DGtal::ArrayImageIterator<TIterableClass>::
84ArrayImageIterator( IterableClass* anIterableClassPtr, Domain const& aFullDomain )
85 : ArrayImageIterator{ anIterableClassPtr, aFullDomain, aFullDomain }
86{}
87
88//------------------------------------------------------------------------------
89/// Iterator pointing after the last value of the viewable domain.
90template <typename TIterableClass>
91DGtal::ArrayImageIterator<TIterableClass>::
92ArrayImageIterator( IterableClass* anIterableClassPtr, Domain const& aFullDomain, Domain const& aViewDomain, bool /* last */ )
93 : ArrayImageIterator{ anIterableClassPtr, aFullDomain, aViewDomain, aViewDomain.upperBound() }
94{
95 increment();
96}
97
98//------------------------------------------------------------------------------
99/// Iterator pointing after the last value of the whole domain.
100template <typename TIterableClass>
101DGtal::ArrayImageIterator<TIterableClass>::
102ArrayImageIterator( IterableClass* anIterableClassPtr, Domain const& aFullDomain, bool /* last */ )
103 : ArrayImageIterator{ anIterableClassPtr, aFullDomain, aFullDomain, true }
104{}
105
106//------------------------------------------------------------------------------
107/// Copy constructor with type interoperability.
108template <typename TIterableClass>
109template <typename TOtherIterableClass>
110DGtal::ArrayImageIterator<TIterableClass>::
111ArrayImageIterator(
112 ArrayImageIterator<TOtherIterableClass> const& other,
113 typename std::enable_if< std::is_convertible<TOtherIterableClass*, IterableClass*>::value >::type*
114)
115 : myIterableClassPtr( other.myIterableClassPtr )
116 , myFullDomain{ other.myFullDomain }
117 , myViewDomain{ other.myViewDomain }
118 , myFullExtent{ other.myFullExtent }
119 , myViewExtent{ other.myViewExtent }
120 , myPoint{ other.myPoint }
121 , myFullIndex{ other.myFullIndex }
122{}
123
124//------------------------------------------------------------------------------
125/// Move constructor with type interoperability.
126template <typename TIterableClass>
127template <typename TOtherIterableClass>
128DGtal::ArrayImageIterator<TIterableClass>::
129ArrayImageIterator(
130 ArrayImageIterator<TOtherIterableClass> && other,
131 typename std::enable_if< std::is_convertible<TOtherIterableClass*, IterableClass*>::value >::type*
132) noexcept
133 : myIterableClassPtr( std::move(other.myIterableClassPtr) )
134 , myFullDomain{ std::move(other.myFullDomain) }
135 , myViewDomain{ std::move(other.myViewDomain) }
136 , myFullExtent{ std::move(other.myFullExtent) }
137 , myViewExtent{ std::move(other.myViewExtent) }
138 , myPoint{ std::move(other.myPoint) }
139 , myFullIndex{ std::move(other.myFullIndex) }
140{}
141
142//------------------------------------------------------------------------------
143/// Destructor.
144template <typename TIterableClass>
145DGtal::ArrayImageIterator<TIterableClass>::
146~ArrayImageIterator()
147{}
148
149//------------------------------------------------------------------------------
150/// Copy assignment with type interoperability.
151template <typename TIterableClass>
152template <typename TOtherIterableClass>
153typename std::enable_if<
154 std::is_convertible<TOtherIterableClass*, TIterableClass*>::value,
155 typename DGtal::ArrayImageIterator<TIterableClass>::Self&>::type
156DGtal::ArrayImageIterator<TIterableClass>::
157operator= ( ArrayImageIterator<TOtherIterableClass> const& other )
158{
159 myIterableClassPtr = other.myIterableClassPtr;
160 myFullDomain = other.myFullDomain;
161 myViewDomain = other.myViewDomain;
162 myFullExtent = other.myFullExtent;
163 myViewExtent = other.myViewExtent;
164 myPoint = other.myPoint;
165 myFullIndex = other.myFullIndex;
166 return *this;
167}
168
169//------------------------------------------------------------------------------
170/// Move assignment constructor with type interoperability.
171template <typename TIterableClass>
172template <typename TOtherIterableClass>
173typename std::enable_if<
174 std::is_convertible<TOtherIterableClass*, TIterableClass*>::value,
175 typename DGtal::ArrayImageIterator<TIterableClass>::Self&>::type
176DGtal::ArrayImageIterator<TIterableClass>::
177operator= ( ArrayImageIterator<TOtherIterableClass> && other )
178{
179 myIterableClassPtr = std::move(other.myIterableClassPtr);
180 myFullDomain = std::move(other.myFullDomain);
181 myViewDomain = std::move(other.myViewDomain);
182 myFullExtent = std::move(other.myFullExtent);
183 myViewExtent = std::move(other.myViewExtent);
184 myPoint = std::move(other.myPoint);
185 myFullIndex = std::move(other.myFullIndex);
186 return *this;
187}
188
189///////////////////////////////////////////////////////////////////////////////
190// Interface - public :
191
192//------------------------------------------------------------------------------
193/// Return the point behind this iterator.
194template <typename TIterableClass>
195inline
196typename DGtal::ArrayImageIterator<TIterableClass>::Point const&
197DGtal::ArrayImageIterator<TIterableClass>::
198 getPoint() const noexcept
199{
200 return myPoint;
201}
202
203//------------------------------------------------------------------------------
204/// Return the distance from this iterator to a given point.
205template <typename TIterableClass>
206inline
207std::ptrdiff_t
208DGtal::ArrayImageIterator<TIterableClass>::
209distance_to( Point const& aPoint ) const noexcept
210{
211 ASSERT_MSG(
212 myViewDomain.isInside(aPoint),
213 "The point is outside the viewable domain !"
214 );
215 return
216 static_cast<std::ptrdiff_t>( Linearizer::getIndex(aPoint, myViewDomain.lowerBound(), myViewExtent) )
217 - static_cast<std::ptrdiff_t>( Linearizer::getIndex(myPoint, myViewDomain.lowerBound(), myViewExtent) );
218}
219
220//------------------------------------------------------------------------------
221/// Writes/Displays the object on an output stream.
222template <typename TIterableClass>
223inline
224void
225DGtal::ArrayImageIterator<TIterableClass>::
226 selfDisplay ( std::ostream & out ) const
227{
228 out << "[ArrayImageIterator] pointing to " << getPoint();
229}
230
231//------------------------------------------------------------------------------
232///Checks the validity/consistency of the object.
233template <typename TIterableClass>
234inline
235bool
236DGtal::ArrayImageIterator<TIterableClass>::isValid() const
237{
238 return myIterableClassPtr != nullptr;
239}
240
241
242///////////////////////////////////////////////////////////////////////////////
243// Hidden services :
244
245//------------------------------------------------------------------------------
246/// Increment of one step.
247template <typename TIterableClass>
248void
249DGtal::ArrayImageIterator<TIterableClass>::
250increment()
251{
252 ++myFullIndex;
253 ++myPoint[0];
254 for ( auto i = 1; i < (int)Domain::dimension && myPoint[i-1] > myViewDomain.upperBound()[i-1]; ++i )
255 {
256 myPoint[i-1] = myViewDomain.lowerBound()[i-1];
257 ++myPoint[i];
258 std::size_t cum = myFullExtent[i-1] - myViewExtent[i-1];
259 for ( auto j = 0; j < i-1; ++j )
260 cum *= myFullExtent[j];
261
262 myFullIndex += cum;
263 }
264}
265
266//------------------------------------------------------------------------------
267/// Decrement of one step.
268template <typename TIterableClass>
269void
270DGtal::ArrayImageIterator<TIterableClass>::
271decrement()
272{
273 --myFullIndex;
274 --myPoint[0];
275 for ( Dimension i = 1; i < Domain::dimension && myPoint[i-1] < myViewDomain.lowerBound()[i-1]; ++i )
276 {
277 myPoint[i-1] = myViewDomain.upperBound()[i-1];
278 --myPoint[i];
279 std::size_t accum = myFullExtent[i-1] - myViewExtent[i-1];
280 for ( int j = 0; j < (int)i-1; ++j )
281 accum *= myFullExtent[j];
282
283 myFullIndex -= accum;
284 }
285}
286
287//------------------------------------------------------------------------------
288/// Equality.
289template <typename TIterableClass>
290inline
291bool
292DGtal::ArrayImageIterator<TIterableClass>::
293equal( Self const& other ) const
294{
295 return myFullIndex == other.myFullIndex;
296}
297
298//------------------------------------------------------------------------------
299/// Dereference.
300template <typename TIterableClass>
301inline
302typename DGtal::ArrayImageIterator<TIterableClass>::Reference
303DGtal::ArrayImageIterator<TIterableClass>::
304dereference() const
305{
306 return myIterableClassPtr->dereference( myPoint, myFullIndex );
307}
308
309//------------------------------------------------------------------------------
310/// Distance to other iterator.
311template <typename TIterableClass>
312inline
313std::ptrdiff_t
314DGtal::ArrayImageIterator<TIterableClass>::
315distance_to( Self const& other ) const
316{
317 return distance_to( other.myPoint );
318}
319
320//------------------------------------------------------------------------------
321/// Advance by n steps.
322template <typename TIterableClass>
323void
324DGtal::ArrayImageIterator<TIterableClass>::
325advance( std::ptrdiff_t n )
326{
327 const auto pos = Self::Linearizer::getIndex( myPoint, myViewDomain.lowerBound(), myViewExtent );
328 myPoint = Self::Linearizer::getPoint( pos + n, myViewDomain.lowerBound(), myViewExtent );
329 myFullIndex = Self::Linearizer::getIndex( myPoint, myFullDomain.lowerBound(), myFullExtent );
330}
331
332
333///////////////////////////////////////////////////////////////////////////////
334// Implementation of inline functions //
335
336template <typename T>
337inline
338std::ostream&
339DGtal::operator<< ( std::ostream & out,
340 const ArrayImageIterator<T> & object )
341{
342 object.selfDisplay( out );
343 return out;
344}
345
346// //
347///////////////////////////////////////////////////////////////////////////////
348