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