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 itkSliceIterator_h 19 #define itkSliceIterator_h 20 21 #include "itkMacro.h" 22 #include "itkIntTypes.h" 23 #include <valarray> 24 25 namespace itk 26 { 27 /** \class SliceIterator 28 * \brief A flexible iterator for itk containers(i.e. itk::Neighborhood) 29 * that support pixel access through operator[]. 30 * 31 * SliceIterator allows iteration along a std::slice through the container. 32 * A slice is a construct that defines a starting position, stride length 33 * (distance between adjacent elements), and a length. 34 * 35 * Any container with operator[] is supported. Because it uses this interface 36 * the iterator is only as efficient as the implementation of a container's 37 * operator[] method. 38 * 39 * References: 40 * Modelled after a slice iterator proposed by Bjarne Stroustrup 41 * in C++ Programming Language, Third Edition. Bjarne Stroustrup. Addison 42 * Wesley, Reading, MA. 1997. 43 * 44 * \ingroup Iterators 45 * \ingroup ITKCommon 46 */ 47 template< typename TPixel, typename TContainer > 48 class SliceIterator 49 { 50 public: 51 /** Constructor. */ SliceIterator(TContainer * n,std::slice s)52 SliceIterator(TContainer *n, std::slice s): 53 m_ContainerPointer(n), m_Pos(0), m_Slice(s) {} 54 55 /** Returns a SliceIterator that points to the beginning of the slice. */ Begin()56 SliceIterator Begin() 57 { 58 SliceIterator ans = *this; 59 60 ans.m_Pos = 0; 61 return ans; 62 } 63 64 /** Returns a SliceIterator that points to one past the end of the slice. */ End()65 SliceIterator End() 66 { 67 SliceIterator ans = *this; 68 69 ans.m_Pos = static_cast< OffsetValueType >( m_Slice.size() ); 70 return ans; 71 } 72 73 /** Increments the iterator. */ 74 SliceIterator operator++() 75 { 76 m_Pos++; 77 return *this; 78 } 79 80 /** Increments the iterator. */ 81 SliceIterator operator++(int) 82 { 83 SliceIterator ans = *this; 84 85 m_Pos++; 86 return ans; 87 } 88 89 /** Returns the element at position n of the slice. Sets the 90 * iterator to point to position n. */ 91 TPixel & operator[](OffsetValueType n) 92 { return this->Loc(m_Pos = n); } 93 94 /** Dereferences the iterator, returning the value that it points 95 * to. */ 96 TPixel & operator*() 97 { return Loc(m_Pos); } 98 99 /** Returns the logical && of the boolean == of two slice iterator positions, 100 * stride, and start locations. */ 101 bool operator==(const SliceIterator & orig) 102 { 103 return orig.m_Pos == this->m_Pos 104 && orig.m_Slice.stride() == this->m_Slice.stride() 105 && orig.m_Slice.start() == this->m_Slice.start(); 106 } 107 108 /** Returns the logical inverse of the boolean == of two slice iterators. */ 109 bool operator!=(const SliceIterator & orig) 110 { 111 return !operator==(orig); 112 } 113 114 /** Returns the boolean < of two slice iterator positions. Result 115 * is only true if the slice iterators have the same stride and 116 * start location. */ 117 bool operator<(const SliceIterator & orig) 118 { 119 return this->m_Pos < orig.m_Pos 120 && this->m_Slice.stride() == orig.m_Slice.stride() 121 && this->m_Slice.start() == orig.m_Slice.start(); 122 } 123 124 private: 125 /** Returns the value located at position n of the slice. */ Loc(OffsetValueType n)126 TPixel & Loc(OffsetValueType n) const 127 { 128 const auto start = static_cast< OffsetValueType >( m_Slice.start() ); 129 const auto stride = static_cast< OffsetValueType >( m_Slice.stride() ); 130 131 return ( *m_ContainerPointer )[start + n * stride]; 132 } 133 134 /** Pointer to the container referenced by the slice iterator. */ 135 TContainer *m_ContainerPointer; 136 137 /** Current position within the slice. */ 138 OffsetValueType m_Pos; 139 140 /** Slice structure information. */ 141 std::slice m_Slice; 142 }; 143 } // end namespace itk 144 145 #endif 146