xref: /AOO41X/main/framework/inc/classes/checkediterator.hxx (revision f8e07b45f7e1fb69563504f404bb0b75210f0be6)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef __FRAMEWORK_CLASSES_CHECKEDITERATOR_HXX_
25 #define __FRAMEWORK_CLASSES_CHECKEDITERATOR_HXX_
26 
27 //_________________________________________________________________________________________________________________
28 //  my own includes
29 //_________________________________________________________________________________________________________________
30 
31 #include <macros/debug.hxx>
32 
33 //_________________________________________________________________________________________________________________
34 //  interface includes
35 //_________________________________________________________________________________________________________________
36 
37 //_________________________________________________________________________________________________________________
38 //  other includes
39 //_________________________________________________________________________________________________________________
40 #include <sal/types.h>
41 
42 #ifndef __SGI_STL_ITERATOR
43 #include <iterator>
44 #endif
45 
46 //_________________________________________________________________________________________________________________
47 //  namespace
48 //_________________________________________________________________________________________________________________
49 
50 namespace framework{
51 
52 //_________________________________________________________________________________________________________________
53 //  exported const
54 //_________________________________________________________________________________________________________________
55 
56 //_________________________________________________________________________________________________________________
57 //  exported definitions
58 //_________________________________________________________________________________________________________________
59 
60 /*-************************************************************************************************************//**
61     @short          implement a iterator which support 2 end states!
62     @descr          For our search methods we need a "walking" iterator object with special functionality!
63                     We must check for 3 different states of an iterator - normal position, exact end, after end.
64                     It's neccessary to detect if we have not found a entry and must return our default or
65                     default already returned and we must break loop!
66                     see using in class FilterCache too for further informations!
67 
68     @Attention      If your wish to debug this inline code ...
69                     under windows and msdev you can use "set ENVCFLAGS=/Ob0" to do that!
70 
71     @implements     -
72     @base           -
73 
74     @devstatus      ready to use
75     @threadsafe     no
76 *//*-*************************************************************************************************************/
77 
78 template< class TContainer >
79 class CheckedIterator
80 {
81     //-------------------------------------------------------------------------------------------------------------
82     //  public methods
83     //-------------------------------------------------------------------------------------------------------------
84 
85     public:
86 
87         //---------------------------------------------------------------------------------------------------------
88         // constructor / destructor
89         //---------------------------------------------------------------------------------------------------------
90 
91         /*-****************************************************************************************************//**
92             @short      standard constructor
93             @descr      Set default values on members.
94                         We set it internal to E_UNKNOWN to detect uninitialized instances of this class.
95                         If we found one - we know: "We must call initialize first!"
96 
97             @seealso    -
98 
99             @param      -
100             @return     -
101 
102             @onerror    -
103         *//*-*****************************************************************************************************/
104 
CheckedIterator()105         inline CheckedIterator()
106                 :   m_eEndState ( E_UNKNOWN )
107                 ,   m_pContainer( NULL      )
108         {
109         }
110 
111         //---------------------------------------------------------------------------------------------------------
112         // interface methods
113         //---------------------------------------------------------------------------------------------------------
114 
115         /*-****************************************************************************************************//**
116             @short      initialize instance with valid container
117             @descr      Set new container at an instance of this class. The other member will set automaticly!
118                         m_pPosition = first element in container
119                         m_eEndState = BEFOREEND
120 
121             @seealso    -
122 
123             @param      "rContainer", must be a valid reference to an existing container.
124             @return     -
125 
126             @onerror    An assertion is thrown.
127         *//*-*****************************************************************************************************/
128 
initialize(const TContainer & rContainer)129         inline void initialize( const TContainer& rContainer )
130         {
131             // Check incoming parameter. We don't accept all!
132             LOG_ASSERT2( &rContainer==NULL      , "CheckedIterator::initialize()", "Invalid parameter detected!"                        )
133             LOG_ASSERT2( m_eEndState!=E_UNKNOWN , "CheckedIterator::initialize()", "Instance already initialized! Don't do it again."   )
134 
135             if( m_eEndState == E_UNKNOWN )
136             {
137                 // Set new container and update other member.
138                 m_pContainer = &rContainer          ;
139                 m_eEndState  = E_BEFOREEND          ;
140                 m_pPosition  = m_pContainer->begin();
141             }
142         }
143 
144         /*-****************************************************************************************************//**
145             @short      set internal states to E_END
146             @descr      Sometimes we need a "walking" check-iterator which is initialized with the END-state!
147                         We need it to return one default value if no other ones exist ...
148 
149             @seealso    using in class FilterCache!
150 
151             @param      -
152             @return     -
153 
154             @onerror    -
155         *//*-*****************************************************************************************************/
156 
setEnd()157         inline void setEnd()
158         {
159             m_pContainer = NULL  ;
160             m_eEndState  = E_END ;
161         }
162 
163         /*-****************************************************************************************************//**
164             @short      set internal states to E_AFTEREND
165             @descr      Sometimes we need a "walking" check-iterator which is initialized with AFTEREND-state!
166                         We need it if we don't have a container but must prevent us against further searching!
167 
168             @seealso    using in class FilterCache!
169 
170             @param      -
171             @return     -
172 
173             @onerror    -
174         *//*-*****************************************************************************************************/
175 
setAfterEnd()176         inline void setAfterEnd()
177         {
178             m_pContainer = NULL       ;
179             m_eEndState  = E_AFTEREND ;
180         }
181 
182         /*-****************************************************************************************************//**
183             @short      reset this iterator
184             @descr      It must be called on an already initialized iterator.
185                         Means the member m_pContainer must be valid. Otherwhise the reaction
186                         isn't defined.
187 
188             @param      -
189             @return     -
190 
191             @onerror    -
192         *//*-*****************************************************************************************************/
193 
reset()194         inline void reset()
195         {
196             m_eEndState  = E_UNKNOWN;
197             m_pContainer = NULL;
198         }
199 
200         /*-****************************************************************************************************//**
201             @short      step to next element in container.
202             @descr      If end of container is reached we change our internal "m_eEndState".
203                         If end reached for first time; we set it to E_END;
204                         If you step to next element again; we set it to E_AFTEREND.
205                         So you have a chance to differ between "exact end" and "after end"!
206 
207             @seealso    method isEnd()
208             @seealso    method isAfterEnd()
209 
210             @param      -
211             @return     A reference to our changed object himself.
212 
213             @onerror    -
214         *//*-*****************************************************************************************************/
215 
operator ++()216         inline CheckedIterator& operator++()
217         {
218             // Warn programmer if he forget to initailize object!
219             LOG_ASSERT2( m_pContainer==NULL, "CheckedIterator::operator++()", "Object not initialized!" )
220             // Step to next element if any exist or set our end states.
221             switch( m_eEndState )
222             {
223                 case E_BEFOREEND:   {
224                                         ++m_pPosition;
225                                         // If iterator reaching end ... set right state!
226                                         if( m_pPosition == m_pContainer->end() )
227                                         {
228                                             m_eEndState = E_END;
229                                         }
230                                     }
231                                     break;
232                 case E_END      :   {
233                                         // Set state only ... iterator already points to end of container!
234                                         m_eEndState = E_AFTEREND;
235                                     }
236                                     break;
237             }
238             return *this;
239         }
240 
241         /*-****************************************************************************************************//**
242             @short      return true if internal iterator was not initialized before
243             @descr      These will be true, if use start a new search by using these iterator mechanism!
244 
245             @seealso    class FilterCache
246 
247             @param      -
248             @return     True if internalk state E_UNKNOWN - false otherwise.
249 
250             @onerror    -
251         *//*-*****************************************************************************************************/
252 
isUninitialized()253         inline sal_Bool isUninitialized()
254         {
255             return( m_eEndState == E_UNKNOWN );
256         }
257 
258         /*-****************************************************************************************************//**
259             @short      return true if internal iterator reached end of container
260             @descr      These will be true if you step to the end of internal container.
261 
262             @seealso    method isAfterEnd()
263 
264             @param      -
265             @return     True if end reached; false otherwise.
266 
267             @onerror    -
268         *//*-*****************************************************************************************************/
269 
isEnd()270         inline sal_Bool isEnd()
271         {
272             // Is true if one end state is set!
273             return  (
274                         ( m_eEndState == E_END      )   ||
275                         ( m_eEndState == E_AFTEREND )
276                     );
277         }
278 
279         /*-****************************************************************************************************//**
280             @short      return true if you call operator++ again and end already reached
281             @descr      These indicate, that end already reached but you call operator++ again and again!
282 
283             @seealso    method isEnd()
284 
285             @param      -
286             @return     True if end multiple reached; false otherwise.
287 
288             @onerror    -
289         *//*-*****************************************************************************************************/
290 
isAfterEnd()291         inline sal_Bool isAfterEnd()
292         {
293             // Is true only, if special end state is set!
294             return( m_eEndState == E_AFTEREND );
295         }
296 
297         /*-****************************************************************************************************//**
298             @short      support readonly access to container entry
299             @descr      Use it to get the value of current container item.
300 
301             @seealso    -
302 
303             @param      -
304             @return     A reference to value of container entry.
305 
306             @onerror    -
307         *//*-*****************************************************************************************************/
308 
getEntry()309         inline typename TContainer::const_iterator getEntry()
310         {
311             // Warn programmer if he forget to initialize these object ...
312             LOG_ASSERT2( m_pContainer==NULL, "CheckedIterator::getEntry()", "Object not initialized!" )
313             // or try to read a non existing element!
314             LOG_ASSERT2( m_eEndState!=E_BEFOREEND, "CheckedIterator::getEntry()", "Wrong using of class detected!" )
315 
316             return m_pPosition;
317         }
318 
319     //-------------------------------------------------------------------------------------------------------------
320     //  private member
321     //-------------------------------------------------------------------------------------------------------------
322 
323     private:
324 
325         // These enum defines our four states for an iterator position in curent container.
326         enum EEndState
327         {
328             E_UNKNOWN   ,
329             E_BEFOREEND ,
330             E_END       ,
331             E_AFTEREND
332         };
333 
334         const TContainer*           m_pContainer    ;   // pointer to current container
335         EEndState                   m_eEndState     ;   // "position state" of iterator!
336         typename TContainer::const_iterator  m_pPosition     ;   // point to actual element in container
337 };
338 
339 }       //  namespace framework
340 
341 #endif  //  #ifndef __FRAMEWORK_CLASSES_CHECKEDITERATOR_HXX_
342