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