Add to retry to read DUID.
[platform/framework/native/appfw.git] / inc / FBaseColArrayListT.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                FBaseColArrayListT.h
19  * @brief               This is the header file for the %ArrayListT class.
20  *
21  * This header file contains the declarations of the %ArrayListT class.
22  */
23 #ifndef _FBASE_COL_ARRAY_LIST_T_H_
24 #define _FBASE_COL_ARRAY_LIST_T_H_
25
26 #include <FBaseResult.h>
27 #include <FBaseColIListT.h>
28 #include <FBaseColIComparerT.h>
29
30 namespace Tizen { namespace Base { namespace Collection
31 {
32
33 template< class Type > class __ArrayListEnumeratorT;
34
35 /**
36  * @class ArrayListT
37  * @brief This class provides a template-based collection of objects that can be individually accessed by an index.
38  *
39  * @since 2.0
40  *
41  * The %ArrayListT class provides a template-based collection of objects that can be individually accessed by an index.
42  *
43  * For more information on the class features, see <a href="../org.tizen.native.appprogramming/html/guide/base/arraylist_linkedlist.htm">ArrayList and LinkedList</a>.
44  *
45  * The following example demonstrates how to use the %ArrayListT class to create and initialize an %ArrayListT instance and to print out its values.
46  *
47  * @code
48  *      #include <FBase.h>
49  *
50  *      using namespace Tizen::Base;
51  *      using namespace Tizen::Base::Collection;
52  *
53  *      void
54  *      MyClass::ArrayListTSample(void)
55  *      {
56  *              ArrayListT< int > list;
57  *
58  *              list.Construct();
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  *
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 ArrayListT
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          * @remarks             After creating an instance of this class, one of the Construct() methods must be called explicitly to initialize this instance.
109          */
110         ArrayListT(void)
111                 : __capacity(0)
112                 , __count(0)
113                 , __pObjArray(null)
114                 , __modCount(0)
115                 , __pComparer(null)
116         {
117         }
118
119         /**
120          * This destructor overrides Tizen::Base::Object::~Object().
121          *
122          * @since 2.0
123          */
124         virtual ~ArrayListT(void)
125         {
126                 if (__pObjArray != null)
127                 {
128                         delete[] __pObjArray;
129                 }
130         }
131
132         /**
133          * Initializes this instance of %ArrayListT with the specified parameter.
134          *
135          * @since 2.0
136          *
137          * @return              An error code
138          * @param[in]   capacity                The initial capacity of the class @n
139          *                              The default capacity is @c 10.
140          * @exception   E_SUCCESS               The method is successful.
141          * @exception   E_INVALID_ARG   A specified input parameter is invalid, or
142          *                                                              the specified @c capacity is negative.
143          * @remarks             If the number of elements added to the list reaches its current capacity,
144          *                              the capacity is automatically increased by memory reallocation.
145          *                              Thus, if the size of the list can be estimated,
146          *                              specifying the initial capacity eliminates the need to perform a number of
147          *                              resizing operations while adding elements to the list.
148          * @see                 ArrayListT()
149          */
150         result Construct(int capacity = DEFAULT_CAPACITY)
151         {
152                 TryReturn(capacity >= 0, E_INVALID_ARG, "[%s] The capacity(%d) MUST be greater than or equal to 0.", GetErrorMessage(E_INVALID_ARG), capacity);
153
154                 result r = SetCapacity(capacity);
155                 TryReturn(r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
156
157                 return r;
158         }
159
160         /**
161          * Initializes this instance of %ArrayListT with the specified parameter. @n
162          * The capacity of the list is the same as the number of elements copied to it.
163          *
164          * @since 2.0
165          *
166          * @return              An error code
167          * @param[in]   collection                      A collection of elements to add
168          * @exception   E_SUCCESS                       The method is successful.
169          * @exception   E_INVALID_OPERATION     The current state of the instance prohibits the execution of the specified operation, or
170          *                                                                      the @c collection is modified during the operation of this method.
171          * @see                 ArrayListT()
172          */
173         result Construct(const ICollectionT< Type >& collection)
174         {
175                 result r = AddItems(collection);
176                 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
177
178                 return r;
179
180 CATCH:
181                 delete[] __pObjArray;
182                 __pObjArray = null;
183
184                 return r;
185         }
186
187         /**
188          * Adds the specified object to the end of the list.
189          *
190          * @since 2.0
191          *
192          * @return              An error code
193          * @param[in]   obj                             An object to add to the list
194          * @exception   E_SUCCESS               The method is successful.
195          * @exception   E_OUT_OF_MEMORY The memory is insufficient.
196          * @see                 Remove()
197          */
198         virtual result Add(const Type& obj)
199         {
200                 if (__count >= __capacity)
201                 {
202                         result r = SetCapacity(__capacity + DEFAULT_CAPACITY);
203                         TryReturn(r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
204                 }
205
206                 __pObjArray[__count++] = obj;
207
208                 __modCount++;
209
210                 return E_SUCCESS;
211         }
212
213         /**
214          * Adds the elements of the specified collection to the end of the list.
215          *
216          * @since 2.0
217          *
218          * @return              An error code
219          * @param[in]   collection                      A collection of elements to add to the list
220          * @exception   E_SUCCESS                       The method is successful.
221          * @exception   E_INVALID_OPERATION     The current state of the instance prohibits the execution of the specified operation, or
222          *                                                                      the @c collection is modified during the operation of this method.
223          * @see                 RemoveItems()
224          */
225         virtual result AddItems(const ICollectionT< Type >& collection)
226         {
227                 result r = E_SUCCESS;
228
229                 IEnumeratorT< Type >* pEnum = null;
230                 int count = collection.GetCount();
231                 if (count > 0)
232                 {
233                         if (count > (__capacity - __count))
234                         {
235                                 r = SetCapacity(__count + count);
236                                 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
237                         }
238
239                         ICollectionT< Type >* pCol = const_cast< ICollectionT< Type >* >(&collection);
240                         pEnum = pCol->GetEnumeratorN();
241                         TryReturn(pEnum != null, r = GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
242
243                         __modCount++;
244
245                         while ((r = pEnum->MoveNext()) != E_OUT_OF_RANGE)
246                         {
247                                 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
248
249                                 Type item;
250                                 r = pEnum->GetCurrent(item);
251                                 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
252
253                                 __pObjArray[__count++] = item;
254                         }
255                 }
256
257                 delete pEnum;
258                 return E_SUCCESS;
259
260 CATCH:
261                 delete pEnum;
262                 return r;
263         }
264
265         /**
266          * Gets the elements of the list in an instance of the IEnumeratorT derived class.
267          *
268          * @since 2.0
269          *
270          * @return              An instance of the IEnumeratorT derived class if successful, @n
271          *                              else @c null if an exception occurs
272          * @exception   E_SUCCESS                       The method is successful.
273          * @exception   E_OUT_OF_MEMORY         The memory is insufficient.
274          * @remarks             The specific error code can be accessed using the GetLastResult() method.
275          * @see                 Tizen::Base::Collection::IEnumeratorT
276          */
277         virtual IEnumeratorT< Type >* GetEnumeratorN(void) const
278         {
279                 result r = E_SUCCESS;
280
281                 __ArrayListEnumeratorT< Type >* pEnum = new __ArrayListEnumeratorT< Type >(*this, __modCount);
282                 TryCatch(pEnum != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
283
284                 SetLastResult(E_SUCCESS);
285                 return pEnum;
286
287 CATCH:
288                 SetLastResult(r);
289                 return null;
290         }
291
292         /**
293          * Gets a bidirectional enumerator (an instance of the IBidirectionalEnumeratorT derived class) of this list.
294          *
295          * @since 2.0
296          *
297          * @return              An instance of the IBidirectionalEnumeratorT derived class, @n
298          *                              else @c null if an exception occurs
299          * @exception   E_SUCCESS                       The method is successful.
300          * @exception   E_OUT_OF_MEMORY         The memory is insufficient.
301          * @remarks             Use this method to obtain a bidirectional enumerator (an instance of the IBidirectionalEnumeratorT derived class)
302          *                              to iterate over a collection (an instance of the IListT derived class).
303          * @remarks             The specific error code can be accessed using the GetLastResult() method.
304          * @see                 Tizen::Base::Collection::IBidirectionalEnumeratorT
305          */
306         virtual IBidirectionalEnumeratorT< Type >* GetBidirectionalEnumeratorN(void) const
307         {
308                 result r = E_SUCCESS;
309
310                 __ArrayListEnumeratorT< Type >* pEnum = new __ArrayListEnumeratorT< Type >(*this, __modCount);
311                 TryCatch(pEnum != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
312
313                 SetLastResult(E_SUCCESS);
314                 return pEnum;
315
316 CATCH:
317                 SetLastResult(r);
318                 return null;
319         }
320
321         /**
322          * Gets the object at the specified @c index of the list.
323          *
324          * @since 2.0
325          *
326          * @return              An error code
327          * @param[in]   index                                   The index of the object to read
328          * @param[out]  obj                                             An object to get from this list
329          * @exception   E_SUCCESS                               The method is successful.
330          * @exception   E_OUT_OF_RANGE                  The specified @c index is outside the bounds of the data structure, or
331          *                                                                              the specified @c index is either equal to or greater than the number of elements or less than @c 0.
332          * @see                 SetAt()
333          */
334         virtual result GetAt(int index, Type& obj) const
335         {
336                 TryReturn(index >= 0 && index < __count, E_OUT_OF_RANGE,
337                         "[%s] The index(%d) MUST be greater than or equal to 0 and less than the number of elements(%d).",
338                         GetErrorMessage(E_OUT_OF_RANGE), index, __count);
339
340                 obj = __pObjArray[index];
341                 return E_SUCCESS;
342         }
343
344         /**
345          * Gets the object at the specified @c index of the list.
346          *
347          * @since 2.0
348          *
349          * @return              An error code
350          * @param[in]   index                                   The index of the object to read
351          * @param[out]  obj                                             An object to get from this list
352          * @exception   E_SUCCESS                               The method is successful.
353          * @exception   E_OUT_OF_RANGE                  The specified @c index is outside the bounds of the data structure, or
354          *                                                                              the specified @c index is either equal to or greater than the number of elements or less than @c 0.
355          * @see                 SetAt()
356          */
357         virtual result GetAt(int index, Type& obj)
358         {
359                 TryReturn(index >= 0 && index < __count, E_OUT_OF_RANGE,
360                         "[%s] The index(%d) MUST be greater than or equal to 0 and less than the number of elements(%d).",
361                         GetErrorMessage(E_OUT_OF_RANGE), index, __count);
362
363                 obj = __pObjArray[index];
364                 return E_SUCCESS;
365         }
366
367         /**
368          * Gets a list of a specified number of elements starting from a specified index.
369          *
370          * @since 2.0
371          *
372          * @return              An instance of the IListT derived class within the specified range of the list, @n
373          *                              else @c null if an exception occurs
374          * @param[in]   startIndex      The index to start reading elements from
375          * @param[in]   count           The number of elements to read
376          * @exception   E_SUCCESS                               The method is successful.
377          * @exception   E_INVALID_ARG                   A specified input parameter is invalid.
378          * @exception   E_OUT_OF_RANGE                  Either of the following conditions has occurred: @n
379          *                                                                              - The specified index is outside the bounds of the data structure. @n
380          *                                                                              - The specified @c startIndex is either greater than or equal to the number of elements or less than @c 0. @n
381          *                                                                              - The specified @c count is either greater than the number of elements starting from @c startIndex or less than @c 0.
382          *
383          * @remarks             The specific error code can be accessed using the GetLastResult() method.
384          */
385         virtual IListT< Type >* GetItemsN(int startIndex, int count) const
386         {
387                 result r = E_SUCCESS;
388
389                 ArrayListT< Type >* pList = null;
390
391                 TryCatch(startIndex >= 0 && count >= 0, r = E_OUT_OF_RANGE,
392                         "[%s] Both of the startIndex(%d) and count(%d) MUST be greater than or equal to 0.", GetErrorMessage(E_OUT_OF_RANGE), startIndex, count);
393                 TryCatch(startIndex < __count, r = E_OUT_OF_RANGE,
394                         "[%s] The startIndex(%d) MUST be less than the number of elements(%d).", GetErrorMessage(E_OUT_OF_RANGE), startIndex, __count);
395                 TryCatch(count <= __count && (startIndex + count <= __count), r = E_OUT_OF_RANGE,
396                         "[%s] The startIndex(%d) + count(%d) MUST be less than or equal to the number of elements(%d).",
397                         GetErrorMessage(E_OUT_OF_RANGE), startIndex, count, __count);
398
399                 pList = new ArrayListT< Type >();
400
401                 r = pList->Construct(count);
402                 TryCatch(r == E_SUCCESS, delete pList, "[%s] Propagating.", GetErrorMessage(r));
403
404                 for (int i = startIndex; i < (startIndex + count); i++)
405                 {
406                         pList->__pObjArray[pList->__count++] = __pObjArray[i];
407                 }
408
409                 SetLastResult(E_SUCCESS);
410                 return pList;
411
412 CATCH:
413                 SetLastResult(r);
414                 return null;
415         }
416
417         /**
418          * Searches for an object in this list. @n
419          * Gets the index of the object if found.
420          *
421          * @since 2.0
422          *
423          * @return              An error code
424          * @param[in]   obj                     The object to locate
425          * @param[out]  index           The index of the object
426          * @exception   E_SUCCESS                       The method is successful.
427          * @exception   E_OBJ_NOT_FOUND         The specified @c obj is not found.
428          * @see                 LastIndexOf()
429          */
430         virtual result IndexOf(const Type& obj, int& index) const
431         {
432                 return IndexOf(obj, 0, __count, index);
433         }
434
435         /**
436          * Searches for an object starting from the specified @c index. @n
437          * Gets the index of the object if found.
438          *
439          * @since 2.0
440          *
441          * @return              An error code
442          * @param[in]   obj                     The object to locate
443          * @param[in]   startIndex      The starting index for the search @n
444          *                                                      It must be less than the number of elements.
445          * @param[out]  index           The index of the object
446          * @exception   E_SUCCESS                               The method is successful.
447          * @exception   E_OUT_OF_RANGE                  The specified @c index is outside the bounds of the data structure, or
448          *                                                                              the specified @c startIndex is either equal to or greater than the number of elements or less than @c 0.
449          * @exception   E_OBJ_NOT_FOUND                 The specified @c obj is not found.
450          * @see                 LastIndexOf()
451          */
452         virtual result IndexOf(const Type& obj, int startIndex, int& index) const
453         {
454                 TryReturn(startIndex >= 0 && startIndex < __count, E_OUT_OF_RANGE,
455                         "[%s] The startIndex(%d) MUST be greater than or equal to 0, and less than the number of elements(%d).",
456                         GetErrorMessage(E_OUT_OF_RANGE), startIndex, __count);
457
458                 return IndexOf(obj, startIndex, (__count - startIndex), index);
459         }
460
461         /**
462          * Searches for an object within the specified range. @n
463          * Gets the index of the object if found.
464          *
465          * @since 2.0
466          *
467          * @return              An error code
468          * @param[in]   obj                     The object to locate
469          * @param[in]   startIndex      The starting index of the range
470          * @param[in]   count           The number of elements to read
471          * @param[out]  index           The index of the object
472          * @exception   E_SUCCESS                               The method is successful.
473          * @exception   E_OUT_OF_RANGE                  Either of the following conditions has occurred: @n
474          *                                                                              - The specified @c index is outside the bounds of the data structure. @n
475          *                                                                              - The specified @c startIndex is either greater than or equal to the number of elements or less than @c 0. @n
476          *                                                                              - The specified @c count is either greater than the number of elements starting from @c startIndex or less than @c 0.
477          * @exception   E_OBJ_NOT_FOUND                 The specified @c obj is not found.
478          * @see                 LastIndexOf()
479          */
480         virtual result IndexOf(const Type& obj, int startIndex, int count, int& index) const
481         {
482                 TryReturn(startIndex >= 0 && count >= 0, E_OUT_OF_RANGE,
483                         "[%s] Both of the startIndex(%d) and count(%d) MUST be greater than or equal to 0.", GetErrorMessage(E_OUT_OF_RANGE), startIndex, count);
484                 TryReturn(startIndex < __count, E_OUT_OF_RANGE,
485                         "[%s] The startIndex(%d) MUST be less than the number of elements(%d).", GetErrorMessage(E_OUT_OF_RANGE), startIndex, __count);
486                 TryReturn(count <= __count && (startIndex + count <= __count), E_OUT_OF_RANGE,
487                         "[%s] The startIndex(%d) + count(%d) MUST be less than or equal to the number of elements(%d).",
488                         GetErrorMessage(E_OUT_OF_RANGE), startIndex, count, __count);
489
490                 int arrayListCount = startIndex + count;
491                 for (int i = startIndex; i < arrayListCount; i++)
492                 {
493                         if (obj == __pObjArray[i])
494                         {
495                                 index = i;
496                                 return E_SUCCESS;
497                         }
498                 }
499
500                 return E_OBJ_NOT_FOUND;
501         }
502
503         /**
504          * Inserts an object at a specified location.
505          *
506          * @since 2.0
507          *
508          * @return              An error code
509          * @param[in]   obj             The object to insert
510          * @param[in]   index   The index at which the object must be inserted
511          * @exception   E_SUCCESS                               The method is successful.
512          * @exception   E_OUT_OF_RANGE                  The specified @c index is outside the bounds of the data structure, or
513          *                                                                              the @c index is greater than the number of elements or less than @c 0.
514          * @remarks             The elements that follow the insertion point move down to accommodate the new element.
515          *                              If the @c index equals the number of elements in the list, the new element
516          *                              is added at the end of the list.
517          * @see                 Add()
518          * @see                 RemoveAt()
519          */
520         virtual result InsertAt(const Type& obj, int index)
521         {
522                 TryReturn(index >= 0 && index <= __count, E_OUT_OF_RANGE,
523                         "[%s] The index(%d) MUST be greater than or equal to 0, and less than or equal to the number of elements(%d).",
524                         GetErrorMessage(E_OUT_OF_RANGE), index, __count);
525
526                 result r = E_SUCCESS;
527
528                 if (__count >= __capacity)
529                 {
530                         r = SetCapacity(__capacity + DEFAULT_CAPACITY);
531                         TryReturn(r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
532                 }
533
534                 for (int i = __count; i > index; i--)
535                 {
536                         __pObjArray[i] = __pObjArray[i - 1];
537                 }
538
539                 __count++;
540                 __modCount++;
541                 __pObjArray[index] = obj;
542
543                 return E_SUCCESS;
544         }
545
546         /**
547          * Inserts the elements of a collection at a specified location.
548          *
549          * @since 2.0
550          *
551          * @return              An error code
552          * @param[in]   collection      The collection to insert
553          * @param[in]   startIndex      The index from which the collection must be inserted
554          * @exception   E_SUCCESS                               The method is successful.
555          * @exception   E_OUT_OF_RANGE                  The specified index is outside the bounds of the data structure, or
556          *                                                                              the @c startIndex is greater than the number of elements or less than @c 0.
557          * @exception   E_INVALID_OPERATION             The current state of the instance prohibits the execution of the specified operation, or
558          *                                                                              the @c collection is modified during the operation of this method.
559          * @remarks             The elements that follow the insertion point move down to accommodate the new elements.
560          *                              If the @c startIndex equals the number of elements in the list, the new elements
561          *                              are added at the end of the list.
562          * @see                 RemoveItems()
563          * @see                 AddItems()
564          */
565         virtual result InsertItemsFrom(const ICollectionT< Type >& collection, int startIndex)
566         {
567                 TryReturn(startIndex >= 0 && startIndex <= __count, E_OUT_OF_RANGE,
568                         "[%s] The startIndex(%d) MUST be greater than or equal to 0, and less than or equal to the number of elements(%d).",
569                         GetErrorMessage(E_OUT_OF_RANGE), startIndex, __count);
570
571                 result r = E_SUCCESS;
572
573                 IEnumeratorT< Type >* pEnum = null;
574                 int count = collection.GetCount();
575
576                 if (count > 0)
577                 {
578                         if (count > (__capacity - __count))
579                         {
580                                 r = SetCapacity(__count + count);
581                                 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
582                         }
583
584                         __count += count;
585                         for (int i = (__count - 1); i >= (startIndex + count); i--)
586                         {
587                                 __pObjArray[i] = __pObjArray[i - count];
588                         }
589
590                         ICollectionT< Type >* pCol = const_cast< ICollectionT< Type >* >(&collection);
591                         pEnum = pCol->GetEnumeratorN();
592                         TryReturn(pEnum != null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
593
594                         __modCount++;
595
596                         while ((r = pEnum->MoveNext()) != E_OUT_OF_RANGE)
597                         {
598                                 Type item;
599
600                                 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
601
602                                 r = pEnum->GetCurrent(item);
603                                 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
604
605                                 __pObjArray[startIndex++] = item;
606                         }
607                 }
608
609                 delete pEnum;
610                 return E_SUCCESS;
611
612 CATCH:
613                 delete pEnum;
614                 return r;
615         }
616
617         /**
618          * Searches for the last occurrence of an object in this list. @n
619          * Gets the index of the object if found.
620          *
621          * @since 2.0
622          *
623          * @return              An error code
624          * @param[in]   obj                     The object to locate
625          * @param[out]  index           The index of the last occurrence of the specified object
626          * @exception   E_SUCCESS               The method is successful.
627          * @exception   E_OBJ_NOT_FOUND The specified @c obj is not found.
628          * @see                 IndexOf()
629          */
630         virtual result LastIndexOf(const Type& obj, int& index) const
631         {
632                 for (int i = (__count - 1); i >= 0; i--)
633                 {
634                         if (obj == __pObjArray[i])
635                         {
636                                 index = i;
637                                 return E_SUCCESS;
638                         }
639                 }
640
641                 return E_OBJ_NOT_FOUND;
642         }
643
644         /**
645          * Removes the first occurrence of a specified object.
646          *
647          * @since 2.0
648          *
649          * @return              An error code
650          * @param[in]   obj                             The object to remove
651          * @exception   E_SUCCESS               The method is successful.
652          * @exception   E_OBJ_NOT_FOUND The specified @c obj is not found.
653          * @see                 Add()
654          * @see                 RemoveAt()
655          * @see                 RemoveAll()
656          */
657         virtual result Remove(const Type& obj)
658         {
659                 int index;
660                 result r = IndexOf(obj, index);
661                 if (IsFailed(r))
662                 {
663                         return E_OBJ_NOT_FOUND;
664                 }
665                 else
666                 {
667                         return RemoveAt(index);
668                 }
669         }
670
671         /**
672          * Removes all the elements of a specified collection from the list.
673          *
674          * @since 2.0
675          *
676          * @return              An error code
677          * @param[in]   collection                      The collection to remove from this list
678          * @exception   E_SUCCESS                       The method is successful.
679          * @exception   E_INVALID_OPERATION     The current state of the instance prohibits the execution of the specified operation, or
680          *                                                                      the @c collection is modified during the operation of this method.
681          * @see                 Remove()
682          * @see                 RemoveAt()
683          */
684         virtual result RemoveItems(const ICollectionT< Type >& collection)
685         {
686                 result r = E_SUCCESS;
687                 int oldCount = __count;
688
689                 ICollectionT< Type >* pCol = const_cast< ICollectionT< Type >* >(&collection);
690                 IEnumeratorT< Type >* pEnum = pCol->GetEnumeratorN();
691                 TryCatch(pEnum != null, r = GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
692
693                 while ((r = pEnum->MoveNext()) != E_OUT_OF_RANGE)
694                 {
695                         Type item;
696
697                         TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
698
699                         r = pEnum->GetCurrent(item);
700                         TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
701
702                         r = Remove(item);
703                         TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
704                 }
705
706                 if (__count < oldCount)
707                 {
708                         Trim();
709                 }
710
711                 delete pEnum;
712                 return E_SUCCESS;
713
714 CATCH:
715                 delete pEnum;
716                 return r;
717         }
718
719         /**
720          * Removes an object from a specified location.
721          *
722          * @since 2.0
723          *
724          * @return              An error code
725          * @param[in]   index                                   The index of the object that is to remove
726          * @exception   E_SUCCESS                               The method is successful.
727          * @exception   E_OUT_OF_RANGE                  The specified @c index is outside the bounds of the data structure, or
728          *                                                                              the specified @c index is greater than or equal to the number of elements or less than @c 0.
729          * @remarks             The elements that follow the deleted object move up the list to occupy the empty location.
730          * @see                 InsertAt()
731          * @see                 Remove()
732          */
733         virtual result RemoveAt(int index)
734         {
735                 TryReturn(index < __count && index >= 0, E_OUT_OF_RANGE,
736                         "[%s] The index MUST be greater than or equal to 0, and less than the number of elements(%d).",
737                         GetErrorMessage(E_OUT_OF_RANGE), index, __count);
738
739                 __modCount++;
740                 __count--;
741
742                 for (int i = index; i < __count; i++)
743                 {
744                         __pObjArray[i] = __pObjArray[i + 1];
745                 }
746
747                 Trim();
748
749                 return E_SUCCESS;
750         }
751
752         /**
753          * Removes all the elements within a specified range.
754          *
755          * @since 2.0
756          *
757          * @return              An error code
758          * @param[in]   startIndex      The starting index of the range
759          * @param[in]   count           The number of elements to remove
760          * @exception   E_SUCCESS                               The method is successful.
761          * @exception   E_OUT_OF_RANGE                  Either of the following conditions has occurred: @n
762          *                                                                              - The specified index is outside the bounds of the data structure. @n
763          *                                                                              - The specified @c startIndex is either greater than or equal to the number of elements or less than @c 0. @n
764          *                                                                              - The specified @c count is either greater than the number of elements starting from @c startIndex or less than @c 0.
765          * @remarks             The elements that follow the deleted elements move up the list to occupy the empty locations.
766          * @see                 AddItems()
767          * @see                 InsertItemsFrom()
768          */
769         virtual result RemoveItems(int startIndex, int count)
770         {
771                 TryReturn(startIndex >= 0 && count >= 0, E_OUT_OF_RANGE,
772                         "[%s] Both of the startIndex(%d) and count(%d) MUST be greater than or equal to 0.", GetErrorMessage(E_OUT_OF_RANGE), startIndex, count);
773                 TryReturn(startIndex < __count, E_OUT_OF_RANGE,
774                         "[%s] The startIndex(%d) MUST be less than the number of elements(%d).", GetErrorMessage(E_OUT_OF_RANGE), startIndex, __count);
775                 TryReturn(count <= __count && (startIndex + count <= __count), E_OUT_OF_RANGE,
776                         "[%s] The startIndex(%d) + count(%d) MUST be less than or equal to the number of elements(%d).",
777                         GetErrorMessage(E_OUT_OF_RANGE), startIndex, count, __count);
778
779                 if (count > 0)
780                 {
781                         Type* newArray = new Type[__capacity];
782                         TryReturn(newArray != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
783
784                         __modCount++;
785                         __count -= count;
786
787                         for (int i = 0; i < startIndex; i++)
788                         {
789                                 newArray[i] = __pObjArray[i];
790                         }
791                         for (int i = startIndex; i < __count; i++)
792                         {
793                                 newArray[i] = __pObjArray[i + count];
794                         }
795
796                         delete[] __pObjArray;
797                         __pObjArray = newArray;
798                 }
799
800                 return E_SUCCESS;
801         }
802
803         /**
804          * Removes all elements in the list.
805          *
806          * @since 2.0
807          */
808         virtual void RemoveAll(void)
809         {
810                 if (__count != 0)
811                 {
812                         delete[] __pObjArray;
813                         __pObjArray = null;
814
815                         __count = 0;
816                         __capacity = 0;
817
818                         __modCount++;
819                 }
820
821         }
822
823         /**
824          * Sets the object at a specified @c index of the current instance of ByteBuffer with the specified object.
825          *
826          * @since 2.0
827          *
828          * @return              An error code
829          * @param[in]   obj             The object to set
830          * @param[in]   index   The index at which the object must be set
831          * @exception   E_SUCCESS                               The method is successful.
832          * @exception   E_OUT_OF_RANGE                  The specified @c index is outside the bounds of the data structure, or
833          *                                                                              the specified @c index is either equal to or greater than the number of elements or less than @c 0.
834          * @see                 GetAt()
835          */
836         virtual result SetAt(const Type& obj, int index)
837         {
838                 TryReturn(index >= 0 && index < __count, E_OUT_OF_RANGE,
839                         "[%s] The index(%d) MUST be greater than or equal to 0, less than the number of elements(%d).",
840                         GetErrorMessage(E_OUT_OF_RANGE), index, __count);
841
842                 __modCount++;
843
844                 __pObjArray[index] = obj;
845
846                 return E_SUCCESS;
847         }
848
849         /**
850          * Sets the capacity of the list to a specified value.
851          *
852          * @since 2.0
853          *
854          * @return              An error code
855          * @param[in]   newCapacity             The new capacity to set for the list
856          * @exception   E_SUCCESS               The method is successful.
857          * @exception   E_INVALID_ARG   A specified input parameter is invalid, or
858          *                                                              the @c newCapacity is negative.
859          * @remarks             If the new capacity is less than the current capacity, the memory
860          *                              is truncated and the elements within the truncated memory are destroyed.
861          * @see                 Construct()
862          * @see                 Trim()
863          * @see                 GetCapacity()
864          */
865         virtual result SetCapacity(int newCapacity)
866         {
867                 TryReturn(newCapacity >= 0, E_INVALID_ARG, "[%s] The newCapacity(%d) MUST be greater than or equal to 0.",
868                         GetErrorMessage(E_INVALID_ARG), newCapacity);
869
870                 result r = E_SUCCESS;
871                 if (__capacity != newCapacity)
872                 {
873                         Type* newArray = null;
874                         if (newCapacity > 0)
875                         {
876                                 newArray = new Type[newCapacity];
877                                 TryCatch(newArray != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
878
879                                 if (__pObjArray != null)
880                                 {
881                                         int count = __count < newCapacity ? __count : newCapacity;
882                                         for (int i = 0; i < count; i++)
883                                         {
884                                                 newArray[i] = __pObjArray[i];
885                                         }
886                                 }
887                         }
888                         if (__pObjArray != null)
889                         {
890                                 delete[] __pObjArray;
891                         }
892                         if (__count > newCapacity)
893                         {
894                                 __modCount++;
895                                 __count = newCapacity;
896                         }
897                         __pObjArray = newArray;
898                         __capacity = newCapacity;
899                 }
900
901                 return r;
902
903 CATCH:
904                 return r;
905         }
906
907         /**
908          * Sorts the elements in the list using a comparer.
909          *
910          * @since 2.0
911          *
912          * @return              An error code
913          * @param[in]   comparer                A pointer to IComparerT
914          * @exception   E_SUCCESS               The method is successful.
915          * @exception   E_INVALID_ARG   A specified input parameter is invalid, or
916          *                                                              the @c comparer is not valid.
917          */
918         virtual result Sort(const IComparerT< Type >& comparer)
919         {
920                 if (0 == __count)
921                         return E_SUCCESS;
922
923                 __pComparer = const_cast< IComparerT< Type >* >(&comparer);
924                 result r = QuickSort(0, (__count - 1));
925                 if (IsFailed(r))
926                 {
927                         AppLogException("[%s] Propagating.", GetErrorMessage(r));
928                         __pComparer = null;
929
930                         return r;
931                 }
932
933                 return E_SUCCESS;
934         }
935
936         /**
937          * Trims the capacity of a list to the actual number of elements in the list.
938          *
939          * @since 2.0
940          *
941          * @return              An error code
942          * @exception   E_SUCCESS               The method is successful.
943          * @exception   E_OUT_OF_MEMORY The memory is insufficient.
944          * @remarks             The specific error code can be accessed using the GetLastResult() method.
945          * @see                 SetCapacity()
946          */
947         virtual void Trim(void)
948         {
949                 if (__capacity == 0)
950                 {
951                         return;
952                 }
953
954                 result r = SetCapacity(__count);
955                 if (IsFailed(r))
956                 {
957                         AppLogException("[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
958                 }
959         }
960
961         /**
962          * Gets the current capacity of the list.
963          *
964          * @since 2.0
965          *
966          * @return      The current capacity of the list
967          * @see         SetCapacity()
968          */
969         int GetCapacity(void) const
970         {
971                 return __capacity;
972         }
973
974         /**
975          * Gets the number of objects currently stored in the list.
976          *
977          * @since 2.0
978          *
979          * @return              The number of objects stored in the list
980          */
981         virtual int GetCount(void) const
982         {
983                 return __count;
984         }
985
986         /**
987          * Checks whether a list contains the specified object.
988          *
989          * @since 2.0
990          *
991          * @return              @c true if the object is present in the list, @n
992          *                              else @c false
993          * @param[in]   obj The object to locate
994          * @see                 ContainsAll()
995          */
996         virtual bool Contains(const Type& obj) const
997         {
998                 if (__count == 0)
999                 {
1000                         return false;
1001                 }
1002
1003                 for (int i = 0; i < __count; i++)
1004                 {
1005                         if (obj == __pObjArray[i])
1006                         {
1007                                 return true;
1008                         }
1009                 }
1010
1011                 return false;
1012         }
1013
1014         /**
1015          * Checks whether the list contains all the elements of the specified @c collection.
1016          *
1017          * @since 2.0
1018          *
1019          * @return              An error code
1020          * @param[in]   collection      The collection to check for in the list
1021          * @param[out]  out                     @c true if the list contains all the elements of the specified @c collection, @n
1022          *                                                      else @c false
1023          * @exception   E_SUCCESS                       The method is successful.
1024          * @exception   E_INVALID_OPERATION     The current state of the instance prohibits the execution of the specified operation, or
1025          *                                                                      the @c collection is modified during the operation of this method.
1026          * @remarks             If the given @c collection is empty, the @c out parameter will be set to @c true.
1027          * @see                 Contains()
1028          */
1029         virtual result ContainsAll(const ICollectionT< Type >& collection, bool& out) const
1030         {
1031                 result r = E_SUCCESS;
1032                 out = false;
1033
1034                 if (collection.GetCount() == 0)
1035                 {
1036                         out = true;
1037                         return E_SUCCESS;
1038                 }
1039
1040                 ICollectionT< Type >* pCol = const_cast< ICollectionT< Type >* >(&collection);
1041                 IEnumeratorT< Type >* pEnum = pCol->GetEnumeratorN();
1042                 TryReturn(pEnum != null, r = GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1043
1044                 while ((r = pEnum->MoveNext()) != E_OUT_OF_RANGE)
1045                 {
1046                         Type item;
1047
1048                         TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
1049
1050                         r = pEnum->GetCurrent(item);
1051                         TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
1052
1053                         if (false == Contains(item))
1054                         {
1055                                 delete pEnum;
1056
1057                                 return E_SUCCESS;
1058                         }
1059                 }
1060
1061
1062                 delete pEnum;
1063
1064                 out = true;
1065
1066                 return E_SUCCESS;
1067
1068 CATCH:
1069                 delete pEnum;
1070
1071                 return r;
1072         }
1073
1074         /**
1075          * Compares two instances of the %ArrayListT class.
1076          *
1077          * @since 2.0
1078          *
1079          * @return              @c true if the two instances match, @n
1080          *                              else @c false
1081          * @param[in]   obj The object to compare with the current instance
1082          * @remarks             This method returns @c true if and only if the two instances contain the same elements in the same order.
1083          */
1084         virtual bool Equals(const Tizen::Base::Object& obj) const
1085         {
1086                 const ArrayListT< Type >* other = dynamic_cast< const ArrayListT< Type >* >(&obj);
1087                 if (null == other)
1088                 {
1089                         return false;
1090                 }
1091                 else if (other == this)
1092                 {
1093                         return true;
1094                 }
1095                 else if (__count != other->__count)
1096                 {
1097                         return false;
1098                 }
1099                 else
1100                 {
1101                         for (int i = 0; i < __count; i++)
1102                         {
1103                                 if (__pObjArray[i] != other->__pObjArray[i])
1104                                 {
1105                                         return false;
1106                                 }
1107                         }
1108                 }
1109
1110                 return true;
1111         }
1112
1113         /**
1114          * Gets the hash value of the current instance.
1115          *
1116          * @since 2.0
1117          *
1118          * @return      The hash value of the current instance
1119          * @remarks     The two Tizen::Base::Object::Equals() instances must return the same hash value. For better performance, @n
1120          *                      the used hash function must generate a random distribution for all inputs.
1121          */
1122         virtual int GetHashCode(void) const
1123         {
1124                 int hash = 0;
1125                 for (int i = 0; i < __count; i++)
1126                 {
1127                         if (&(__pObjArray[i]) != null)
1128                         {
1129                                 hash += reinterpret_cast< int >(&(__pObjArray[i]));
1130                         }
1131                 }
1132                 return hash;
1133         }
1134
1135 private:
1136         /**
1137          * The implementation of this copy constructor is intentionally blank and declared as private to prohibit copying of objects.
1138          *
1139          * @param[in]   list The instance of the %ArrayListT class to copy from
1140          */
1141         ArrayListT(const ArrayListT< Type >& list);
1142
1143         /**
1144          * The implementation of this copy assignment operator is intentionally blank and declared as private to prohibit copying of objects.
1145          *
1146          * @param[in]   list An instance of %ArrayListT
1147          */
1148         ArrayListT< Type >& operator =(const ArrayListT< Type >& list);
1149
1150         /**
1151          * Sorts a section of a list using a comparer.
1152          *
1153          * @return              An error code
1154          * @param[in]   startIndex              The start index of the section of the list
1155          * @param[in]   endIndex                The end index of the section of the list
1156          * @exception   E_SUCCESS               The method is successful.
1157          * @exception   E_INVALID_ARG   A specified input parameter is invalid, or
1158          *                                                              the comparer has failed to compare the elements.
1159          */
1160         result QuickSort(int startIndex, int endIndex)
1161         {
1162                 result r = E_SUCCESS;
1163
1164                 if (startIndex < endIndex)
1165                 {
1166                         int middleIndex;
1167                         int i = startIndex - 1;
1168                         int j = endIndex + 1;
1169                         while (true)
1170                         {
1171                                 int compareResult = 1;
1172                                 while ((compareResult > 0) && (j > static_cast< int >(startIndex)))
1173                                 {
1174                                         j--;
1175
1176                                         r = __pComparer->Compare(__pObjArray[j], __pObjArray[startIndex], compareResult);
1177                                         TryReturn(r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1178                                 }
1179
1180                                 compareResult = -1;
1181                                 while ((compareResult < 0) && (i < static_cast< int >(endIndex)))
1182                                 {
1183                                         i++;
1184
1185                                         r = __pComparer->Compare(__pObjArray[i], __pObjArray[startIndex], compareResult);
1186                                         TryReturn(r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1187                                 }
1188
1189                                 if (i < j)
1190                                 {
1191                                         Type temp = __pObjArray[j];
1192                                         __pObjArray[j] = __pObjArray[i];
1193                                         __pObjArray[i] = temp;
1194                                 }
1195                                 else
1196                                 {
1197                                         middleIndex = j;
1198                                         break;
1199                                 }
1200                         }
1201
1202                         r = QuickSort(startIndex, middleIndex);
1203                         TryReturn(r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1204
1205                         r = QuickSort(middleIndex + 1, endIndex);
1206                         TryReturn(r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1207                 }
1208
1209                 return r;
1210         }
1211
1212         int __capacity;
1213         int __count;
1214         Type* __pObjArray;
1215         int __modCount;
1216         IComparerT< Type >* __pComparer;
1217         static const int DEFAULT_CAPACITY = 10;
1218
1219         friend class __ArrayListEnumeratorT< Type >;
1220
1221 }; // ArrayListT
1222
1223 //
1224 // @class       __ArrayListEnumeratorT
1225 // @brief       This class is an implementation of the IEnumeratorT interface for the %ArrayListT class.
1226 // @since 2.0
1227 //
1228 template< class Type >
1229 class __ArrayListEnumeratorT
1230         : public IBidirectionalEnumeratorT< Type >
1231         , public Tizen::Base::Object
1232 {
1233 public:
1234         __ArrayListEnumeratorT(const ArrayListT< Type >& list, int modCount)
1235                 : __list(list)
1236                 , __modCount(modCount)
1237                 , __position(-1)
1238         {
1239         }
1240
1241         virtual ~__ArrayListEnumeratorT(void)
1242         {
1243         }
1244
1245         virtual result GetCurrent(Type& obj) const
1246         {
1247                 TryReturn((__modCount == __list.__modCount), E_INVALID_OPERATION,
1248                         "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1249                 TryReturn((__position > -1) && (__position < static_cast< int >(__list.__count)), E_INVALID_OPERATION,
1250                         "[%s] Current position(%d) is before the first element or past the last element.", GetErrorMessage(E_INVALID_OPERATION), __position);
1251
1252                 obj = __list.__pObjArray[__position];
1253                 return E_SUCCESS;
1254         }
1255
1256         virtual result MoveNext(void)
1257         {
1258                 TryReturn((__modCount == __list.__modCount), E_INVALID_OPERATION,
1259                         "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1260
1261                 if ((__position + 1) >= static_cast< int >(__list.__count))
1262                 {
1263                         return E_OUT_OF_RANGE;
1264                 }
1265                 else
1266                 {
1267                         __position++;
1268                 }
1269
1270                 return E_SUCCESS;
1271         }
1272
1273         virtual result Reset(void)
1274         {
1275                 TryReturn((__modCount == __list.__modCount), E_INVALID_OPERATION,
1276                         "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1277
1278                 __position = -1;
1279                 return E_SUCCESS;
1280         }
1281
1282         virtual result MovePrevious(void)
1283         {
1284                 TryReturn(__modCount == __list.__modCount, E_INVALID_OPERATION,
1285                         "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1286
1287                 TryReturn(__position > 0, E_OUT_OF_RANGE, "[%s] Reached start of the list, no previous element", GetErrorMessage(E_OUT_OF_RANGE));
1288
1289                 __position--;
1290
1291                 return E_SUCCESS;
1292         }
1293
1294         virtual result ResetLast(void)
1295         {
1296                 TryReturn(__modCount == __list.__modCount, E_INVALID_OPERATION,
1297                         "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1298
1299                 __position = __list.__count;
1300                 return E_SUCCESS;
1301         }
1302
1303 private:
1304         const ArrayListT< Type >& __list;
1305         int __modCount;
1306         int __position;
1307
1308 }; //__ArrayListEnumeratorT
1309
1310 } } } // Tizen::Base::Collection
1311
1312 #endif // _FBASE_COL_ARRAY_LIST_T_H_