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 itkRootTreeIterator_h
19 #define itkRootTreeIterator_h
20 
21 #include "itkTreeIteratorBase.h"
22 
23 namespace itk
24 {
25 template< typename TTreeType >
26 class RootTreeIterator:public TreeIteratorBase< TTreeType >
27 {
28 public:
29 
30   /** Typedefs */
31   using Superclass = TreeIteratorBase< TTreeType >;
32   using TreeType = TTreeType;
33   using ValueType = typename TTreeType::ValueType;
34   using TreeNodeType = typename Superclass::TreeNodeType;
35   using NodeType = typename Superclass::NodeType;
36 
37   /** Constructor */
38   RootTreeIterator(TreeType *tree, const TreeNodeType *start = nullptr);
39 
40   /** Return the type of the iterator */
41   NodeType GetType() const override;
42 
43   /** Clone function */
44   TreeIteratorBase< TTreeType > * Clone() override;
45 
46 protected:
47 
48   /** Return the next node */
49   const ValueType & Next() override;
50 
51   /** Return true if the next node exists */
52   bool HasNext() const override;
53 
54 private:
55 
56   /** Find the next node */
57   const TreeNodeType * FindNextNode() const;
58 };
59 
60 /** Constructor */
61 template< typename TTreeType >
RootTreeIterator(TTreeType * tree,const TreeNodeType * start)62 RootTreeIterator< TTreeType >::RootTreeIterator(TTreeType *tree, const TreeNodeType *start):
63   TreeIteratorBase< TTreeType >(tree, start)
64 {
65   if ( start )
66     {
67     this->m_Begin = const_cast< TreeNode< ValueType > * >( start );
68     }
69   this->m_Root = tree->GetRoot();
70   this->m_Position = this->m_Begin;
71 }
72 
73 /** Return the type of the iterator */
74 template< typename TTreeType >
75 typename RootTreeIterator< TTreeType >::NodeType
GetType()76 RootTreeIterator< TTreeType >::GetType() const
77 {
78   return TreeIteratorBase< TTreeType >::ROOT;
79 }
80 
81 /** Return true if the next node exists */
82 template< typename TTreeType >
83 bool
HasNext()84 RootTreeIterator< TTreeType >::HasNext() const
85 {
86   if ( const_cast< TreeNodeType * >( FindNextNode() ) != nullptr )
87     {
88     return true;
89     }
90   return false;
91 }
92 
93 /** Go to the next node */
94 template< typename TTreeType >
95 const typename RootTreeIterator< TTreeType >::ValueType &
Next()96 RootTreeIterator< TTreeType >::Next()
97 {
98   this->m_Position = const_cast< TreeNodeType * >( FindNextNode() );
99   return this->m_Position->Get();
100 }
101 
102 /** Find the next node */
103 template< typename TTreeType >
104 const typename RootTreeIterator< TTreeType >::TreeNodeType *
FindNextNode()105 RootTreeIterator< TTreeType >::FindNextNode() const
106 {
107   if ( this->m_Position == nullptr )
108     {
109     return nullptr;
110     }
111   if ( this->m_Position == this->m_Root )
112     {
113     return nullptr;
114     }
115   return this->m_Position->GetParent();
116 }
117 
118 /** Clone function */
119 template< typename TTreeType >
Clone()120 TreeIteratorBase< TTreeType > *RootTreeIterator< TTreeType >::Clone()
121 {
122   auto * clone = new RootTreeIterator< TTreeType >(const_cast< TTreeType * >( this->m_Tree ),
123                                                                            this->m_Position);
124   *clone = *this;
125   return clone;
126 }
127 } // end namespace itk
128 
129 #endif
130