Flush app registry before releasing file lock
[platform/framework/native/appfw.git] / inc / FBaseColLinkedListT.h
1 //
2 // Copyright (c) 2012 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                FBaseColLinkedListT.h
19  * @brief               This is the header file for the %LinkedListT class.
20  *
21  * This header file contains the declarations of the %LinkedListT class.
22  */
23 #ifndef _FCOL_LINKED_LIST_T_H_
24 #define _FCOL_LINKED_LIST_T_H_
25
26 #include <FBaseResult.h>
27 #include <FBaseColIComparerT.h>
28 #include <FBaseColIListT.h>
29
30 namespace Tizen { namespace Base { namespace Collection
31 {
32
33 template< class Type > class __LinkedListEnumeratorT;
34 template< class Type > class __LinkedListNodeT;
35
36 /**
37  * @class LinkedListT
38  * @brief This class represents a template-based collection of objects that can be individually accessed by an index.
39  *
40  * @since 2.0
41  *
42  * The %LinkedListT class represents a template-based collection of objects that can be individually accessed by an index.
43  *
44  * For more information on the class features, see <a href="../org.tizen.native.appprogramming/html/guide/base/arraylist_linkedlist.htm">ArrayList and LinkedList</a>.
45  *
46  * The following example demonstrates how to use the %LinkedListT class.
47  *
48  * @code
49  *
50  *      #include <FBase.h>
51  *
52  *      using namespace Tizen::Base;
53  *      using namespace Tizen::Base::Collection;
54  *
55  *      void
56  *      MyClass::LinkedListTSample(void)
57  *      {
58  *              LinkedListT< int > list;
59  *
60  *              int int1 = 1;
61  *              int int2 = 2;
62  *              int int3 = 3;
63  *              int int4 = 4;
64  *
65  *              list.Add(int1);         // 1
66  *              list.Add(int2);         // 1,2
67  *              list.Add(int3);         // 1,2,3
68  *
69  *              int temp;
70  *              for (int i = 0; i < list.GetCount(); i++)
71  *              {
72  *                      list.GetAt(i, temp);
73  *              }
74  *
75  *              list.InsertAt(int4, 1); // 1,4,2,3
76  *
77  *              ComparerT< int >* pIntComparer = new ComparerT<int>();
78  *              list.Sort(*pIntComparer);       // 1,2,3,4
79  *
80  *              delete pIntComparer;
81  *
82  *              list.Remove(int3);      // 1,2,4
83  *              list.RemoveAt(0);       // 2,4
84  *
85  *              // Uses an enumerator to access elements in the list
86  *              IEnumeratorT< int >* pEnum = list.GetEnumeratorN();;
87  *              while (pEnum->MoveNext() == E_SUCCESS)
88  *              {
89  *                      pEnum->GetCurrent(temp);
90  *              }
91  *
92  *              delete pEnum;
93  *      }
94  * @endcode
95  */
96 template< class Type >
97 class LinkedListT
98         : public IListT< Type >
99         , public Object
100 {
101 public:
102         /**
103          * This is the default constructor for this class.
104          *
105          * @since 2.0
106          */
107         LinkedListT(void)
108                 : __pListHead(null)
109                 , __pListTail(null)
110                 , __count(0)
111                 , __modCount(0)
112         {
113         }
114
115         /**
116          * This destructor overrides Tizen::Base::Object::~Object().
117          *
118          * @since 2.0
119          */
120         virtual ~LinkedListT(void)
121         {
122                 __modCount++;
123
124                 RemoveAll();
125         }
126
127         /**
128          * Adds the specified object to the end of this list.
129          *
130          * @since 2.0
131          *
132          * @return              An error code
133          * @param[in]   obj                             The object to add
134          * @exception   E_SUCCESS               The method is successful.
135          * @exception   E_OUT_OF_MEMORY The memory is insufficient.
136          * @see Remove()
137          */
138         virtual result Add(const Type& obj)
139         {
140                 result r = E_SUCCESS;
141
142                 if (null == __pListHead)
143                 {
144                         r = InsertFirst(obj);
145                 }
146                 else
147                 {
148                         r = InsertLast(obj);
149                 }
150                 if (r != E_SUCCESS)
151                 {
152                         AppLogException("[%s] Propagating.", GetErrorMessage(r));
153                 }
154
155                 return r;
156         }
157
158         /**
159          * Adds the elements of the specified collection to the end of this list.
160          *
161          * @since 2.0
162          *
163          * @return              An error code
164          * @param[in]   collection                      The collection to add
165          * @exception   E_SUCCESS                       The method is successful.
166          * @exception   E_INVALID_OPERATION     Either of the following conditions has occurred:
167          *                                                                      - The current state of the instance prohibits the execution of the specified operation.
168          *                                                                      - The specified @c collection is modified during the operation of this method.
169          * @see                 RemoveItems()
170          */
171         virtual result AddItems(const ICollectionT< Type >& collection)
172         {
173                 result r = InsertItemsFrom(collection, __count);
174                 if (r != E_SUCCESS)
175                 {
176                         AppLogException("[%s] Propagating.", GetErrorMessage(r));
177                 }
178
179                 return r;
180         }
181
182         /**
183          * Gets the enumerator of this list.
184          *
185          * @since 2.0
186          *
187          * @return              The enumerator (an instance of the IEnumeratorT derived class) of this list, @n
188          *                              else @c null if an exception occurs
189          * @exception   E_SUCCESS               The method is successful.
190          * @exception   E_OUT_OF_MEMORY The memory is insufficient.
191          * @remarks             The specific error code can be accessed using the GetLastResult() method.
192          */
193         virtual IEnumeratorT< Type >* GetEnumeratorN(void) const
194         {
195                 ClearLastResult();
196
197                 result r = E_SUCCESS;
198
199                 __LinkedListEnumeratorT< Type >* pEnum = new __LinkedListEnumeratorT< Type >(*this, __modCount);
200                 TryCatch(pEnum != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
201
202                 return pEnum;
203
204 CATCH:
205                 SetLastResult(r);
206                 return null;
207         }
208
209         /**
210          * Gets the bidirectional enumerator (an instance of the IBidirectionalEnumeratorT derived class) of this list.
211          *
212          * @since 2.0
213          *
214          * @return                      An instance of the IBidirectionalEnumeratorT derived class, @n
215          *                                      else @c null if an exception occurs
216          * @exception           E_SUCCESS                       The method is successful.
217          * @exception           E_OUT_OF_MEMORY         The memory is insufficient.
218          * @remarks
219          *                                      - Use this method to obtain a bidirectional enumerator (an instance of the IBidirectionalEnumeratorT derived class)
220          *                                      to iterate over a collection (an instance of the IListT derived class).
221          *                                      - The specific error code can be accessed using the GetLastResult() method.
222          */
223         virtual IBidirectionalEnumeratorT< Type >* GetBidirectionalEnumeratorN(void) const
224         {
225                 ClearLastResult();
226
227                 result r = E_SUCCESS;
228
229                 __LinkedListEnumeratorT< Type >* pEnum = new __LinkedListEnumeratorT< Type >(*this, __modCount);
230                 TryCatch(pEnum != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
231
232                 return pEnum;
233
234 CATCH:
235                 SetLastResult(r);
236                 return null;
237         }
238
239         /**
240          * Gets the object at the specified index of this list.
241          *
242          * @since 2.0
243          *
244          * @return              An error code
245          * @param[in]   index                                   The index of the object to read
246          * @param[out]  obj                                             The object to get from this list
247          * @exception   E_SUCCESS                               The method is successful.
248          * @exception   E_OUT_OF_RANGE                  Either of the following conditions has occurred:
249          *                                                                              - The specified @c index is outside the bounds of the data structure.
250          *                                                                              - The specified @c index is either greater than or equal to the number of elements.
251          *                                                                              - The specified @c index is less than @c 0.
252          * @see                 SetAt()
253          */
254         virtual result GetAt(int index, Type& obj) const
255         {
256                 TryReturn(index >= 0 && index < __count, E_OUT_OF_RANGE,
257                         "[%s] The index(%d) MUST be greater than or equal to 0, and less than the number of elements(%d).",
258                         GetErrorMessage(E_OUT_OF_RANGE), index, __count);
259
260                 __LinkedListNodeT< Type >* pNode = GetNode(index);
261                 if (pNode != null)
262                 {
263                         obj = pNode->pObj;
264                 }
265                 return E_SUCCESS;
266         }
267
268         /**
269          * Gets the object at the specified index of this list.
270          *
271          * @since 2.0
272          *
273          * @return              An error code
274          * @param[in]   index                                   The index of the object to read
275          * @param[out]  obj                                             The object to get from this list
276          * @exception   E_SUCCESS                               The method is successful.
277          * @exception   E_OUT_OF_RANGE                  Either of the following conditions has occurred:
278          *                                                                          - The specified @c index is outside the bounds of the data structure.
279          *                                                                              - The specified @c index is either greater than or equal to the number of elements.
280          *                                                                              - The specified @c index is less than @c 0.
281          * @see                 SetAt()
282          */
283         virtual result GetAt(int index, Type& obj)
284         {
285                 TryReturn(index >= 0 && index < __count, E_OUT_OF_RANGE,
286                         "[%s] The index(%d) MUST be greater than or equal to 0, and less than the number of elements(%d).",
287                         GetErrorMessage(E_OUT_OF_RANGE), index, __count);
288
289                 __LinkedListNodeT< Type >* pNode = GetNode(index);
290                 if (pNode != null)
291                 {
292                         obj = pNode->pObj;
293                 }
294                 return E_SUCCESS;
295         }
296
297         /**
298          * Gets an IListT-derived instance with the specified range from the calling list object.
299          *
300          * @since 2.0
301          *
302          * @return              A pointer to the IListT derived instance, @n
303          *                              else @c null if an exception occurs
304          * @param[in]   startIndex                              The starting index of the range
305          * @param[in]   count                                   The number of elements to read
306          * @exception   E_SUCCESS                               The method is successful.
307          * @exception   E_OUT_OF_RANGE                  Either of the following conditions has occurred:
308          *                                                                              - The specified @c index is outside the bounds of the data structure.
309          *                                                                              - The specified @c startIndex is either greater than or equal to the number of elements.
310      *                                                                          - The specified @c startIndex is less than @c 0. @n
311          *                                                                              - The specified @c count is greater than the number of elements starting from @c startIndex.
312      *                                                                          - The specified @c count is less than @c 0.
313          *
314          * @remarks             The specific error code can be accessed using the GetLastResult() method.
315          */
316         virtual IListT< Type >* GetItemsN(int startIndex, int count) const
317         {
318                 ClearLastResult();
319
320                 result r = E_SUCCESS;
321                 LinkedListT< Type >* pList = null;
322                 __LinkedListNodeT< Type >* pNode = null;
323                 __LinkedListNodeT< Type >* pPrevNode = null;
324
325                 TryCatch(startIndex >= 0 && count >= 0, r = E_OUT_OF_RANGE,
326                         "[%s] Both of the startIndex(%d) and count(%d) MUST be greater than or equal to 0.",
327                         GetErrorMessage(E_OUT_OF_RANGE), startIndex, count);
328                 TryCatch(startIndex < __count, r = E_OUT_OF_RANGE,
329                         "[%s] The startIndex(%d) MUST be less than the number of elements(%d).", GetErrorMessage(E_OUT_OF_RANGE), startIndex, __count);
330                 TryCatch(count <= __count && (startIndex + count <= __count), r = E_OUT_OF_RANGE,
331                         "[%s] The startIndex(%d) + count(%d) MUST be less than or equal to the number of elements(%d).",
332                         GetErrorMessage(E_OUT_OF_RANGE), startIndex, count, __count);
333
334                 pList = new LinkedListT< Type >();
335
336                 pNode = GetNode(startIndex);
337                 if ((pList != null) && (pNode != null))
338                 {
339                         r = pList->InsertFirst(pNode->pObj);
340                         TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
341
342                         pNode = pNode->pNext;
343                         pPrevNode = pList->__pListTail;
344
345                         for (int i = 0; i < (count - 1); i++)
346                         {
347                                 if (pNode != null)
348                                 {
349                                         pPrevNode = pList->InsertNext(pPrevNode, pNode->pObj);
350                                         TryCatch(pPrevNode != null, r = GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
351                                         pNode = pNode->pNext;
352                                 }
353                         }
354                 }
355
356                 return pList;
357
358 CATCH:
359                 SetLastResult(r);
360                 delete pList;
361
362                 return null;
363         }
364
365         /**
366          * Searches for an object in this list. @n
367          * Gets the index of the object if found.
368          *
369          * @since 2.0
370          *
371          * @return              An error code
372          * @param[in]   obj                                     The object to locate
373          * @param[out]  index                           The index of the object
374          * @exception   E_SUCCESS                       The method is successful.
375          * @exception   E_OBJ_NOT_FOUND         The specified @c obj has not been found.
376          */
377         virtual result IndexOf(const Type& obj, int& index) const
378         {
379                 result r = E_SUCCESS;
380                 if (__count == 0)
381                 {
382                         r = E_OBJ_NOT_FOUND;
383                 }
384                 else
385                 {
386                         r = IndexOf(obj, 0, __count, index);
387                 }
388
389                 return r;
390         }
391
392         /**
393          * Searches for an object starting from the specified index. @n
394          * Gets the index of the object if found.
395          *
396          * @since 2.0
397          *
398          * @return              An error code
399          * @param[in]   obj                             The object to locate
400          * @param[in]   startIndex                              The starting index for the search @n
401          *                                                                              It must be less than the number of elements.
402          * @param[out]  index                                   The index of the object
403          * @exception   E_SUCCESS                               The method is successful.
404          * @exception   E_OUT_OF_RANGE                  Either of the following conditions has occurred:
405          *                                                                              - The specified @c index is outside the bounds of the data structure.
406          *                                                                              - The specified @c startIndex is either greater than or equal to the number of elements in the list.
407          *                                                                              - The specified @c startIndex is less than @c 0.
408          * @exception   E_OBJ_NOT_FOUND                 The specified @c obj has not been found.
409          * @see                 LastIndexOf()
410          */
411         virtual result IndexOf(const Type& obj, int startIndex, int& index) const
412         {
413                 TryReturn((startIndex >= 0 && startIndex < __count), E_OUT_OF_RANGE,
414                         "[%s] The startIndex(%d) MUST be greater than or equal to 0, and less than the number of elements(%d).",
415                         GetErrorMessage(E_OUT_OF_RANGE), startIndex, __count);
416
417                 return IndexOf(obj, startIndex, (__count - startIndex), index);
418         }
419
420         /**
421          * Searches for an object within the specified range. @n
422          * Gets the index of the object if found.
423          *
424          * @since 2.0
425          *
426          * @return              An error code
427          * @param[in]   obj                             The object to locate
428          * @param[in]   startIndex                              The starting index of the range
429          * @param[in]   count                                   The number of elements to read
430          * @param[out]  index                                   The index of the object
431          * @exception   E_SUCCESS                               The method is successful.
432          * @exception   E_OUT_OF_RANGE                  Either of the following conditions has occurred:
433          *                                                                              - The specified @c index is outside the bounds of the data structure.
434          *                                                                              - The specified @c startIndex is either greater than or equal to the number of elements in the list.
435          *                                                                              - The specified @c startIndex is less than @c 0.
436          *                                                                              - The specified @c count is greater than the number of elements starting from @c startIndex.
437          *                                                                              - The specified @c count is less than @c 0.
438          * @exception   E_OBJ_NOT_FOUND                 The specified @c obj has not been found.
439          * @see                 LastIndexOf()
440          */
441         virtual result IndexOf(const Type& obj, int startIndex, int count, int& index) const
442         {
443                 TryReturn(startIndex >= 0 && count >= 0, E_OUT_OF_RANGE,
444                         "[%s] Both of the startIndex(%d) and count(%d) MUST be greater than or equal to 0.",
445                         GetErrorMessage(E_OUT_OF_RANGE), startIndex, count);
446                 TryReturn(startIndex < __count, E_OUT_OF_RANGE,
447                         "[%s] The startIndex(%d) MUST be less than the number of elements(%d).", GetErrorMessage(E_OUT_OF_RANGE), startIndex, __count);
448                 TryReturn(count <= __count && (startIndex + count <= __count), E_OUT_OF_RANGE,
449                         "[%s] The startIndex(%d) + count(%d) MUST be less than or equal to the number of elements(%d).",
450                         GetErrorMessage(E_OUT_OF_RANGE), startIndex, count, __count);
451
452                 result r = E_OBJ_NOT_FOUND;
453                 __LinkedListNodeT< Type >* pNode = GetNode(startIndex);
454                 for (int i = 0; i < count; i++)
455                 {
456                         if (pNode != null)
457                         {
458                                 if (obj == pNode->pObj)
459                                 {
460                                         index = (startIndex + i);
461                                         r = E_SUCCESS;
462                                         break;
463                                 }
464                                 pNode = pNode->pNext;
465                         }
466                 }
467
468                 return r;
469         }
470
471         /**
472          * Inserts the object at the specified location.
473          *
474          * @since 2.0
475          *
476          * @return              An error code
477          * @param[in]   obj                                             The object to insert
478          * @param[in]   index                                   The index at which the object is inserted
479          * @exception   E_SUCCESS                               The method is successful.
480          * @exception   E_OUT_OF_RANGE                  Either of the following conditions has occurred:
481          *                                                                              - The specified @c index is outside the bounds of the data structure.
482          *                                                                              - The specified @c index is greater than the number of elements.
483          *                                                                              - The specified @c index is less than @c 0.
484          * @remarks             If the @c index is equal to the number of elements then the new elements
485          *                              is added at the end of this list.
486          * @see                 Add()
487          * @see                 RemoveAt()
488          */
489         virtual result InsertAt(const Type& obj, int index)
490         {
491                 TryReturn(index >= 0 && index <= __count, E_OUT_OF_RANGE,
492                         "[%s] The index(%d) MUST be greater than or equal to 0, and less than or equal to the number of elements(%d).",
493                         GetErrorMessage(E_OUT_OF_RANGE), index, __count);
494
495                 result r = E_SUCCESS;
496
497                 __LinkedListNodeT< Type >* pPrevNode = null;
498                 if (index == 0)
499                 {
500                         r = InsertFirst(obj);
501                 }
502                 else if (index == __count)
503                 {
504                         r = InsertLast(obj);
505                 }
506                 else
507                 {
508                         pPrevNode = GetNode(index - 1);
509                         if (pPrevNode != null)
510                         {
511                                 InsertNext(pPrevNode, obj);
512                         }
513                         r = GetLastResult();
514                 }
515                 if (r != E_SUCCESS)
516                 {
517                         AppLogException("[%s] Propagating.", GetErrorMessage(r));
518                 }
519
520                 return r;
521         }
522
523
524         /**
525          * Inserts the elements of the collection at the specified location.
526          *
527          * @since 2.0
528          *
529          * @return              An error code
530          * @param[in]   collection                              The collection to insert
531          * @param[in]   startIndex                              The starting index at which the collection is inserted
532          * @exception   E_SUCCESS                               The method is successful.
533          * @exception   E_OUT_OF_RANGE                  Either of the following conditions has occurred:
534          *                                                                              - The specified @c index is outside the bounds of the data structure.
535          *                                                                              - The specified @c startIndex is greater than the number of elements.
536      *                                                                          - The specified @c startIndex is less than @c 0.
537          * @exception   E_INVALID_OPERATION             Either of the following conditions has occurred:
538          *                                                                              - The current state of the instance prohibits the execution of the specified operation.
539          *                                                                              - The specified @c collection is modified during the operation of this method.
540          * @remarks             If the @c startIndex is equal to the number of elements then the new elements
541          *                              are added at the end of this list.
542          * @see                 RemoveItems()
543          * @see                 AddItems()
544          */
545         virtual result InsertItemsFrom(const ICollectionT< Type >& collection, int startIndex)
546         {
547                 TryReturn(startIndex >= 0 && startIndex <= __count, E_OUT_OF_RANGE,
548                         "[%s] The startIndex(%d) MUST be greater than or equal to 0, and less than or equal to the number of elements(%d).",
549                         GetErrorMessage(E_OUT_OF_RANGE), startIndex, __count);
550
551                 result r = E_SUCCESS;
552
553                 IEnumeratorT< Type >* pEnum = null;
554                 int count = collection.GetCount();
555                 if (count > 0)
556                 {
557                         __LinkedListNodeT< Type >* pPrevNode = null;
558                         ;
559                         if (startIndex == __count)
560                         {
561                                 pPrevNode = __pListTail;
562                         }
563                         else if (startIndex > 0)
564                         {
565                                 pPrevNode = GetNode(startIndex - 1);
566                         }
567
568                         ICollectionT< Type >* pCol = const_cast< ICollectionT< Type >* >(&collection);
569                         pEnum = pCol->GetEnumeratorN();
570                         TryCatch(pEnum != null, r = GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
571
572                         while (true)
573                         {
574                                 Type obj;
575                                 r = pEnum->MoveNext();
576
577                                 if (E_OUT_OF_RANGE == r)
578                                 {
579                                         r = E_SUCCESS;
580                                         break;
581                                 }
582                                 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
583
584                                 r = pEnum->GetCurrent(obj);
585                                 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
586
587                                 if (null == pPrevNode)
588                                 {
589                                         r = InsertFirst(obj);
590                                         TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
591                                         pPrevNode = __pListHead;
592                                 }
593                                 else
594                                 {
595                                         pPrevNode = InsertNext(pPrevNode, obj);
596                                         TryCatch(pPrevNode != null, r = GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
597                                 }
598                         }
599                 }
600
601                 if (null != pEnum)
602                 {
603                         delete pEnum;
604                 }
605
606                 return r;
607
608 CATCH:
609                 if (null != pEnum)
610                 {
611                         delete pEnum;
612                 }
613                 return r;
614         }
615
616         /**
617          * Searches for the last occurrence of an object in this list. @n
618          * Gets the index of the object if found.
619          *
620          * @since 2.0
621          *
622          * @return              An error code
623          * @param[in]   obj                     The object to locate
624          * @param[out]  index                           The index of the last occurrence of the specified object
625          * @exception   E_SUCCESS                       The method is successful.
626          * @exception   E_OBJ_NOT_FOUND         The specified @c obj has not been found.
627          * @see                 IndexOf()
628          */
629         virtual result LastIndexOf(const Type& obj, int& index) const
630         {
631                 result r = E_OBJ_NOT_FOUND;
632                 __LinkedListNodeT< Type >* pNode = __pListTail;
633                 for (int i = (__count - 1); i >= 0; i--)
634                 {
635                         if (obj == pNode->pObj)
636                         {
637                                 index = i;
638                                 r = E_SUCCESS;
639                                 break;
640                         }
641                         pNode = pNode->pPrev;
642                 }
643
644                 return r;
645         }
646
647         /**
648          * Removes the first occurrence of the specified object from the list.
649          *
650          * @since 2.0
651          *
652          * @return              An error code
653          * @param[in]   obj                             The object to remove
654          * @exception   E_SUCCESS               The method is successful.
655          * @exception   E_OBJ_NOT_FOUND The specified @c obj has not been found.
656          * @see                 Add()
657          * @see                 RemoveAt()
658          * @see                 RemoveAll()
659          */
660         virtual result Remove(const Type& obj)
661         {
662                 result r = E_OBJ_NOT_FOUND;
663                 __LinkedListNodeT< Type >* pNode = __pListHead;
664                 while (null != pNode)
665                 {
666                         if (pNode->pObj == obj)
667                         {
668                                 RemoveNode(pNode);
669                                 r = E_SUCCESS;
670                                 break;
671                         }
672                         pNode = pNode->pNext;
673                 }
674
675                 return r;
676         }
677
678         /**
679          * Removes all the elements from the specified collection.
680          *
681          * @since 2.0
682          *
683          * @return              An error code
684          * @param[in]   collection                      The collection to remove from this list
685          * @exception   E_SUCCESS                       The method is successful.
686          * @exception   E_INVALID_OPERATION     Either of the following conditions has occurred:
687          *                                                                      - The current state of the instance prohibits the execution of the specified operation.
688          *                                                                      - The specified @c collection is modified during the operation of this method.
689          * @see                 Remove()
690          * @see                 RemoveAt()
691          */
692         virtual result RemoveItems(const ICollectionT< Type >& collection)
693         {
694                 result r = E_SUCCESS;
695
696                 ICollectionT< Type >* pCol = const_cast< ICollectionT< Type >* >(&collection);
697                 IEnumeratorT< Type >* pEnum = pCol->GetEnumeratorN();
698                 TryCatch(pEnum != null, r = GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
699
700                 while (true)
701                 {
702                         Type temp;
703                         r = pEnum->MoveNext();
704
705                         if (E_OUT_OF_RANGE == r)
706                         {
707                                 r = E_SUCCESS;
708                                 break;
709                         }
710                         TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
711
712                         r = pEnum->GetCurrent(temp);
713                         TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
714
715                         r = Remove(temp);
716                         TryLog(r == E_SUCCESS, "[%s] Remove() failed.", GetErrorMessage(r));
717                 }
718
719                 if (null != pEnum)
720                 {
721                         delete pEnum;
722                 }
723                 return r;
724
725 CATCH:
726                 if (null != pEnum)
727                 {
728                         delete pEnum;
729                 }
730                 return r;
731         }
732
733         /**
734          * Removes the object at the specified location.
735          *
736          * @since 2.0
737          *
738          * @return              An error code
739          * @param[in]   index                                   The index at which the object is removed
740          * @exception   E_SUCCESS                               The method is successful.
741          * @exception   E_OUT_OF_RANGE                  Either of the following conditions has occurred:
742          *                                                                              - The specified @c index is outside the bounds of the data structure.
743          *                                                                              - The specified @c index is greater than the number of elements.
744          *                                                                              - The specified @c index is less than @c 0.
745          * @see                 InsertAt()
746          */
747         virtual result RemoveAt(int index)
748         {
749                 TryReturn(index < __count && index >= 0, E_OUT_OF_RANGE,
750                         "[%s] The index(%d) MUST be greater than or equal to 0, and less than the number of elements(%d).",
751                         GetErrorMessage(E_OUT_OF_RANGE), index, __count);
752
753                 RemoveNode(GetNode(index));
754                 return E_SUCCESS;
755         }
756
757         /**
758          * Removes all the elements within the specified range.
759          *
760          * @since 2.0
761          *
762          * @return              An error code
763          * @param[in]   startIndex                              The starting index of the range
764          * @param[in]   count                                   The number of elements to read
765          * @exception   E_SUCCESS                               The method is successful.
766          * @exception   E_OUT_OF_RANGE                  Either of the following conditions has occurred:
767          *                                                                              - The specified @c index is outside the bounds of the data structure.
768          *                                                                              - The specified @c startIndex is either greater than or equal to the number of elements.
769          *                                                                              - The specified @c startIndex is less than @c 0.
770          *                                                                              - The specified @c count is greater than the number of elements starting from @c startIndex.
771          *                                                                              - The specified @c count is less than @c 0.
772          * @see                 AddItems()
773          * @see                 InsertItemsFrom()
774          */
775         virtual result RemoveItems(int startIndex, int count)
776         {
777                 TryReturn(startIndex >= 0 && count >= 0, E_OUT_OF_RANGE,
778                         "[%s] Both of the startIndex(%d) and count(%d) MUST be greater than or equal to 0.",
779                         GetErrorMessage(E_OUT_OF_RANGE), startIndex, count);
780                 TryReturn(startIndex < __count, E_OUT_OF_RANGE,
781                         "[%s] The startIndex(%d) MUST be less than the number of elements(%d).", GetErrorMessage(E_OUT_OF_RANGE), startIndex, __count);
782                 TryReturn(count <= __count && (startIndex + count <= __count), E_OUT_OF_RANGE,
783                         "[%s] The startIndex(%d) + count(%d) MUST be less than or equal to the number of elements(%d).",
784                         GetErrorMessage(E_OUT_OF_RANGE), startIndex, count, __count);
785
786                 if (count > 0)
787                 {
788                         __LinkedListNodeT< Type >* pNode = GetNode(startIndex);
789                         for (int i = 0; i < count; i++)
790                         {
791                                 if (pNode != null)
792                                 {
793                                         __LinkedListNodeT< Type >* pNextNode = pNode->pNext;
794                                         RemoveNode(pNode);
795                                         pNode = pNextNode;
796                                 }
797                         }
798                 }
799                 return E_SUCCESS;
800         }
801
802         /**
803          * Removes all the elements from this list.
804          *
805          * @since 2.0
806          */
807         virtual void RemoveAll(void)
808         {
809                 if (__count > 0)
810                 {
811                         __modCount++;
812                         __LinkedListNodeT< Type >* pNode = __pListHead;
813                         __LinkedListNodeT< Type >* pTemp;
814                         while (null != pNode)
815                         {
816                                 pTemp = pNode->pNext;
817                                 delete pNode;
818                                 pNode = pTemp;
819                                 __count--;
820                         }
821                         __pListHead = null;
822                         __pListTail = null;
823                 }
824         }
825
826         /**
827          * Sets the object at the specified index with the specified object.
828          *
829          * @since 2.0
830          *
831          * @return              An error code
832          * @param[in]   obj                                             The object to set
833          * @param[in]   index                                   The index at which the object is set
834          * @exception   E_SUCCESS                               The method is successful.
835          * @exception   E_OUT_OF_RANGE                  Either of the following conditions has occurred:
836          *                                                                              - The specified @c index is outside the bounds of the data structure.
837          *                                                                              - The specified @c index is either greater than or equal to the number of elements.
838          *                                                                              - The specified @c index is less than @c 0.
839          * @see                 GetAt()
840          */
841         virtual result SetAt(const Type& obj, int index)
842         {
843                 TryReturn(index >= 0 && index < __count, E_OUT_OF_RANGE,
844                         "[%s] The index(%d) MUST be greater than or equal to 0, less than the number of elements(%d).",
845                         GetErrorMessage(E_OUT_OF_RANGE), index, __count);
846
847                 __modCount++;
848                 __LinkedListNodeT< Type >* pNode = GetNode(index);
849                 if (pNode != null)
850                 {
851                         pNode->pObj = obj;
852                 }
853
854                 return E_SUCCESS;
855         }
856
857         /**
858          * Sorts the elements of this list using the comparer provided.
859          *
860          * @since 2.0
861          *
862          * @return              An error code
863          * @param[in]   comparer                The IComparerT implementation to use when comparing the elements
864          * @exception   E_SUCCESS               The method is successful.
865          * @exception   E_INVALID_ARG   Either of the following conditions has occurred:
866          *                                                              - The specified input parameter is invalid.
867          *                                                              - The specified @c comparer is invalid.
868          */
869         virtual result Sort(const IComparerT< Type >& comparer)
870         {
871                 if (0 == __count)
872                 {
873                         return E_SUCCESS;
874                 }
875
876                 result r = QuickSort(0, (__count - 1), comparer);
877                 if (r != E_SUCCESS)
878                 {
879                         AppLogException("[%s] Propagating.", GetErrorMessage(r));
880                 }
881
882                 return r;
883         }
884
885         /**
886          * Gets the number of objects currently stored in this list.
887          *
888          * @since 2.0
889          *
890          * @return              The number of objects currently stored in this list
891          */
892         virtual int GetCount(void) const
893         {
894                 return __count;
895         }
896
897         /**
898          * Checks whether the list contains the specified object.
899          *
900          * @since 2.0
901          *
902          * @return              @c true if the list contains the specified object, @n
903          *                              else @c false
904          * @param[in]   obj     The object to locate
905          * @see                 ContainsAll()
906          */
907         virtual bool Contains(const Type& obj) const
908         {
909                 if (__count == 0)
910                 {
911                         return false;
912                 }
913
914                 __LinkedListNodeT< Type >* pNode = GetNode(0);
915                 for (int i = 0; i < __count; i++)
916                 {
917                         if (pNode != null)
918                         {
919                                 if (obj == pNode->pObj)
920                                 {
921                                         return true;
922                                 }
923                                 pNode = pNode->pNext;
924                         }
925                 }
926
927                 return false;
928         }
929
930         /**
931          * Checks whether the list contains all the elements of the specified collection.
932          *
933          * @since 2.0
934          *
935          * @return              An error code
936          * @param[in]   collection                      The collection to check for containment in this list
937          * @param[out]  out                             Set to @c true if this list contains all of the elements in the specified collection, @n
938          *                                                                      else @c false
939          * @exception   E_SUCCESS                       The method is successful.
940          * @exception   E_INVALID_OPERATION     Either of the following conditions has occurred:
941          *                                                                      - The current state of the instance prohibits the execution of the specified operation.
942          *                                                                      - The specified @c collection is modified during the operation of this method.
943          * @remarks             If the given @c collection is empty, then @c out is set to @c true.
944          * @see                 Contains()
945          */
946         virtual result ContainsAll(const ICollectionT< Type >& collection, bool& out) const
947         {
948                 result r = E_SUCCESS;
949                 out = false;
950
951                 if (collection.GetCount() == 0)
952                 {
953                         out = true;
954                         return E_SUCCESS;
955                 }
956
957                 ICollectionT< Type >* pCol = const_cast< ICollectionT< Type >* >(&collection);
958                 IEnumeratorT< Type >* pEnum = pCol->GetEnumeratorN();
959                 TryCatch(pEnum != null, r = GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
960
961                 while (true)
962                 {
963                         Type temp;
964
965                         r = pEnum->MoveNext();
966
967                         if (E_OUT_OF_RANGE == r)
968                         {
969                                 r = E_SUCCESS;
970                                 out = true;
971                                 break;
972                         }
973                         TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
974
975                         r = pEnum->GetCurrent(temp);
976                         TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
977
978                         if (false == Contains(temp))
979                         {
980                                 out = false;
981                                 break;
982                         }
983                 }
984
985                 if (null != pEnum)
986                 {
987                         delete pEnum;
988                 }
989                 return r;
990
991 CATCH:
992                 if (null != pEnum)
993                 {
994                         delete pEnum;
995                 }
996                 return r;
997         }
998
999         /**
1000          * Compares the given object with the calling LinkedList object.
1001          *
1002          * @since 2.0
1003          *
1004          * @return              @c true if the specified instance equals the current instance, @n
1005          *                              else @c false
1006          * @param[in]   obj The object to compare with the calling object
1007          * @remarks     This method returns @c true only if the specified object is also an instance of the LinkedList class,
1008          *                      both lists have the same size, and all the corresponding pairs of elements in the two lists are equal. @n
1009          *                      In other words, the two lists are equal if they contain the same elements in the same order.
1010          */
1011         virtual bool Equals(const Object& obj) const
1012         {
1013                 bool out = true;
1014
1015                 const LinkedListT< Type >* other = dynamic_cast< const LinkedListT< Type >* >(&obj);
1016                 if (null == other)
1017                 {
1018                         out = false;
1019                 }
1020                 else if (other == this)
1021                 {
1022                         out = true;
1023                 }
1024                 else if (__count != other->__count)
1025                 {
1026                         out = false;
1027                 }
1028                 else
1029                 {
1030                         __LinkedListNodeT< Type >* pNode = __pListHead;
1031                         __LinkedListNodeT< Type >* pOtherNode = other->__pListHead;
1032                         for (int i = 0; i < __count; i++)
1033                         {
1034                                 if (!(pNode->pObj == pOtherNode->pObj))
1035                                 {
1036                                         out = false;
1037                                         break;
1038                                 }
1039                                 pNode = pNode->pNext;
1040                                 pOtherNode = pOtherNode->pNext;
1041                         }
1042                 }
1043
1044                 return out;
1045         }
1046
1047         /**
1048          * Gets the hash value of the current instance.
1049          *
1050          * @since 2.0
1051          *
1052          * @return      The hash value of the current instance
1053          * @remarks     The two Tizen::Base::Object::Equals() instances must return the same hash value. @n
1054          *                      For better performance, the used hash function must generate a random distribution for all the inputs.
1055          */
1056         virtual int GetHashCode(void) const
1057         {
1058                 int hash = 0;
1059                 if (__count > 0)
1060                 {
1061                         __LinkedListNodeT< Type >* pNode = __pListHead;
1062                         while (pNode != null)
1063                         {
1064                                 hash += reinterpret_cast< int >(pNode);
1065                                 pNode = pNode->pNext;
1066                         }
1067                 }
1068
1069                 return hash;
1070         }
1071
1072 private:
1073         /**
1074          * The implementation of this copy constructor is intentionally blank and declared as private to prohibit copying of objects.
1075          *
1076          * @param[in]   list The %LinkedListT object to initialize the new object
1077          */
1078         LinkedListT(const LinkedListT< Type >& list);
1079
1080         /**
1081          * The implementation of this copy assignment operator is intentionally blank and declared as private to prohibit copying of objects.
1082          *
1083          * @param[in]   list An instance of %LinkedListT
1084          */
1085         LinkedListT< Type >& operator =(const LinkedListT< Type >& list);
1086
1087         /**
1088          * Gets the node at the specified index.
1089          *
1090          * @return              A node at the specified index
1091          * @param[in]   index The index of the node to read
1092          */
1093         __LinkedListNodeT< Type >* GetNode(int index) const
1094         {
1095                 if (index >= __count)
1096                 {
1097                         return null;
1098                 }
1099
1100                 __LinkedListNodeT< Type >* pNode = __pListHead;
1101                 for (int i = 0; i < index; i++)
1102                 {
1103                         pNode = pNode->pNext;
1104                 }
1105
1106                 return pNode;
1107         }
1108
1109         /**
1110          * Inserts an object to the beginning of the %LinkedList.
1111          *
1112          * @return              An error code
1113          * @param[in]   obj                     The object to insert
1114          * @exception   E_OUT_OF_MEMORY The memory is insufficient.
1115          * @exception   E_SUCCESS               The method is successful.
1116          */
1117         result InsertFirst(const Type& obj)
1118         {
1119                 result r = E_SUCCESS;
1120                 __LinkedListNodeT< Type >* pNode = new __LinkedListNodeT< Type >(obj);
1121                 TryCatch(pNode != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
1122
1123                 __modCount++;
1124                 __count++;
1125                 if (null == __pListHead)
1126                 {
1127                         __pListHead = pNode;
1128                         __pListTail = pNode;
1129                 }
1130                 else
1131                 {
1132                         pNode->pNext = __pListHead;
1133                         __pListHead->pPrev = pNode;
1134                         __pListHead = pNode;
1135                 }
1136
1137                 return r;
1138
1139 CATCH:
1140                 return r;
1141         }
1142
1143         /**
1144          * Inserts an object to the end of the LinkedList.
1145          *
1146          * @return              An error code
1147          * @param[in]   obj                     The object to insert
1148          * @exception   E_OUT_OF_MEMORY The memory is insufficient.
1149          * @exception   E_SUCCESS               The method is successful.
1150          */
1151         result InsertLast(const Type& obj)
1152         {
1153                 __LinkedListNodeT< Type >* pNode = InsertNext(__pListTail, obj);
1154                 if (pNode == null)
1155                 {
1156                         AppLogException("[%s] Propagating.", GetErrorMessage(GetLastResult()));
1157                 }
1158
1159                 return GetLastResult();
1160         }
1161
1162         /**
1163          * Inserts an object after the specified node.
1164          *
1165          * @return              An error code
1166          * @param[in]   obj             The object to insert
1167          * @param[in]   pPrevNode       The node after which the object must be inserted
1168          * @exception   E_OUT_OF_MEMORY The memory is insufficient.
1169          * @exception   E_SUCCESS               The method is successful.
1170          * @remarks             The specific error code can be accessed using the GetLastResult() method.
1171          */
1172         __LinkedListNodeT< Type >* InsertNext(__LinkedListNodeT< Type >* pPrevNode, const Type& obj)
1173         {
1174                 ClearLastResult();
1175                 result r = E_SUCCESS;
1176                 __LinkedListNodeT< Type >* pNode = new __LinkedListNodeT< Type >(obj);
1177                 TryCatch(pNode != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
1178
1179                 __modCount++;
1180                 __count++;
1181                 if (null == __pListHead)
1182                 {
1183                         __pListHead = pNode;
1184                         __pListTail = pNode;
1185                 }
1186                 else if (pPrevNode == __pListTail)
1187                 {
1188                         pNode->pPrev = __pListTail;
1189                         __pListTail->pNext = pNode;
1190                         __pListTail = pNode;
1191                 }
1192                 else
1193                 {
1194                         TryCatch(pPrevNode != null, r = E_INVALID_ARG, "[%s] The pPrevNode is null.", GetErrorMessage(E_INVALID_ARG));
1195                         pNode->pPrev = pPrevNode;
1196                         pNode->pNext = pPrevNode->pNext;
1197                         pPrevNode->pNext->pPrev = pNode;
1198                         pPrevNode->pNext = pNode;
1199                 }
1200
1201                 return pNode;
1202
1203 CATCH:
1204                 SetLastResult(r);
1205                 if (pNode != null)
1206                 {
1207                         delete pNode;
1208                         pNode = null;
1209                 }
1210
1211                 return pNode;
1212         }
1213
1214         /**
1215          * Removes the specified node.
1216          *
1217          * @param[in]   pNode The pointer of the node to remove
1218          */
1219         void RemoveNode(__LinkedListNodeT< Type >* pNode)
1220         {
1221                 AppAssertf((null != pNode), "pNode is null.\n");
1222                 AppAssertf((__count > 0), "__count is zero.\n");
1223
1224                 __modCount++;
1225                 __count--;
1226                 if (__count == 0)
1227                 {
1228                         __pListHead = null;
1229                         __pListTail = null;
1230                 }
1231                 else if (pNode == __pListHead)
1232                 {
1233                         __pListHead = pNode->pNext;
1234                         __pListHead->pPrev = null;
1235                 }
1236                 else if (pNode == __pListTail)
1237                 {
1238                         __pListTail = pNode->pPrev;
1239                         __pListTail->pNext = null;
1240                 }
1241                 else
1242                 {
1243                         pNode->pNext->pPrev = pNode->pPrev;
1244                         pNode->pPrev->pNext = pNode->pNext;
1245                 }
1246                 delete pNode;
1247         }
1248
1249         /**
1250          * Sorts the specified sub-list within the calling instance.
1251          *
1252          * @param[in]   startIndex      The starting index of the sub-list to sort
1253          * @param[in]   endIndex        The ending index of the sub-list to sort
1254          * @param[in]   pComparer       The comparer function to sort the list
1255          * @exception   E_SUCCESS               The method is successful.
1256          * @exception   E_INVALID_ARG   A specified input parameter is invalid, or @n
1257          *                                                              the comparer has failed to compare the elements.
1258          */
1259         result QuickSort(int startIndex, int endIndex, const IComparerT< Type >& comparer)
1260         {
1261                 result r = E_SUCCESS;
1262
1263                 if (startIndex < endIndex)
1264                 {
1265                         int middleIndex;
1266                         int i = startIndex - 1;
1267                         int j = endIndex + 1;
1268                         Type startObj = Type();
1269                         __LinkedListNodeT< Type >* pNodeI = null;
1270                         __LinkedListNodeT< Type >* pNodeJ = null;
1271                         __LinkedListNodeT< Type >* pNode = GetNode(startIndex);
1272
1273                         if (pNode != null)
1274                         {
1275                                 startObj = pNode->pObj;
1276                         }
1277
1278                         while (true)
1279                         {
1280                                 int compareResult = 1;
1281                                 while ((compareResult > 0) && (j > static_cast< int >(startIndex)))
1282                                 {
1283                                         j--;
1284                                         pNodeJ = (null == pNodeJ) ? GetNode(j) : pNodeJ->pPrev;
1285                                         if (pNodeJ != null)
1286                                         {
1287                                                 r = comparer.Compare(pNodeJ->pObj, startObj, compareResult);
1288                                                 TryReturn(r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1289                                         }
1290                                 }
1291
1292                                 compareResult = -1;
1293                                 while ((compareResult < 0) && (i < static_cast< int >(endIndex)))
1294                                 {
1295                                         i++;
1296                                         pNodeI = (null == pNodeI) ? GetNode(i) : pNodeI->pNext;
1297                                         if (pNodeI != null)
1298                                         {
1299                                                 r = comparer.Compare(pNodeI->pObj, startObj, compareResult);
1300                                                 TryReturn(r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1301                                         }
1302                                 }
1303
1304                                 if (i < j)
1305                                 {
1306                                         if ((pNodeJ != null) && (pNodeI != null))
1307                                         {
1308                                                 Type temp = pNodeJ->pObj;
1309                                                 pNodeJ->pObj = pNodeI->pObj;
1310                                                 pNodeI->pObj = temp;
1311                                         }
1312                                 }
1313                                 else
1314                                 {
1315                                         middleIndex = j;
1316                                         break;
1317                                 }
1318                         }
1319
1320                         r = QuickSort(startIndex, middleIndex, comparer);
1321                         TryReturn(r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1322
1323                         r = QuickSort(middleIndex + 1, endIndex, comparer);
1324                         TryReturn(r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1325                 }
1326
1327                 return r;
1328         }
1329
1330         __LinkedListNodeT< Type >* __pListHead;
1331         __LinkedListNodeT< Type >* __pListTail;
1332         int __count;
1333         int __modCount;
1334         friend class __LinkedListEnumeratorT< Type >;
1335
1336 }; // LinkedListT
1337
1338 //
1339 // @class       __LinkedListNodeT
1340 // @brief       This is a node for LinkedListT.
1341 // @since 2.0
1342 //
1343 template< class Type >
1344 class __LinkedListNodeT
1345         : public Object
1346 {
1347 public:
1348         /**
1349          * This is the constructor for this class.
1350          *
1351          * @since 2.0
1352          *
1353          * @param[in]   obj     The object to include in this node
1354          */
1355         __LinkedListNodeT(const Type& obj)
1356                 : pPrev(null)
1357                 , pNext(null)
1358                 , pObj(obj)
1359         {
1360         }
1361
1362         /**
1363          * Internal variable.
1364          *
1365          * @since 2.0
1366          */
1367         __LinkedListNodeT< Type >* pPrev;
1368
1369         /**
1370          * Internal variable.
1371          *
1372          * @since 2.0
1373          */
1374         __LinkedListNodeT< Type >* pNext;
1375
1376         /**
1377          * Internal variable.
1378          *
1379          * @since 2.0
1380          */
1381         Type pObj;
1382
1383 }; // __LinkedListNodeT
1384
1385 //
1386 // @class       __LinkedListEnumeratorT
1387 // @brief       This class is an implementation of IEnumeratorT for %LinkedListT.
1388 // @since 2.0
1389 //
1390 template< class Type >
1391 class __LinkedListEnumeratorT
1392         : public IBidirectionalEnumeratorT< Type >
1393         , public Object
1394 {
1395 public:
1396         /**
1397          * This is the constructor for this class.
1398          *
1399          * @since 2.0
1400          *
1401          * @param[in]   list            The list to enumerate
1402          * @param[in]   modCount        The modification count to detect the change in the list
1403          */
1404         __LinkedListEnumeratorT(const LinkedListT< Type >& list, int modCount)
1405                 : __list(list)
1406                 , __pNode(null)
1407                 , __modCount(modCount)
1408         {
1409
1410         }
1411
1412         /**
1413          * This is the destructor for this class.
1414          *
1415          * @since 2.0
1416          */
1417         virtual ~__LinkedListEnumeratorT(void)
1418         {
1419
1420         }
1421
1422         /**
1423          * Gets the current object in the list.
1424          *
1425          * @since 2.0
1426          *
1427          * @return              An error code
1428          * @param[out]  obj                               The current object
1429          * @exception   E_INVALID_OPERATION       Either of the following conditions has occurred:
1430          *                                                                      - The current state of the instance prohibits the execution of the specified operation.
1431          *                                                                      - This enumerator is currently positioned before the first element or
1432          *                                                                      past the last element.
1433          *                                                                      - The list is modified after this enumerator is created.
1434          * @exception   E_SUCCESS                         The method is successful.
1435          */
1436         result GetCurrent(Type& obj) const
1437         {
1438                 TryReturn(__modCount == __list.__modCount, E_INVALID_OPERATION,
1439                         "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1440                 TryReturn(__pNode != null, E_INVALID_OPERATION,
1441                         "[%s] Current position is before the first element or past the last element.", GetErrorMessage(E_INVALID_OPERATION));
1442
1443                 obj = __pNode->pObj;
1444                 return E_SUCCESS;
1445         }
1446
1447
1448         /**
1449          * Moves this enumerator to the next element of the list. @n
1450          * When this enumerator is first created or after a call to Reset(),
1451          * the first call to MoveNext() positions this enumerator to the first element in the list.
1452          *
1453          * @since 2.0
1454          *
1455          * @return              An error code
1456          * @exception   E_SUCCESS                       The method is successful.
1457          * @exception   E_INVALID_OPERATION     Either of the following conditions has occurred:
1458          *                                                                      - The current state of the instance prohibits the execution of the specified operation.
1459          *                                                                      - The list is modified after this enumerator is created.
1460          * @exception   E_OUT_OF_RANGE          The enumerator has passed the end of the list.
1461          * @see                 Reset()
1462          */
1463         result MoveNext(void)
1464         {
1465                 TryReturn(__modCount == __list.__modCount, E_INVALID_OPERATION,
1466                         "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1467
1468                 if (null == __pNode)
1469                 {
1470                         __pNode = __list.__pListHead;
1471                         if (null == __pNode)
1472                         {
1473                                 return E_OUT_OF_RANGE;
1474                         }
1475                 }
1476                 else
1477                 {
1478                         if (null != __pNode->pNext)
1479                         {
1480                                 __pNode = __pNode->pNext;
1481                         }
1482                         else
1483                         {
1484                                 return E_OUT_OF_RANGE;
1485                         }
1486                 }
1487
1488                 return E_SUCCESS;
1489         }
1490
1491         /**
1492          * Positions this enumerator before the first element in the list.
1493          *
1494          * @since 2.0
1495          *
1496          * @return              An error code
1497          * @exception   E_SUCCESS                       The method is successful.
1498          * @exception   E_INVALID_OPERATION     Either of the following conditions has occurred:
1499          *                                                                      - The current state of the instance prohibits the execution of the specified operation.
1500          *                                                                      - The list is modified after this enumerator is created.
1501          */
1502         result Reset(void)
1503         {
1504                 TryReturn(__modCount == __list.__modCount, E_INVALID_OPERATION,
1505                         "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1506
1507                 __pNode = null;
1508                 return E_SUCCESS;
1509         }
1510
1511         result MovePrevious(void)
1512         {
1513                 TryReturn(__modCount == __list.__modCount, E_INVALID_OPERATION,
1514                         "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1515
1516                 if (__pNode == null)
1517                 {
1518                         __pNode = __list.__pListTail;
1519                         if (__pNode == null)
1520                         {
1521                                 return E_OUT_OF_RANGE;
1522                         }
1523                 }
1524                 else
1525                 {
1526                         if (__pNode->pPrev != null)
1527                         {
1528                                 __pNode = __pNode->pPrev;
1529                         }
1530                         else
1531                         {
1532                                 return E_OUT_OF_RANGE;
1533                         }
1534                 }
1535
1536                 return E_SUCCESS;
1537         }
1538
1539         result ResetLast(void)
1540         {
1541                 return Reset();
1542         }
1543
1544 private:
1545         const LinkedListT< Type >& __list;
1546         __LinkedListNodeT< Type >* __pNode;
1547         int __modCount;
1548
1549 }; // __LinkedListEnumeratorT
1550
1551 }}} // Tizen::Base::Collection
1552
1553 #endif // _FCOL_LINKED_LIST_T_H_