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