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