Merge "remove unnecessary implementations" into tizen_2.1
[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 (__pList->GetCount() != 0)
69                 {
70                         if (!__isPostEnd)
71                         {
72                                 __pEnum->MoveNext();
73                                 __currentObj = static_cast< T >(__pEnum->GetCurrent());
74                         }
75                         else
76                         {
77                                 __index = __pList->GetCount();
78                                 __pEnum->MovePrevious();
79                         }
80                 }
81                 else
82                 {
83                         // Control reaches here intentionally because begin() should be equal to end()
84                         __isPostEnd = true;
85                 }
86         }
87
88         /**
89          * This is copy constructor of %IteratorT class.
90          *
91          * @since               2.1
92          *
93          * @param[in]   rhs     A reference to the %IteratorT instance
94          */
95         IteratorT(const IteratorT< T >& rhs)
96                 : __pList(rhs.__pList)
97                 , __isPostEnd(rhs.__isPostEnd)
98                 , __index(rhs.__index)
99                 , __pEnum(__pList->GetBidirectionalEnumeratorN())
100                 , __currentObj(rhs.__currentObj)
101         {
102                 if (!__isPostEnd)
103                 {
104                         for (int i = 0; i <= __index; ++i)
105                         {
106                                 __pEnum->MoveNext();
107                         }
108                 }
109                 else
110                 {
111                         __pEnum->MovePrevious();
112                 }
113         }
114
115         /**
116          * This is assignment operator of %IteratorT class.
117          *
118          * @since               2.1
119          *
120          * @return              A reference to the %IteratorT instance
121          * @param[in]   rhs     A reference to the %IteratorT instance on the right-hand side of the operator
122          */
123         IteratorT< T >& operator=(const IteratorT< T >& rhs)
124         {
125                 IteratorT< T > tmp(rhs);
126                 tmp.swap(*this);
127                 return *this;
128         }
129
130         /**
131          * This is the indirection operator for %IteratorT class.
132          *
133          * @since       2.1
134          *
135          * @return              A T type reference
136          */
137         T& operator*(void) const
138         {
139                 AppAssertf(!__isPostEnd && __index >= 0, "It is out of range.");
140                 return const_cast< T& >(__currentObj);
141         }
142
143         /**
144          * This is the structure dereference operator for %IteratorT class.
145          *
146          * @since       2.1
147          *
148          * @return              A T type pointer equivalent to the pointer address
149          */
150         T* operator->(void) const
151         {
152                 return &(operator*());
153         }
154
155         /**
156          * Moves to the next element of the collection.
157          *
158          * @since               2.1
159          *
160          * @return              A reference to the %IteratorT type instance
161          * @exception   E_SUCCESS                       The method is successful.
162          * @exception   E_OUT_OF_RANGE          The iterator is outside the bounds of the list.
163          * @exception   E_INVALID_OPERATION     The current state of the instance prohibits the execution of the specified operation
164          *                                                                      the collection is modified after the enumerator is created.
165          * @remarks             The specific error code can be accessed using GetLastResult() method.
166          */
167         IteratorT< T >& operator++(void)
168         {
169                 const int PRE_BEGIN_IDX = -1;
170                 TryCatchResult(__index >= PRE_BEGIN_IDX, , E_OUT_OF_RANGE, "[%s] It is out of range.", GetErrorMessage(E_OUT_OF_RANGE));
171
172                 if (__index != PRE_BEGIN_IDX)
173                 {
174                         result r = __pEnum->MoveNext();
175                         TryCatchResult(r == E_SUCCESS, __isPostEnd = true; __currentObj = null, r, "[%s] It already reached the end.", GetErrorMessage(r));
176                 }
177
178                 __currentObj = static_cast< T >(__pEnum->GetCurrent());
179
180         CATCH:
181                 ++__index;
182                 return *this;
183         }
184
185         /**
186          * Moves to the next element of the collection and returns the previous state.
187          *
188          * @since       2.1
189          *
190          * @return              An IteratorT instance
191          * @exception   E_SUCCESS                       The method is successful.
192          * @exception   E_OUT_OF_RANGE          The iterator is outside the bounds of the list.
193          * @exception   E_INVALID_OPERATION     The current state of the instance prohibits the execution of the specified operation or
194          *                                                                      the collection is modified after the enumerator is created.
195          * @remarks             It takes O(n) time to get current Enumerate point to return. So use this operator as little as possible.
196          * @remarks             The specific error code can be accessed using GetLastResult() method.
197          */
198         IteratorT< T > operator++(int)
199         {
200                 IteratorT< T > tempIter = *this;
201                 operator++();
202                 return tempIter;
203         }
204
205         /**
206          * Moves to the previous element of the collection.
207          *
208          * @since               2.1
209          *
210          * @return              A reference to the %IteratorT type instance
211          * @exception   E_SUCCESS                       The method is successful.
212          * @exception   E_OUT_OF_RANGE          The iterator is outside the bounds of the list.
213          * @exception   E_INVALID_OPERATION     The current state of the instance prohibits the execution of the specified operation or
214          *                                                                      the collection is modified after the enumerator is created.
215          * @remarks             The specific error code can be accessed using GetLastResult() method.
216          */
217         IteratorT< T >& operator--(void)
218         {
219                 TryCatchResult(__index <= __pList->GetCount(), , E_OUT_OF_RANGE, "[%s] It is out of range.", GetErrorMessage(E_OUT_OF_RANGE));
220
221                 if (!__isPostEnd)
222                 {
223                         result r = __pEnum->MovePrevious();
224                         TryCatchResult(r == E_SUCCESS, __currentObj = null, r, "[%s] It already reached the front.", GetErrorMessage(r));
225                 }
226                 else
227                 {
228                         __isPostEnd = false;
229                 }
230
231                 __currentObj = static_cast< T >(__pEnum->GetCurrent());
232
233 CATCH:
234                 --__index;
235                 return *this;
236         }
237
238         /**
239          * Moves to the previous element of the collection and returns the previous state.
240          *
241          * @since               2.1
242          *
243          * @return              An IteratorT instance
244          * @exception   E_SUCCESS                       The method is successful.
245          * @exception   E_OUT_OF_RANGE          The iterator is outside the bounds of the list.
246          * @exception   E_INVALID_OPERATION     The current state of the instance prohibits the execution of the specified operation or
247          *                                                                      the collection is modified after the enumerator is created.
248          * @remarks             It takes O(n) time to get current Enumerate point to return. So use this operator as little as possible.
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 every 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          *      Exchanges values of the two %IteratorT instances
309          *
310          *      @since          2.1
311          *
312          *      @param[in]      rhs     A reference to the %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_