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