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