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