1 /*=========================================================================
2  *
3  *  Copyright Insight Software Consortium
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *         http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkConstSliceIterator_h
19 #define itkConstSliceIterator_h
20 
21 #include "itkMacro.h"
22 #include "itkIntTypes.h"
23 #include <valarray>
24 
25 namespace itk
26 {
27 /**
28  * \class ConstSliceIterator
29  * \brief A flexible iterator for ITK containers(i.e. itk::Neighborhood)
30  * that support pixel access through operator[].
31  *
32  * ConstSliceIterator allows const iteration along a std::slice through the
33  * container.
34  * A slice is a construct that defines a starting position, stride length
35  * (distance between adjacent elements), and a length.
36  *
37  * Any container with operator[] const is supported.  Because it uses this
38  *  interface the iterator is only as efficient as the implementation of a
39  * container's operator[] method.
40  *
41  * References:
42  * Modelled after a slice iterator proposed by Bjarne Stroustrup
43  * in C++ Programming Language, Third Edition. Bjarne Stroustrup.  Addison
44  * Wesley, Reading, MA. 1997.
45  *
46  * \ingroup Iterators
47  *
48  * \ingroup ITKCommon
49  */
50 template< typename TPixel, typename TContainer >
51 class ConstSliceIterator
52 {
53 public:
54   /** Constructor. */
ConstSliceIterator(const TContainer * n,std::slice s)55   ConstSliceIterator(const TContainer *n, std::slice s):
56     m_ContainerPointer(n), m_Pos(0), m_Slice(s) {}
57 
58   /** Returns a ConstSliceIterator that points to the beginning of the slice. */
Begin()59   ConstSliceIterator Begin()
60   {
61     ConstSliceIterator ans = *this;
62 
63     ans.m_Pos = 0;
64     return ans;
65   }
66 
67   /** Returns a ConstSliceIterator that points to one past the end
68    *  of the slice. */
End()69   ConstSliceIterator End()
70   {
71     ConstSliceIterator ans = *this;
72 
73     ans.m_Pos = static_cast< SizeValueType >( m_Slice.size() );
74     return ans;
75   }
76 
77   /** Increments the iterator. */
78   ConstSliceIterator operator++()
79   {
80     m_Pos++;
81     return *this;
82   }
83 
84   /** Increments the iterator. */
85   ConstSliceIterator operator++(int)
86   {
87     ConstSliceIterator ans  = *this;
88 
89     m_Pos++;
90     return ans;
91   }
92 
93   /** Returns the element at position n of the slice. Sets the
94    * iterator to point to position n. */
95   const TPixel & operator[](SizeValueType n)
96   {
97     return this->Loc(m_Pos = n);
98   }
99 
100   /** Dereferences the iterator, returning the value that it points
101    * to. */
102   const TPixel & operator*()
103   {
104     return Loc(m_Pos);
105   }
106 
107   /** Returns the logical && of the boolean == of two slice iterator positions,
108    * stride, and start locations. */
109   bool operator==(const ConstSliceIterator & orig)
110   {
111     return orig.m_Pos == this->m_Pos
112            &&   orig.m_Slice.stride() == this->m_Slice.stride()
113            &&   orig.m_Slice.start() == this->m_Slice.start();
114   }
115 
116   /** Returns the logical inverse of the boolean == of two slice iterators. */
117   bool operator!=(const ConstSliceIterator & orig)
118   {
119     return !operator==(orig);
120   }
121 
122   /** Returns the boolean < of two slice iterator positions.  Result
123    * is only true if the slice iterators have the same stride and
124    * start location. */
125   bool operator<(const ConstSliceIterator & orig)
126   {
127     return this->m_Pos < orig.m_Pos
128            &&   this->m_Slice.stride() == orig.m_Slice.stride()
129            &&   this->m_Slice.start() == orig.m_Slice.start();
130   }
131 
132 private:
133   /** Returns the value located at position n of the slice. */
Loc(SizeValueType n)134   const TPixel & Loc(SizeValueType n) const
135   {
136     return ( *m_ContainerPointer )[static_cast< SizeValueType >( m_Slice.start() + n * m_Slice.stride())];
137   }
138 
139   /** Pointer to the container referenced by the slice iterator. */
140   const TContainer *m_ContainerPointer;
141 
142   /** Current position within the slice. */
143   SizeValueType m_Pos;
144 
145   /** Slice structure information. */
146   std::slice m_Slice;
147 };
148 } // end namespace itk
149 
150 #endif
151