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