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