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