Add to retry to read DUID.
[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;
178                         __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_