ITK  4.1.0
Insight Segmentation and Registration Toolkit
itkPreOrderTreeIterator.h
Go to the documentation of this file.
00001 /*=========================================================================
00002  *
00003  *  Copyright Insight Software Consortium
00004  *
00005  *  Licensed under the Apache License, Version 2.0 (the "License");
00006  *  you may not use this file except in compliance with the License.
00007  *  You may obtain a copy of the License at
00008  *
00009  *         http://www.apache.org/licenses/LICENSE-2.0.txt
00010  *
00011  *  Unless required by applicable law or agreed to in writing, software
00012  *  distributed under the License is distributed on an "AS IS" BASIS,
00013  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  *  See the License for the specific language governing permissions and
00015  *  limitations under the License.
00016  *
00017  *=========================================================================*/
00018 #ifndef __itkPreOrderTreeIterator_h
00019 #define __itkPreOrderTreeIterator_h
00020 
00021 #include "itkTreeIteratorBase.h"
00022 
00023 namespace itk
00024 {
00025 template< class TTreeType >
00026 class PreOrderTreeIterator:public TreeIteratorBase< TTreeType >
00027 {
00028 public:
00029 
00031   typedef typename TTreeType::ValueType     ValueType;
00032   typedef TreeIteratorBase< TTreeType >     Superclass;
00033   typedef typename Superclass::TreeNodeType TreeNodeType;
00034   typedef typename Superclass::NodeType     NodeType;
00035 
00037   PreOrderTreeIterator(const TTreeType *tree, const TreeNodeType *start = NULL);
00038 
00040   NodeType GetType() const;
00041 
00043   TreeIteratorBase< TTreeType > * Clone();
00044 
00045 protected:
00047   const ValueType & Next();
00048 
00050   bool HasNext() const;
00051 
00052 private:
00053 
00055   const TreeNodeType * FindNextNode() const;
00056 };
00057 
00059 template< class TTreeType >
00060 PreOrderTreeIterator< TTreeType >::PreOrderTreeIterator(const TTreeType *tree, const TreeNodeType *start):
00061   TreeIteratorBase< TTreeType >(tree, start)
00062 {}
00063 
00065 template< class TTreeType >
00066 typename PreOrderTreeIterator< TTreeType >::NodeType
00067 PreOrderTreeIterator< TTreeType >::GetType() const
00068 {
00069   return TreeIteratorBase< TTreeType >::PREORDER;
00070 }
00071 
00073 template< class TTreeType >
00074 bool
00075 PreOrderTreeIterator< TTreeType >::HasNext() const
00076 {
00077   if ( const_cast< TreeNodeType * >( FindNextNode() ) != NULL )
00078     {
00079     return true;
00080     }
00081   return false;
00082 }
00084 
00086 template< class TTreeType >
00087 const typename PreOrderTreeIterator< TTreeType >::ValueType &
00088 PreOrderTreeIterator< TTreeType >::Next()
00089 {
00090   this->m_Position = const_cast< TreeNodeType * >( FindNextNode() );
00091   return this->m_Position->Get();
00092 }
00094 
00096 template< class TTreeType >
00097 const typename PreOrderTreeIterator< TTreeType >::TreeNodeType *
00098 PreOrderTreeIterator< TTreeType >::FindNextNode() const
00099 {
00100   if ( this->m_Position == NULL )
00101     {
00102     return NULL;
00103     }
00104   if ( this->m_Position->HasChildren() )
00105     {
00106     return dynamic_cast< const TreeNodeType * >( this->m_Position->GetChild(0) );
00107     }
00109 
00110   if ( !this->m_Position->HasParent() )
00111     {
00112     return NULL;
00113     }
00114 
00115   TreeNodeType *child = this->m_Position;
00116   TreeNodeType *parent = dynamic_cast< TreeNodeType * >( this->m_Position->GetParent() );
00117 
00118   // Are we a subtree? Then we are done.
00119   if ( parent && parent->ChildPosition(this->m_Root) >= 0 )
00120     {
00121     return NULL;
00122     }
00123 
00124   int childPosition = parent->ChildPosition(child);
00125   int lastChildPosition = parent->CountChildren() - 1;
00126 
00127   while ( childPosition < lastChildPosition )
00128     {
00129     TreeNodeType *help = dynamic_cast< TreeNodeType * >( parent->GetChild(childPosition + 1) );
00130 
00131     if ( help != NULL )
00132       {
00133       return help;
00134       }
00135     childPosition++;
00136     }
00137 
00138   while ( parent->HasParent() )
00139     {
00140     child = parent;
00141     parent = dynamic_cast< TreeNodeType * >( parent->GetParent() );
00142 
00143     // Subtree
00144     if ( parent->ChildPosition(this->m_Root) >= 0 )
00145       {
00146       return NULL;
00147       }
00148 
00149     childPosition = parent->ChildPosition(child);
00150     lastChildPosition = parent->CountChildren() - 1;
00151 
00152     while ( childPosition < lastChildPosition )
00153       {
00154       TreeNodeType *help = dynamic_cast< TreeNodeType * >( parent->GetChild(childPosition + 1) );
00155 
00156       if ( help != NULL )
00157         {
00158         return help;
00159         }
00160       }
00161     }
00162   return NULL;
00163 }
00164 
00166 template< class TTreeType >
00167 TreeIteratorBase< TTreeType > *PreOrderTreeIterator< TTreeType >::Clone()
00168 {
00169   PreOrderTreeIterator< TTreeType > *clone = new PreOrderTreeIterator< TTreeType >(this->m_Tree, this->m_Position);
00170   *clone = *this;
00171   return clone;
00172 }
00173 } // end namespace itk
00175 
00176 #endif
00177