text: /*=========================================================================
   *
   *  Copyright Insight Software Consortium
   *
   *  Licensed under the Apache License, Version 2.0 (the "License");
   *  you may not use this file except in compliance with the License.
   *  You may obtain a copy of the License at
   *
   *         http://www.apache.org/licenses/LICENSE-2.0.txt
   *
   *  Unless required by applicable law or agreed to in writing, software
   *  distributed under the License is distributed on an "AS IS" BASIS,
   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *  See the License for the specific language governing permissions and
   *  limitations under the License.
   *
   *=========================================================================*/
  #ifndef itkConstShapedNeighborhoodIterator_h
  #define itkConstShapedNeighborhoodIterator_h
  
  #include <vector>
  #include <list>
  #include "itkNeighborhoodIterator.h"
  
  namespace itk
  {
  /** \class ConstShapedNeighborhoodIterator
   *
   * \brief Const version of ShapedNeighborhoodIterator, defining iteration
   * of a local N-dimensional neighborhood of pixels across an itk::Image.
   *
   * ConstShapedNeighborhoodIterator implements the read-only methods of
   * ShapedNeighborhoodIterator.  A "shaped" neighborhood iterator is one that
   * allows you to specify which neighbor elements are active and which are
   * inactive.  See ShapedNeighborhoodIterator for more information.
   *
   * \sa Neighborhood
   *
   * \par MORE INFORMATION
   * For a complete description of the ITK Image Iterators and their API, please
   * see the Iterators chapter in the ITK Software Guide.  The ITK Software Guide
   * is available in print and as a free .pdf download from http://www.itk.org.
   *
   * \ingroup ImageIterators
   *
   * \sa ImageConstIterator \sa ConditionalConstIterator
   * \sa ConstNeighborhoodIterator \sa ConstShapedNeighborhoodIterator
   * \sa ConstSliceIterator  \sa CorrespondenceDataStructureIterator
   * \sa FloodFilledFunctionConditionalConstIterator
   * \sa FloodFilledImageFunctionConditionalConstIterator
   * \sa FloodFilledImageFunctionConditionalIterator
   * \sa FloodFilledSpatialFunctionConditionalConstIterator
   * \sa FloodFilledSpatialFunctionConditionalIterator
   * \sa ImageConstIterator \sa ImageConstIteratorWithIndex
   * \sa ImageIterator \sa ImageIteratorWithIndex
   * \sa ImageLinearConstIteratorWithIndex  \sa ImageLinearIteratorWithIndex
   * \sa ImageRandomConstIteratorWithIndex  \sa ImageRandomIteratorWithIndex
   * \sa ImageRegionConstIterator \sa ImageRegionConstIteratorWithIndex
   * \sa ImageRegionExclusionConstIteratorWithIndex
   * \sa ImageRegionExclusionIteratorWithIndex
   * \sa ImageRegionIterator  \sa ImageRegionIteratorWithIndex
   * \sa ImageRegionReverseConstIterator  \sa ImageRegionReverseIterator
   * \sa ImageReverseConstIterator  \sa ImageReverseIterator
   * \sa ImageSliceConstIteratorWithIndex  \sa ImageSliceIteratorWithIndex
   * \sa NeighborhoodIterator \sa PathConstIterator  \sa PathIterator
   * \sa ShapedNeighborhoodIterator  \sa SliceIterator
   * \sa ImageConstIteratorWithIndex
   * \ingroup ITKCommon
   */
  template< typename TImage,  typename TBoundaryCondition =
              ZeroFluxNeumannBoundaryCondition< TImage > >
  class ConstShapedNeighborhoodIterator:
    private NeighborhoodIterator< TImage, TBoundaryCondition >
  {
  public:
  
    /** Extract image type information. */
    typedef typename TImage::InternalPixelType InternalPixelType;
    typedef typename TImage::PixelType         PixelType;
  
    /** Save the image dimension. */
    itkStaticConstMacro(Dimension, unsigned int, TImage::ImageDimension);
  
    /** Standard class typedefs. */
    typedef ConstShapedNeighborhoodIterator                    Self;
    typedef NeighborhoodIterator< TImage, TBoundaryCondition > Superclass;
  
    /** Inherit typedefs from superclass */
    typedef typename Superclass::OffsetType      OffsetType;
    typedef typename OffsetType::OffsetValueType OffsetValueType;
    typedef typename Superclass::RadiusType      RadiusType;
    typedef typename Superclass::SizeType        SizeType;
    typedef typename SizeType::SizeValueType     SizeValueType;
  
    /** Typedef support for common objects */
    typedef TImage                                     ImageType;
    typedef typename TImage::RegionType                RegionType;
    typedef Index< itkGetStaticConstMacro(Dimension) > IndexType;
    typedef typename IndexType::IndexValueType         IndexValueType;
    typedef Neighborhood< PixelType, itkGetStaticConstMacro(Dimension) >
    NeighborhoodType;
  
    typedef typename NeighborhoodType::NeighborIndexType  NeighborIndexType;
  
    /** An stl storage container type that can be sorted.  The type used for
     *  the list of active offsets in the neighborhood. */
    typedef std::list< NeighborIndexType >             IndexListType;
  
    typedef typename IndexListType::iterator        IndexListIterator;
    typedef typename IndexListType::const_iterator  IndexListConstIterator;
  
    /** Typedef for boundary condition type. */
    typedef TBoundaryCondition BoundaryConditionType;
  
    /** Typedef for generic boundary condition pointer */
    typedef ImageBoundaryCondition< ImageType > *ImageBoundaryConditionPointerType;
  
    /** Const Interator */
    struct ConstIterator {
      ConstIterator() { m_NeighborhoodIterator = ITK_NULLPTR; }
      ConstIterator(Self *s)
      {
        m_NeighborhoodIterator = s;
        this->GoToBegin();
      }
  
      virtual ~ConstIterator() {}
  
      ConstIterator & operator=(const ConstIterator & o)
      {
        m_NeighborhoodIterator = o.m_NeighborhoodIterator;
        m_ListIterator = o.m_ListIterator;
        return *this;
      }
  
      ConstIterator(const ConstIterator & o)
      {
        m_NeighborhoodIterator = o.m_NeighborhoodIterator;
        m_ListIterator = o.m_ListIterator;
      }
  
      void operator++(int)
      { m_ListIterator++; }
  
      void operator--(int)
      { m_ListIterator--; }
  
      const ConstIterator & operator++()
      {
        m_ListIterator++;
        return *this;
      }
  
      const ConstIterator & operator--()
      {
        m_ListIterator--;
        return *this;
      }
  
      bool operator!=(const ConstIterator & o) const
      { return m_ListIterator != o.m_ListIterator; }
      bool operator==(const ConstIterator & o) const
      { return m_ListIterator == o.m_ListIterator; }
  
      bool IsAtEnd() const
      {
        if ( m_ListIterator == m_NeighborhoodIterator->GetActiveIndexList().end() )
          {
          return true;
          }
        else
          {
          return false;
          }
      }
  
      void GoToBegin()
      {
        m_ListIterator = m_NeighborhoodIterator->GetActiveIndexList().begin();
      }
  
      void GoToEnd()
      {
        m_ListIterator = m_NeighborhoodIterator->GetActiveIndexList().end();
      }
  
      PixelType Get() const
      { return m_NeighborhoodIterator->GetPixel(*m_ListIterator); }
  
      OffsetType GetNeighborhoodOffset() const
      { return m_NeighborhoodIterator->GetOffset(*m_ListIterator); }
  
      typename IndexListType::value_type GetNeighborhoodIndex() const
      { return *m_ListIterator; }
  
  protected:
  
      Self *m_NeighborhoodIterator;
  
      typename IndexListType::const_iterator m_ListIterator;
  
      void ProtectedSet(const PixelType & v) const
      { m_NeighborhoodIterator->SetPixel(*m_ListIterator, v); }
    };
  
    /** Returns a const iterator for the neighborhood which points to the first
     * pixel in the neighborhood. */
    const ConstIterator & Begin() const
    { return m_ConstBeginIterator; }
  
    /** Returns a const iterator for the neighborhood which points to the last
     * pixel in the neighborhood. */
    const ConstIterator & End() const
    { return m_ConstEndIterator; }
  
    /** Default constructor */
    ConstShapedNeighborhoodIterator()
    {
      InitializeConstShapedNeighborhoodIterator();
    }
  
    /** Initialize the iterator. */
    void InitializeConstShapedNeighborhoodIterator()
    {
      m_ConstBeginIterator = ConstIterator(this);
      m_ConstEndIterator = ConstIterator(this);
      m_ConstEndIterator.GoToEnd();
      m_CenterIsActive = false;
    }
  
    /** Virtual destructor */
    virtual ~ConstShapedNeighborhoodIterator()  {}
  
    /** Constructor which establishes the region size, neighborhood, and image
     * over which to walk. */
    ConstShapedNeighborhoodIterator(const SizeType & radius,
                                    const ImageType *ptr,
                                    const RegionType & region):
      Superclass (radius, const_cast< ImageType * >( ptr ), region)
    {
      InitializeConstShapedNeighborhoodIterator();
    }
  
    // Expose the following methods from the superclass.  This is a
    // restricted subset of the methods available for
    // ConstNeighborhoodIterator.
    using Superclass::GetImagePointer;
    using Superclass::GetRadius;
    using Superclass::GetIndex;
    using Superclass::GetNeighborhoodIndex;
    using Superclass::GetCenterNeighborhoodIndex;
    using Superclass::GetRegion;
    using Superclass::GetBeginIndex;
    using Superclass::GoToBegin;
    using Superclass::GoToEnd;
    using Superclass::IsAtBegin;
    using Superclass::IsAtEnd;
    using Superclass::GetOffset;
    using Superclass::operator==;
    using Superclass::operator!=;
    using Superclass::operator<;
    using Superclass::operator>;
    using Superclass::operator>=;
    using Superclass::operator<=;
    using Superclass::operator[];
    using Superclass::GetElement;
    using Superclass::SetLocation;
    using Superclass::GetCenterPointer;
    using Superclass::GetCenterPixel;
    using Superclass::OverrideBoundaryCondition;
    using Superclass::ResetBoundaryCondition;
    using Superclass::GetBoundaryCondition;
    using Superclass::GetNeedToUseBoundaryCondition;
    using Superclass::SetNeedToUseBoundaryCondition;
    using Superclass::NeedToUseBoundaryConditionOn;
    using Superclass::NeedToUseBoundaryConditionOff;
    using Superclass::Print;
    using Superclass::operator-;
    using Superclass::GetPixel;
    using Superclass::SetRegion;
  
    /** Assignment operator */
    Self & operator=(const Self & orig)
    {
      if(this != &orig)
        {
        Superclass::operator=(orig);
        m_ActiveIndexList = orig.m_ActiveIndexList;
        m_CenterIsActive = orig.m_CenterIsActive;
  
        // Reset begin and end pointers
        m_ConstBeginIterator.GoToBegin();
        m_ConstEndIterator.GoToBegin();
        }
      return *this;
    }
  
    /** Standard itk print method */
    virtual void PrintSelf(std::ostream &, Indent) const;
  
    /** Add/Remove a neighborhood offset (from the center of the neighborhood)
     *  to/from the active list.  Active list offsets are the only locations
     *  updated and accessible through the iterator.  */
    virtual void ActivateOffset(const OffsetType & off)
    { this->ActivateIndex( Superclass::GetNeighborhoodIndex(off) ); }
    virtual void DeactivateOffset(const OffsetType & off)
    { this->DeactivateIndex( Superclass::GetNeighborhoodIndex(off) ); }
  
    /** Removes all active pixels from this neighborhood. */
    virtual void ClearActiveList()
    {
      m_ActiveIndexList.clear();
      m_ConstBeginIterator.GoToBegin();
      m_ConstEndIterator.GoToEnd();
      m_CenterIsActive = false;
    }
  
    /** Returns the list of active indices in the neighborhood */
    const IndexListType & GetActiveIndexList() const
    { return m_ActiveIndexList; }
  
    /** Returns the size of the list of active neighborhood indices. */
    typename IndexListType::size_type GetActiveIndexListSize() const
    { return m_ActiveIndexList.size(); }
  
    /** Add non-zero neighborhood offsets to the active list. The
      * radius of the neighborhood must match the radius of the shaped
      * iterator */
    void CreateActiveListFromNeighborhood(const NeighborhoodType &);
  
    /** Reimplements the operator++ method so that only active pixel locations
     * are updated. */
    Self & operator++();
  
    /** Reimplements the operator-- method so that only active pixel locations
     * are updated. */
    Self & operator--();
  
    /** Addition of an itk::Offset.  Note that this method does not do any bounds
     * checking.  Adding an offset that moves the iterator out of its assigned
     * region will produce undefined results. */
    Self & operator+=(const OffsetType &);
  
    /** Subtraction of an itk::Offset. Note that this method does not do
     *  any bounds checking.  Subtracting an offset that moves the iterator
     *  out of its assigned region will produce undefined results. */
    Self & operator-=(const OffsetType &);
  
  protected:
    using Superclass::SetPixel;
    using Superclass::SetCenterPixel;
    /** Copy constructor */
    ConstShapedNeighborhoodIterator(const ConstShapedNeighborhoodIterator &) ITK_DELETE_FUNCTION;
  
    friend struct ConstIterator;
  
    /** Class is protected here so that it is not publicly accessible, but can be
     * accessed by subclasses.. */
    //  Superclass::SetPixel;
    //  Superclass::SetCenterPixel;
  
    /** Add/Remove a neighborhood index to/from the active.  Locations in the
        active list are the only accessible elements in the neighborhood. The
        argument is an index location calculated as an offset into a linear
        array which represents the image region defined by the radius of this
        iterator, with the smallest dimension as the fastest increasing index. */
    virtual void ActivateIndex( NeighborIndexType );
  
    virtual void DeactivateIndex( NeighborIndexType );
  
    bool          m_CenterIsActive;
    IndexListType m_ActiveIndexList;
    ConstIterator m_ConstEndIterator;
    ConstIterator m_ConstBeginIterator;
  };
  } // namespace itk
  
  #ifndef ITK_MANUAL_INSTANTIATION
  #include "itkConstShapedNeighborhoodIterator.hxx"
  #endif
  
  #endif
  