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