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