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