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