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 itkConstNeighborhoodIterator_h
19 #define itkConstNeighborhoodIterator_h
20 
21 #include <vector>
22 #include <cstring>
23 #include <iostream>
24 #include "itkImage.h"
25 #include "itkNeighborhood.h"
26 #include "itkMacro.h"
27 #include "itkZeroFluxNeumannBoundaryCondition.h"
28 
29 namespace itk
30 {
31 /** \class ConstNeighborhoodIterator
32  *
33  * \brief Const version of NeighborhoodIterator, defining iteration of a local
34  * N-dimensional neighborhood of pixels across an itk::Image.
35  *
36  * ConstNeighborhoodIterator implements the read-only methods of
37  * NeighborhoodIterator.  It serves as a base class from which other iterators
38  * are derived. See NeighborhoodIterator for more complete information.
39  *
40  * \ingroup ImageIterators
41  *
42  * \sa Neighborhood \sa ImageIterator \sa NeighborhoodIterator
43  * \ingroup ITKCommon
44  *
45  * \wiki
46  * \wikiexample{Iterators/ConstNeighborhoodIterator,Iterate over a region of an image with a neighborhood (without write access)}
47  * \endwiki
48  */
49 template< typename TImage,  typename TBoundaryCondition =
50             ZeroFluxNeumannBoundaryCondition< TImage > >
51 class ITK_TEMPLATE_EXPORT ConstNeighborhoodIterator:
52   public Neighborhood< typename TImage::InternalPixelType *,
53                        TImage::ImageDimension >
54 {
55 public:
56   /** Extract image type information. */
57   using InternalPixelType = typename TImage::InternalPixelType;
58   using PixelType = typename TImage::PixelType;
59 
60   /** Type used to refer to space dimensions */
61   using DimensionValueType = unsigned int;
62 
63   /** Save the image dimension. */
64   static constexpr DimensionValueType Dimension = TImage::ImageDimension;
65 
66   /** Standard class type aliases. */
67   using Self = ConstNeighborhoodIterator;
68   using Superclass = Neighborhood< InternalPixelType *,
69                         Self::Dimension >;
70 
71   /** Inherit type alias from superclass */
72   using OffsetType = typename Superclass::OffsetType;
73   using RadiusType = typename Superclass::RadiusType;
74   using SizeType = typename Superclass::SizeType;
75   using Iterator = typename Superclass::Iterator;
76   using ConstIterator = typename Superclass::ConstIterator;
77 
78   /** Typedef support for common objects */
79   using ImageType = TImage;
80   using RegionType = typename TImage::RegionType;
81   using IndexType = Index< Self::Dimension >;
82   using NeighborhoodType = Neighborhood< PixelType, Self::Dimension >;
83 
84 
85   /** Typedef for boundary condition type. */
86   using BoundaryConditionType = TBoundaryCondition;
87 
88   using OutputImageType = typename  BoundaryConditionType::OutputImageType;
89 
90   /** Type used to refer to the elements in the list of neighbor pixels. */
91   using NeighborIndexType = typename NeighborhoodType::NeighborIndexType;
92 
93   /** Typedef for the functor used to access neighborhoods of pixel pointers.
94    * This is obtained as a trait from the image and is different for Image
95    * and VectorImage. */
96   using NeighborhoodAccessorFunctorType = typename ImageType::NeighborhoodAccessorFunctorType;
97 
98   /** Typedef for generic boundary condition pointer */
99   using ImageBoundaryConditionPointerType = ImageBoundaryCondition<ImageType, OutputImageType> *;
100   using ImageBoundaryConditionConstPointerType = const ImageBoundaryCondition<ImageType, OutputImageType> *;
101 
102   /** Default constructor */
103   ConstNeighborhoodIterator();
104 
105   /** Virtual destructor */
106   ~ConstNeighborhoodIterator() override = default;
107 
108   /** Copy constructor */
109   ConstNeighborhoodIterator(const ConstNeighborhoodIterator &);
110 
111   /** Constructor which establishes the region size, neighborhood, and image
112    * over which to walk. */
ConstNeighborhoodIterator(const SizeType & radius,const ImageType * ptr,const RegionType & region)113   ConstNeighborhoodIterator(const SizeType & radius,
114                             const ImageType *ptr,
115                             const RegionType & region)
116   {
117     this->Initialize(radius, ptr, region);
118     for ( DimensionValueType i = 0; i < Dimension; i++ )
119               { m_InBounds[i] = false; }
120     this->ResetBoundaryCondition();
121     m_NeighborhoodAccessorFunctor = ptr->GetNeighborhoodAccessor();
122     m_NeighborhoodAccessorFunctor.SetBegin( ptr->GetBufferPointer() );
123   }
124 
125   /** Assignment operator */
126   Self & operator=(const Self & orig);
127 
128   /** Standard itk print method */
129   void PrintSelf(std::ostream &, Indent) const override;
130 
131   /** Computes the internal, N-d offset of a pixel array position n from
132    * (0,0, ..., 0) in the "upper-left" corner of the neighborhood. */
133   OffsetType ComputeInternalIndex(const NeighborIndexType n) const;
134 
135   /** Returns the array of upper loop bounds used during iteration. */
GetBound()136   IndexType GetBound() const
137   {    return m_Bound;   }
138 
139   /** Returns the loop bound used to define the edge of a single
140    * dimension in the itk::Image region. */
GetBound(NeighborIndexType n)141   IndexValueType GetBound(NeighborIndexType n) const
142   {    return m_Bound[n];  }
143 
144   /** Returns the pointer to the center pixel of the neighborhood. */
GetCenterPointer()145   const InternalPixelType * GetCenterPointer() const
146   {    return ( this->operator[]( ( this->Size() ) >> 1 ) );  }
147 
148   /** Returns the pixel referenced at the center of the
149    *  ConstNeighborhoodIterator. */
GetCenterPixel()150   PixelType GetCenterPixel() const
151   { return m_NeighborhoodAccessorFunctor.Get( this->GetCenterPointer() ); }
152 
153   /** Returns a smartpointer to the image on which this iterator operates. */
GetImagePointer()154   const ImageType * GetImagePointer() const
155   { return m_ConstImage; }
156 
157   /** Returns the N-dimensional index of the iterator's position in
158    * the image. */
GetIndex()159   ITK_ITERATOR_VIRTUAL IndexType GetIndex() const ITK_ITERATOR_FINAL
160   { return m_Loop;  }
161 
GetFastIndexPlusOffset(const OffsetType & o)162   inline IndexType GetFastIndexPlusOffset(const OffsetType & o) const
163     { return m_Loop + o; }
164 
165   /** Function that "dereferences" a ConstNeighborhoodIterator,
166    * returning a Neighborhood of pixel values. */
167   ITK_ITERATOR_VIRTUAL NeighborhoodType GetNeighborhood() const ITK_ITERATOR_FINAL;
168 
169   /** Returns the pixel value located at a linear array location i. */
GetPixel(const NeighborIndexType i)170   ITK_ITERATOR_VIRTUAL PixelType GetPixel(const NeighborIndexType i) const ITK_ITERATOR_FINAL
171   {
172     if ( !m_NeedToUseBoundaryCondition || this->InBounds() )
173       {
174       return ( m_NeighborhoodAccessorFunctor.Get( this->operator[](i) ) );
175       }
176 
177     OffsetType internalIndex;
178     OffsetType offset;
179 
180     return this->IndexInBounds(i, internalIndex, offset) ?
181       m_NeighborhoodAccessorFunctor.Get(this->operator[](i)) :
182       m_NeighborhoodAccessorFunctor.BoundaryCondition(internalIndex, offset, this, m_BoundaryCondition);
183   }
184 
185   /** Return the pixel value located at a linear array location i.
186    * Sets "IsInBounds" to true if the location is inside the
187    * image and the pixel value returned is an actual pixel in the
188    * image. Sets "IsInBounds" to false if the location is outside the
189    * image and the pixel value returned is a boundary condition. */
190   ITK_ITERATOR_VIRTUAL PixelType GetPixel(NeighborIndexType i, bool & IsInBounds) const ITK_ITERATOR_FINAL;
191 
192   /** Returns the pixel value located at the itk::Offset o from the center of
193       the neighborhood. */
GetPixel(const OffsetType & o)194   ITK_ITERATOR_VIRTUAL PixelType GetPixel(const OffsetType & o) const ITK_ITERATOR_FINAL
195   {
196     bool inbounds;
197 
198     return ( this->GetPixel(this->GetNeighborhoodIndex(o), inbounds) );
199   }
200 
201   /** Returns the pixel value located at the itk::Offset o from the center of
202    * the neighborhood. Sets "IsInBounds" to true if the offset is inside the
203    * image and the pixel value returned is an actual pixel in the
204    * image. Sets "IsInBounds" to false if the offset is outside the
205    * image and the pixel value returned is a boundary condition. */
GetPixel(const OffsetType & o,bool & IsInBounds)206   ITK_ITERATOR_VIRTUAL PixelType GetPixel(const OffsetType & o,
207                              bool & IsInBounds) const ITK_ITERATOR_FINAL
208   { return ( this->GetPixel(this->GetNeighborhoodIndex(o), IsInBounds) ); }
209 
210   /** Returns the pixel value located i pixels distant from the neighborhood
211    *  center in the positive specified "axis" direction. No bounds checking
212    *  is done on the size of the neighborhood. */
GetNext(const unsigned axis,NeighborIndexType i)213   ITK_ITERATOR_VIRTUAL PixelType GetNext(const unsigned axis, NeighborIndexType i) const ITK_ITERATOR_FINAL
214   {
215     return ( this->GetPixel( this->GetCenterNeighborhoodIndex()
216                              + ( i * this->GetStride(axis) ) ) );
217   }
218 
219   /** Returns the pixel value located one pixel distant from the neighborhood
220    *  center in the specifed positive axis direction. No bounds checking is
221    *  done on the size of the neighborhood. */
GetNext(const unsigned axis)222   ITK_ITERATOR_VIRTUAL PixelType GetNext(const unsigned axis) const ITK_ITERATOR_FINAL
223   {
224     return ( this->GetPixel( this->GetCenterNeighborhoodIndex()
225                              + this->GetStride(axis) ) );
226   }
227 
228   /** Returns the pixel value located i pixels distant from the neighborhood
229    *  center in the negative specified "axis" direction. No bounds checking
230    *  is done on the size of the neighborhood. */
GetPrevious(const unsigned axis,NeighborIndexType i)231   ITK_ITERATOR_VIRTUAL PixelType GetPrevious(const unsigned axis, NeighborIndexType i) const ITK_ITERATOR_FINAL
232   {
233     return ( this->GetPixel( this->GetCenterNeighborhoodIndex()
234                              - ( i * this->GetStride(axis) ) ) );
235   }
236 
237   /** Returns the pixel value located one pixel distant from the neighborhood
238    *  center in the specifed negative axis direction. No bounds checking is
239    *  done on the size of the neighborhood. */
GetPrevious(const unsigned axis)240   ITK_ITERATOR_VIRTUAL PixelType GetPrevious(const unsigned axis) const ITK_ITERATOR_FINAL
241   {
242     return ( this->GetPixel( this->GetCenterNeighborhoodIndex()
243                              - this->GetStride(axis) ) );
244   }
245 
246   /** Returns the image index for neighbor pixel at offset o from the center of
247       the neighborhood. */
GetIndex(const OffsetType & o)248   ITK_ITERATOR_VIRTUAL IndexType GetIndex(const OffsetType & o) const ITK_ITERATOR_FINAL
249   { return ( this->GetIndex() + o ); }
250 
251   /** Returns the image index for neighbor pixel at index i in the
252       neighborhood. */
GetIndex(NeighborIndexType i)253   ITK_ITERATOR_VIRTUAL IndexType GetIndex(NeighborIndexType i) const ITK_ITERATOR_FINAL
254   { return ( this->GetIndex() + this->GetOffset(i) ); }
255 
256   /**  Returns the region of iteration. */
GetRegion()257   RegionType GetRegion() const
258   { return m_Region; }
259 
260   /** Returns the N-dimensional starting index of the iterator's position on
261    * the image. */
GetBeginIndex()262   IndexType GetBeginIndex() const
263   { return m_BeginIndex; }
264 
265   /** Returns a bounding box for the region spanned by this neighborhood
266       represented by an itk::ImageRegion */
267   RegionType GetBoundingBoxAsImageRegion() const;
268 
269   /** Returns the offsets used to wrap across dimensional boundaries. */
GetWrapOffset()270   OffsetType GetWrapOffset() const
271   {  return m_WrapOffset;  }
272 
273   /** Returns the internal offset associated with wrapping around a single
274    * dimension's region boundary in the itk::Image.  An offset for each
275    * dimension is necessary to shift pointers when wrapping around region
276    * edges because region memory is not necessarily contiguous within the
277    * buffer. */
GetWrapOffset(NeighborIndexType n)278   OffsetValueType GetWrapOffset(NeighborIndexType n) const
279   {    return m_WrapOffset[n];   }
280 
281   /** Method for rewinding the iterator to its beginning pixel. */
282   ITK_ITERATOR_VIRTUAL void GoToBegin() ITK_ITERATOR_FINAL;
283 
284   /** Method for sending the iterator to one past the last pixel in its
285    * region. */
286   ITK_ITERATOR_VIRTUAL void GoToEnd() ITK_ITERATOR_FINAL;
287 
288   /** Initializes the iterator to walk a particular image and a particular
289    * region of that image. */
290   ITK_ITERATOR_VIRTUAL void Initialize(const SizeType & radius, const ImageType *ptr,
291                                        const RegionType & region) ITK_ITERATOR_FINAL;
292 
293   /** Method for determining whether the iterator is at the
294    * beginning of its iteration region. */
IsAtBegin()295   ITK_ITERATOR_VIRTUAL bool IsAtBegin() const ITK_ITERATOR_FINAL
296   {    return ( this->GetCenterPointer() == m_Begin );   }
297 
298   /** Method for determining whether the iterator has reached the
299    * end of its iteration region. */
IsAtEnd()300   ITK_ITERATOR_VIRTUAL bool IsAtEnd() const ITK_ITERATOR_FINAL
301   {
302     if ( this->GetCenterPointer() > m_End )
303       {
304       ExceptionObject    e(__FILE__, __LINE__);
305       std::ostringstream msg;
306       msg << "In method IsAtEnd, CenterPointer = " << this->GetCenterPointer()
307           << " is greater than End = " << m_End
308           << std::endl
309           << "  " << *this;
310       e.SetDescription( msg.str().c_str() );
311       throw e;
312       }
313     return ( this->GetCenterPointer() == m_End );
314   }
315 
316   /** Increments the pointers in the ConstNeighborhoodIterator,
317    * wraps across boundaries automatically, accounting for
318    * the disparity in the buffer size and the region size of the
319    * image. */
320   Self & operator++();
321 
322   /** Decrements the pointers in the ConstNeighborhoodIterator,
323    * wraps across boundaries automatically, accounting for
324    * the disparity in the buffer size and the region size of the
325    * image. */
326   Self & operator--();
327 
328   /** Returns a boolean == comparison of the memory addresses of the center
329    * elements of two ConstNeighborhoodIterators of like pixel type and
330    * dimensionality.  The radii of the iterators are ignored. */
331   bool operator==(const Self & it) const
332   {   return it.GetCenterPointer() == this->GetCenterPointer();   }
333 
334   /** Returns a boolean != comparison of the memory addresses of the center
335    * elements of two ConstNeighborhoodIterators of like pixel type and
336    * dimensionality.  The radii of the iterators are ignored. */
337   bool operator!=(const Self & it) const
338   {    return it.GetCenterPointer() != this->GetCenterPointer();  }
339 
340   /** Returns a boolean < comparison of the memory addresses of the center
341    * elements of two ConstNeighborhoodIterators of like pixel type and
342    * dimensionality.  The radii of the iterators are ignored. */
343   bool operator<(const Self & it) const
344   {  return this->GetCenterPointer() < it.GetCenterPointer();  }
345 
346   /** Returns a boolean < comparison of the memory addresses of the center
347    * elements of two ConstNeighborhoodIterators of like pixel type and
348    * dimensionality.  The radii of the iterators are ignored. */
349   bool operator<=(const Self & it) const
350   {    return this->GetCenterPointer() <= it.GetCenterPointer();  }
351 
352   /** Returns a boolean > comparison of the memory addresses of the center
353    * elements of two ConstNeighborhoodIterators of like pixel type and
354    * dimensionality.  The radii of the iterators are ignored. */
355   bool operator>(const Self & it) const
356   {    return this->GetCenterPointer() > it.GetCenterPointer();  }
357 
358   /** Returns a boolean >= comparison of the memory addresses of the center
359    * elements of two ConstNeighborhoodIterators of like pixel type and
360    * dimensionality.  The radii of the iterators are ignored. */
361   bool operator>=(const Self & it) const
362   {    return this->GetCenterPointer() >= it.GetCenterPointer();  }
363 
364   /** This method positions the iterator at an indexed location in the
365    * image. SetLocation should _NOT_ be used to update the position of the
366    * iterator during iteration, only for initializing it to a position
367    * prior to iteration.  This method is not optimized for speed. */
SetLocation(const IndexType & position)368   void SetLocation(const IndexType & position)
369   {
370     this->SetLoop(position);
371     this->SetPixelPointers(position);
372   }
373 
374   /** Addition of an itk::Offset.  Note that this method does not do any bounds
375    * checking.  Adding an offset that moves the iterator out of its assigned
376    * region will produce undefined results. */
377   Self & operator+=(const OffsetType &);
378 
379   /** Subtraction of an itk::Offset. Note that this method does not do any
380    *  bounds checking.  Subtracting an offset that moves the iterator out
381    * of its assigned region will produce undefined results. */
382   Self & operator-=(const OffsetType &);
383 
384   /** Distance between two iterators */
385   OffsetType operator-(const Self & b)
386   {  return m_Loop - b.m_Loop;  }
387 
388   /** Returns false if the iterator overlaps region boundaries, true
389    * otherwise.  Also updates an internal boolean array indicating
390    * which of the iterator's faces are out of bounds. */
391   bool InBounds() const;
392 
393   /** Returns true if the neighborhood index is within region boundaries,
394    * false otherwise.
395    * If false, then internalIndex and offset are calculated. Otherwise their
396    * values are left unchanged.
397    * Also updates an internal boolean array indicating
398    * which of the iterator's faces are out of bounds.
399    * \param n - linear neighborhood index.
400    * \param internalIndex - calculated for index \c n only when the neighborhood is not
401    * completely within region boundaries.
402    * \param offset - per-dimension offsets for index n to nearest boundary index,
403    * calculate only when the neighborhood is not completely within region boundaries. */
404   bool IndexInBounds(const NeighborIndexType n, OffsetType & internalIndex, OffsetType & offset ) const;
405 
406   /** Returns true if the neighborhood index is within region boundaries,
407    * false otherwise. */
408   bool IndexInBounds(const NeighborIndexType n ) const;
409 
410   /** Allows a user to override the internal boundary condition. Care should
411    * be taken to ensure that the overriding boundary condition is a persistent
412    * object during the time it is referenced.  The overriding condition
413    * can be of a different type than the default type as long as it is
414    * a subclass of ImageBoundaryCondition. */
OverrideBoundaryCondition(const ImageBoundaryConditionPointerType i)415   ITK_ITERATOR_VIRTUAL void OverrideBoundaryCondition(const
416                                          ImageBoundaryConditionPointerType i) ITK_ITERATOR_FINAL
417   { m_BoundaryCondition = i; }
418 
419   /** Resets the boundary condition to the internal, default conditions
420    * specified by the template parameter. */
ResetBoundaryCondition()421   ITK_ITERATOR_VIRTUAL void ResetBoundaryCondition() ITK_ITERATOR_FINAL
422   { m_BoundaryCondition = &m_InternalBoundaryCondition; }
423 
424   /** Sets the internal, default boundary condition. */
SetBoundaryCondition(const TBoundaryCondition & c)425   void SetBoundaryCondition(const TBoundaryCondition & c)
426   { m_InternalBoundaryCondition = c; }
427 
428   /** */
GetBoundaryCondition()429   ImageBoundaryConditionPointerType GetBoundaryCondition() const
430   { return m_BoundaryCondition; }
431 
432   /** */
NeedToUseBoundaryConditionOn()433   void NeedToUseBoundaryConditionOn()
434   {
435     this->SetNeedToUseBoundaryCondition(true);
436   }
437 
NeedToUseBoundaryConditionOff()438   void NeedToUseBoundaryConditionOff()
439   {
440     this->SetNeedToUseBoundaryCondition(false);
441   }
442 
SetNeedToUseBoundaryCondition(bool b)443   void SetNeedToUseBoundaryCondition(bool b)
444   {
445     m_NeedToUseBoundaryCondition = b;
446   }
447 
GetNeedToUseBoundaryCondition()448   bool GetNeedToUseBoundaryCondition() const
449   {
450     return m_NeedToUseBoundaryCondition;
451   }
452 
453   /** Set the region to iterate over. */
454   ITK_ITERATOR_VIRTUAL void SetRegion(const RegionType & region) ITK_ITERATOR_FINAL;
455 
456 protected:
457 
458   /** Default method for setting the coordinate location of the iterator.
459    * Loop indices correspond to the actual Image region index. */
SetLoop(const IndexType & p)460   ITK_ITERATOR_VIRTUAL void SetLoop(const IndexType & p) ITK_ITERATOR_FINAL
461   {  m_Loop = p; m_IsInBoundsValid = false; }
462 
463   /** Method for setting internal loop boundaries.  This
464    * method must be defined in each subclass because
465    * each subclass may handle loop boundaries differently. */
466   ITK_ITERATOR_VIRTUAL void SetBound(const SizeType &) ITK_ITERATOR_FINAL;
467 
468   /** Default method for setting the values of the internal pointers
469    * to itk::Image memory buffer locations.  This method should
470    * generally only be called when the iterator is initialized.
471    * \sa SetLocation */
472   ITK_ITERATOR_VIRTUAL void SetPixelPointers(const IndexType &) ITK_ITERATOR_FINAL;
473 
474   /** Default method for setting the index of the first pixel in the
475    * iteration region. */
SetBeginIndex(const IndexType & start)476   ITK_ITERATOR_VIRTUAL void SetBeginIndex(const IndexType & start) ITK_ITERATOR_FINAL
477   {  m_BeginIndex = start;  }
478 
479   /** Default method for setting the index of the first pixel in the
480    * iteration region. */
481   ITK_ITERATOR_VIRTUAL void SetEndIndex() ITK_ITERATOR_FINAL;
482 
483   /** The starting index for iteration within the itk::Image region
484    * on which this ConstNeighborhoodIterator is defined. */
485   IndexType m_BeginIndex;
486 
487   /** An array of upper looping boundaries used during iteration. */
488   IndexType m_Bound;
489 
490   /** A pointer to the first pixel in the iteration region. */
491   const InternalPixelType *m_Begin;
492 
493   /** The image on which iteration is defined. */
494   typename ImageType::ConstWeakPointer m_ConstImage;
495 
496   /** A pointer to one past the last pixel in the iteration region. */
497   const InternalPixelType *m_End;
498 
499   /** The end index for iteration within the itk::Image region
500    * on which this ConstNeighborhoodIterator is defined. */
501   IndexType m_EndIndex;
502 
503   /** Array of loop counters used during iteration. */
504   IndexType m_Loop;
505 
506   /** The region over which iteration is defined. */
507   RegionType m_Region;
508 
509   /** The internal array of offsets that provide support for regions of
510    *  interest.
511    *  An offset for each dimension is necessary to shift pointers when wrapping
512    *  around region edges because region memory is not necessarily contiguous
513    *  within the buffer. */
514   OffsetType m_WrapOffset;
515 
516   /** Pointer to the actual boundary condition that will be used.
517    * By default this points to m_BoundaryCondition, but
518    * OverrideBoundaryCondition allows a user to point this variable an external
519    * boundary condition.  */
520   ImageBoundaryConditionPointerType m_BoundaryCondition;
521 
522   /** Denotes which of the iterators dimensional sides spill outside
523    * region of interest boundaries. */
524   mutable bool m_InBounds[Dimension];
525 
526   /** Denotes if iterator is entirely within bounds */
527   mutable bool m_IsInBounds{false};
528 
529   /** Is the m_InBounds and m_IsInBounds variables up to date? Set to
530    * false whenever the iterator is repositioned.  Set to true within
531    * InBounds(). */
532   mutable bool m_IsInBoundsValid{false};
533 
534   /** Lower threshold of in-bounds loop counter values. */
535   IndexType m_InnerBoundsLow;
536 
537   /** Upper threshold of in-bounds loop counter values. */
538   IndexType m_InnerBoundsHigh;
539 
540   /** Default boundary condition. */
541   TBoundaryCondition m_InternalBoundaryCondition;
542 
543   /** Does the specified region need to worry about boundary conditions? */
544   bool m_NeedToUseBoundaryCondition{false};
545 
546   /** Functor type used to access neighborhoods of pixel pointers */
547   NeighborhoodAccessorFunctorType m_NeighborhoodAccessorFunctor;
548 };
549 
550 template< typename TImage >
551 inline ConstNeighborhoodIterator< TImage >
552 operator+(const ConstNeighborhoodIterator< TImage > & it,
553           const typename ConstNeighborhoodIterator< TImage >::OffsetType & ind)
554 {
555   ConstNeighborhoodIterator< TImage > ret ( it );
556   ret += ind;
557   return ret;
558 }
559 
560 template< typename TImage >
561 inline ConstNeighborhoodIterator< TImage >
562 operator+(const typename ConstNeighborhoodIterator< TImage >::OffsetType & ind,
563           const ConstNeighborhoodIterator< TImage > & it)
564 {  return ( it + ind ); }
565 
566 template< typename TImage >
567 inline ConstNeighborhoodIterator< TImage >
568 operator-(const ConstNeighborhoodIterator< TImage > & it,
569           const typename ConstNeighborhoodIterator< TImage >
570           ::OffsetType & ind)
571 {
572   ConstNeighborhoodIterator< TImage > ret(it);
573   ret -= ind;
574   return ret;
575 }
576 } // namespace itk
577 
578 #ifndef ITK_MANUAL_INSTANTIATION
579 #include "itkConstNeighborhoodIterator.hxx"
580 #endif
581 
582 #endif
583