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