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