Merge "Update code of system and text for reporting Klocwork." into devel_3.0_main
[platform/framework/native/appfw.git] / inc / FBaseColPairIteratorT.h
1 //
2 // Copyright (c) 2013 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 /**
18  * @file                FBaseColPairIteratorT.h
19  * @brief               This is the header file for the %PairIteratorT class.
20  *
21  * This header file contains the declarations of the %PairIteratorT class.
22  */
23
24 #ifndef _FBASE_COL_PAIR_ITERATOR_T_H_
25 #define _FBASE_COL_PAIR_ITERATOR_T_H_
26
27 #include <algorithm>    // std::swap (Before C++11)
28 #include <iterator>
29 #include <utility>
30 #include <unique_ptr.h>
31 #include <FBaseLog.h>
32 #include <FBaseColIMap.h>
33 #include <FBaseColIMultiMap.h>
34 #include <FBaseColIMapEnumerator.h>
35
36 namespace Tizen { namespace Base { namespace Collection
37 {
38 /**
39  * @class       PairIteratorT
40  * @brief       This class provides an iterator that is used to convert %IMap or %IMultiMap to STL containers. @n
41  *                      %StlConverter provides static methods to get this iterator from %IMap or %IMultiMap.
42  *
43  * @since       2.1
44  *
45  * @remarks     The %PairIteratorT class satisfies requirements of C++ standard library ForwardIterator which is not mutable.
46  *                      It does not satisfy the requirements of an OutputIterator which can be dereferenced as an lvalue.
47  *
48  * The %PairIteratorT class provides an iterator that is used to convert IMap or IMultiMap to STL containers.
49  * StlConverter provides static methods to get this iterator from IMap or IMultiMap.
50  */
51
52 template< typename K, typename V >
53 class PairIteratorT
54         : public std::iterator< std::forward_iterator_tag, std::pair< K, V > >
55 {
56 public:
57         typedef std::forward_iterator_tag iterator_category;
58         typedef typename std::iterator_traits< PairIteratorT< K, V > >::value_type value_type;
59         typedef typename std::iterator_traits< PairIteratorT< K, V > >::difference_type difference_type;
60         typedef typename std::iterator_traits< PairIteratorT< K, V > >::pointer pointer;
61         typedef typename std::iterator_traits< PairIteratorT< K, V > >::reference reference;
62
63         /**
64          * This is the default constructor for this class.
65          *
66          * @since               3.0
67          */
68         PairIteratorT(void)
69                 : __pMap(null)
70                 , __pMultiMap(null)
71                 , __isPostEnd(false)
72                 , __index(0)
73                 , __pEnum(null)
74                 , __currentObj(null)
75         {
76         }
77
78         /**
79          * Initializes this instance of %PairIteratorT class.
80          *
81          * @since               2.1
82          *
83          * @param[in]   map                     A reference to the IMap instance to convert
84          * @param[in]   isPostEnd       A boolean value to check the end
85          */
86         explicit PairIteratorT(const IMap& map, bool isPostEnd = false)
87                 : __pMap(&map)
88                 , __pMultiMap(null)
89                 , __isPostEnd(isPostEnd)
90                 , __index(0)
91                 , __pEnum(__pMap->GetMapEnumeratorN())
92                 , __currentObj()
93         {
94                 if (__pMap->GetCount() != 0)
95                 {
96                         if (!__isPostEnd)
97                         {
98                                 __pEnum->MoveNext();
99                                 __currentObj.first = static_cast< K >(__pEnum->GetKey());
100                                 __currentObj.second = static_cast< V >(__pEnum->GetValue());
101                         }
102                         else
103                         {
104                                 __index = __pMap->GetCount();
105                         }
106                 }
107                 else
108                 {
109                         // Control reaches here intentionally because begin() should be equal to end()
110                         __isPostEnd = true;
111                 }
112         }
113
114         /**
115          * Initializes this instance of %PairIteratorT class.
116          *
117          * @since               2.1
118          *
119          * @param[in]   multiMap        A reference to the IMultiMap instance to convert
120          * @param[in]   isPostEnd       A boolean value to check the end
121          */
122         PairIteratorT(const IMultiMap& multiMap, bool isPostEnd = false)
123                 : __pMap(null)
124                 , __pMultiMap(&multiMap)
125                 , __isPostEnd(isPostEnd)
126                 , __index(0)
127                 , __pEnum(__pMultiMap->GetMapEnumeratorN())
128                 , __currentObj()
129         {
130                 if (__pMultiMap->GetCount() != 0)
131                 {
132                         if (!__isPostEnd)
133                         {
134                                 __pEnum->MoveNext();
135                                 __currentObj.first = static_cast< K >(__pEnum->GetKey());
136                                 __currentObj.second = static_cast< V >(__pEnum->GetValue());
137                         }
138                         else
139                         {
140                                 __index = __pMultiMap->GetCount();
141                         }
142                 }
143                 else
144                 {
145                         // Control reaches here intentionally because begin() should be equal to end()
146                         __isPostEnd = true;
147                 }
148         }
149
150         /**
151          * This is the copy constructor of the %PairIteratorT class.
152          *
153          * @since               2.1
154          *
155          * @param[in]   rhs                                     A reference to the %PairIteratorT instance
156          * @exception   E_SUCCESS                       The method is successful.
157          * @exception   E_INVALID_ARG           Both @c __pMap and @c __pMultiMap are @c null.
158          * @exception   E_INVALID_OPERATION     The current state of the instance prohibits the execution of the specified operation, or
159          *                                                                      the collection is modified after the enumerator is created.
160          * @remarks             The specific error code can be accessed using GetLastResult() method.
161          */
162         PairIteratorT(const PairIteratorT< K, V >& rhs)
163                 : __pMap(rhs.__pMap)
164                 , __pMultiMap(rhs.__pMultiMap)
165                 , __isPostEnd(rhs.__isPostEnd)
166                 , __index(rhs.__index)
167                 , __currentObj(rhs.__currentObj)
168         {
169                 TryReturnVoidResult(__pMap != null || __pMultiMap != null, E_INVALID_ARG, "[%s] __pMap or __pMultiMap should not be null.", GetErrorMessage(E_INVALID_ARG));
170
171                 if (__pMap != null)
172                 {
173                         __pEnum.reset(__pMap->GetMapEnumeratorN());
174                 }
175                 else if (__pMultiMap != null)
176                 {
177                         __pEnum.reset(__pMultiMap->GetMapEnumeratorN());
178                 }
179
180                 if (!__isPostEnd)
181                 {
182                         for (int i = 0; i <= __index; ++i)
183                         {
184                                 __pEnum->MoveNext();
185                         }
186                 }
187         }
188
189         /**
190          * This is assignment operator of the %PairIteratorT class.
191          *
192          * @since               2.1
193          *
194          * @return              A reference to the %PairIteratorT instance
195          * @param[in]   rhs                                     A reference to the %PairIteratorT instance on the right-hand side of the operator
196          * @exception   E_SUCCESS                       The method is successful.
197          * @exception   E_INVALID_ARG           Both @c __pMap and @c __pMultiMap are @c null.
198          * @exception   E_INVALID_OPERATION     The current state of the instance prohibits the execution of the specified operation, or
199          *                                                                      the collection is modified after the enumerator is created.
200          * @remarks             The specific error code can be accessed using GetLastResult() method.
201          */
202         PairIteratorT< K, V >& operator =(const PairIteratorT< K, V >& rhs)
203         {
204                 PairIteratorT< K, V > tmp(rhs);
205                 tmp.swap(*this);
206                 return *this;
207         }
208
209         /**
210          * This is the indirection operator for the %PairIteratorT class.
211          *
212          * @since               2.1
213          *
214          * @return              A std::pair type reference with K and V type
215          */
216         reference operator *(void) const
217         {
218                 AppAssertf(!__isPostEnd, "It is out of range.");
219                 return const_cast< std::pair< K, V >& >(__currentObj);
220         }
221
222         /**
223          * This is the structure dereference operator for the %PairIteratorT class.
224          *
225          * @since               2.1
226          *
227          * @return              A std::pair type pointer equivalent to the pointer address
228          */
229         pointer operator ->(void) const
230         {
231                 return &(operator *());
232         }
233
234         /**
235          * Moves to the next element of the collection.
236          *
237          * @since               2.1
238          *
239          * @return              A reference to the %PairIteratorT instance
240          * @exception   E_SUCCESS                       The method is successful.
241          * @exception   E_OUT_OF_RANGE          The enumerator has passed the end of the collection.
242          * @exception   E_INVALID_OPERATION     The current state of the instance prohibits the execution of the specified operation, or
243          *                                                                      the collection is modified after the enumerator is created.
244          * @remarks             The specific error code can be accessed using GetLastResult() method.
245          */
246         PairIteratorT< K, V >& operator ++(void)
247         {
248                 TryReturnResult(!__isPostEnd, *this, E_OUT_OF_RANGE, "[%s] It already reached the end.", GetErrorMessage(E_OUT_OF_RANGE));
249
250                 result r = __pEnum->MoveNext();
251                 TryCatchResult(r == E_SUCCESS, __isPostEnd = true;
252                         __currentObj.first = null;
253                         __currentObj.second = null,
254                         r, "[%s] It already reached the end.", GetErrorMessage(r));
255
256                 __currentObj.first = static_cast< K >(__pEnum->GetKey());
257                 __currentObj.second = static_cast< V >(__pEnum->GetValue());
258
259 CATCH:
260                 ++__index;
261                 return *this;
262         }
263
264         /**
265          * Moves to the next element of the collection and returns the previous state.
266          *
267          * @since       2.1
268          *
269          * @return              A %PairIteratorT instance
270          * @exception   E_SUCCESS                       The method is successful.
271          * @exception   E_OUT_OF_RANGE          The enumerator has passed the end of the collection.
272          * @exception   E_INVALID_OPERATION     The current state of the instance prohibits the execution of the specified operation, or
273          *                                                                      the collection is modified after the enumerator is created.
274          * @remarks             The specific error code can be accessed using GetLastResult() method.
275          */
276         PairIteratorT< K, V > operator ++(int)
277         {
278                 PairIteratorT< K, V > tempIter = *this;
279                 operator ++();
280                 return tempIter;
281         }
282
283         /**
284          *      Checks the two %PairIteratorT instances for equality.
285          *
286          *      @since          2.1
287          *
288          *      @return         @c true if every member of the specified %PairIteratorT instance equals the calling instance's members, @n
289          *                              else @c false
290          *      @param[in]      rhs     A reference to the %PairIteratorT instance on the right-hand side of the operator
291          */
292         bool operator ==(const PairIteratorT< K, V >& rhs) const
293         {
294                 if (__pMap != rhs.__pMap)
295                 {
296                         return false;
297                 }
298
299                 if (__pMultiMap != rhs.__pMultiMap)
300                 {
301                         return false;
302                 }
303
304                 if (__index != rhs.__index)
305                 {
306                         return false;
307                 }
308
309                 if (__isPostEnd != rhs.__isPostEnd)
310                 {
311                         return false;
312                 }
313                 else if (__isPostEnd && rhs.__isPostEnd)
314                 {
315                         // In this case, __currentObj state is invalid
316                         return true;
317                 }
318
319                 // If both this->__isPostEnd and rhs.__isPostEnd are false, then reach here. This means both iterators are in the middle of the list.
320                 return __currentObj == rhs.__currentObj;
321         }
322
323         /**
324          *      Checks the two %PairIteratorT instances for inequality.
325          *
326          *      @since          2.1
327          *
328          *      @return         @c true if any member of the specified %PairIteratorT instance is not equal to the calling instance's members, @n
329          *                              else @c false
330          *      @param[in]      rhs     A reference to the %PairIteratorT instance on the right-hand side of the operator
331          */
332         bool operator !=(const PairIteratorT< K, V >& rhs) const
333         {
334                 return !operator ==(rhs);
335         }
336
337         /**
338          *      Swaps values of the two %PairIteratorT instances.
339          *
340          *      @since          2.1
341          *
342          *      @param[in]      rhs     A reference to the %PairIteratorT instance to swap
343          */
344         void swap(PairIteratorT< K, V >& rhs)
345         {
346                 std::swap(__pMap, rhs.__pMap);
347                 std::swap(__pMultiMap, rhs.__pMultiMap);
348                 std::swap(__isPostEnd, rhs.__isPostEnd);
349                 std::swap(__index, rhs.__index);
350                 std::swap(__pEnum, rhs.__pEnum);
351                 std::swap(__currentObj, rhs.__currentObj);
352         }
353
354 private:
355         const IMap* __pMap;
356         const IMultiMap* __pMultiMap;
357         bool __isPostEnd;
358         difference_type __index;
359         std::unique_ptr< IMapEnumerator > __pEnum;
360         value_type __currentObj;
361 };  // PairIteratorT
362
363 }}} // Tizen::Base::Collection
364
365 #endif //_FBASE_COL_PAIR_ITERATOR_T_H_