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