2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file FBaseColArrayList.cpp
20 * @brief This is the implementation for ArrayList class.
24 #include <unique_ptr.h>
26 #include <FBaseColArrayList.h>
27 #include <FBaseResult.h>
28 #include <FBaseSysLog.h>
31 namespace Tizen { namespace Base { namespace Collection
35 * @class _ArrayListEnumerator
36 * @brief This is an implementation of IEnumerator for ArrayList.
38 class _ArrayListEnumerator
39 : public IBidirectionalEnumerator
43 _ArrayListEnumerator(const ArrayList& list, int modCount);
44 virtual ~_ArrayListEnumerator(void);
46 virtual Object* GetCurrent(void) const;
47 virtual result MoveNext(void);
48 virtual result Reset(void);
50 virtual result MovePrevious();
51 virtual result ResetLast();
54 const ArrayList& __list;
59 _ArrayListEnumerator::_ArrayListEnumerator(const ArrayList& list, int modCount)
61 , __modCount(modCount)
66 _ArrayListEnumerator::~_ArrayListEnumerator(void)
71 _ArrayListEnumerator::GetCurrent(void) const
73 SysTryReturn(NID_BASE_COL, (__modCount == __list.__modCount), null, E_INVALID_OPERATION, "[%s] The source collection was modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
74 SysTryReturn(NID_BASE_COL, ((__position >= 0) && (__position < __list.__count)), null, E_INVALID_OPERATION, "[%s] Current position(%d) is before the first element or past the last element.", GetErrorMessage(E_INVALID_OPERATION), __position);
76 SetLastResult(E_SUCCESS);
78 return __list.__pObjArray[__position];
82 _ArrayListEnumerator::MoveNext(void)
84 SysTryReturnResult(NID_BASE_COL, (__modCount == __list.__modCount), E_INVALID_OPERATION, "The source collection was modified after the creation of this enumerator.");
86 if ((__position + 1) >= static_cast< int >(__list.__count))
88 return E_OUT_OF_RANGE;
99 _ArrayListEnumerator::Reset(void)
101 SysTryReturnResult(NID_BASE_COL, (__modCount == __list.__modCount), E_INVALID_OPERATION, "The source collection was modified after the creation of this enumerator.");
109 _ArrayListEnumerator::MovePrevious(void)
111 SysTryReturnResult(NID_BASE_COL, (__modCount == __list.__modCount), E_INVALID_OPERATION, "The source collection was modified after the creation of this enumerator.");
112 SysTryReturnResult(NID_BASE_COL, __position > 0, E_OUT_OF_RANGE, "Reached start of the list, no previous element.");
120 _ArrayListEnumerator::ResetLast(void)
122 SysTryReturnResult(NID_BASE_COL, (__modCount == __list.__modCount), E_INVALID_OPERATION, "The source collection was modified after the creation of this enumerator.");
124 __position = __list.__count;
128 ArrayList::ArrayList(DeleterFunctionType deleter)
135 , __pArrayListImpl(null)
140 ArrayList::Construct(int capacity)
142 SysTryReturnResult(NID_BASE_COL, capacity >= 0, E_INVALID_ARG, "The capacity(%d) MUST be greater than or equal to 0.", capacity);
144 result r = SetCapacity(capacity);
145 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
151 ArrayList::Construct(const ICollection& collection)
153 result r = AddItems(collection);
154 SysTryCatch(NID_BASE_COL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
159 delete[] __pObjArray;
165 ArrayList::~ArrayList(void)
168 delete[] __pObjArray;
172 ArrayList::Add(Object* pObj)
174 SysTryReturnResult(NID_BASE_COL, pObj != null, E_INVALID_ARG, "Invalid argument used. The pObj is null");
176 if (__count >= __capacity)
178 result r = SetCapacity(__capacity + DEFAULT_CAPACITY);
179 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
182 __pObjArray[__count++] = pObj;
190 ArrayList::AddItems(const ICollection& collection)
192 result r = E_SUCCESS;
194 int insertingCount = collection.GetCount();
195 if (insertingCount <= 0)
200 if (insertingCount > (__capacity - __count))
202 r = SetCapacity(__count + insertingCount);
203 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
206 std::unique_ptr< IEnumerator > pEnum(collection.GetEnumeratorN());
207 SysTryReturnResult(NID_BASE_COL, pEnum != null, GetLastResult(), "Propagating.");
210 while ((r = pEnum->MoveNext()) != E_OUT_OF_RANGE)
212 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
214 Object* pItem = pEnum->GetCurrent();
215 SysTryReturnResult(NID_BASE_COL, pItem != null, GetLastResult(), "Propagating.");
217 __pObjArray[__count++] = pItem;
224 ArrayList::GetEnumeratorN(void) const
226 return GetBidirectionalEnumeratorN();
229 IBidirectionalEnumerator*
230 ArrayList::GetBidirectionalEnumeratorN(void) const
232 std::unique_ptr< _ArrayListEnumerator > pEnum(new (std::nothrow) _ArrayListEnumerator(*this, __modCount));
233 SysTryReturn(NID_BASE_COL, pEnum != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
235 SetLastResult(E_SUCCESS);
236 return pEnum.release();
240 ArrayList::GetAt(int index) const
242 SysTryReturn(NID_BASE_COL, index >= 0 && index < __count, null, E_OUT_OF_RANGE, "[%s] The index(%d) MUST be greater than or equal to 0 and less than the number of elements(%d).", GetErrorMessage(E_OUT_OF_RANGE), index, __count);
244 SetLastResult(E_SUCCESS);
245 return __pObjArray[index];
249 ArrayList::GetAt(int index)
251 const Object* pObj = (static_cast< const ArrayList* >(this))->GetAt(index);
252 return const_cast< Object* >(pObj);
256 ArrayList::GetItemsN(int startIndex, int count) const
258 result r = E_SUCCESS;
259 SysTryReturn(NID_BASE_COL, startIndex >= 0 && count >= 0, null, E_OUT_OF_RANGE, "[%s] Both of the startIndex(%d) and count(%d) MUST be greater than or equal to 0.", GetErrorMessage(E_OUT_OF_RANGE), startIndex, count);
260 SysTryReturn(NID_BASE_COL, startIndex < __count, null, E_OUT_OF_RANGE,
261 "[%s] The startIndex(%d) MUST be less than the number of elements(%d).", GetErrorMessage(E_OUT_OF_RANGE), startIndex, __count);
262 SysTryReturn(NID_BASE_COL, count <= __count && (startIndex + count <= __count), null, E_OUT_OF_RANGE,
263 "[%s] The startIndex(%d) + count(%d) MUST be less than or equal to the number of elements(%d).", GetErrorMessage(E_OUT_OF_RANGE), startIndex, count, __count);
265 std::unique_ptr< ArrayList > pList(new (std::nothrow) ArrayList());
266 SysTryReturn(NID_BASE_COL, pList != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
268 r = pList->Construct(count);
269 SysTryReturn(NID_BASE_COL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
271 memcpy(pList->__pObjArray, __pObjArray + startIndex, sizeof(Object*) * count);
272 pList->__count = count;
274 SetLastResult(E_SUCCESS);
275 return pList.release();
279 ArrayList::IndexOf(const Object& obj, int& index) const
281 return IndexOf(obj, 0, __count, index);
285 ArrayList::IndexOf(const Object& obj, int startIndex, int& index) const
287 SysTryReturnResult(NID_BASE_COL, startIndex >= 0 && startIndex < __count, E_OUT_OF_RANGE, "The startIndex(%d) MUST be greater than or equal to 0, and less than the number of elements(%d).", startIndex, __count);
288 return IndexOf(obj, startIndex, (__count - startIndex), index);
292 ArrayList::IndexOf(const Object& obj, int startIndex, int count, int& index) const
294 SysTryReturnResult(NID_BASE_COL, __count != 0, E_OBJ_NOT_FOUND, "The arraylist is empty.");
295 SysTryReturnResult(NID_BASE_COL, startIndex >= 0 && count >= 0, E_OUT_OF_RANGE, "Both of the startIndex(%d) and count(%d) MUST be greater than or equal to 0.", startIndex, count);
296 SysTryReturnResult(NID_BASE_COL, startIndex < __count, E_OUT_OF_RANGE,
297 "The startIndex(%d) MUST be less than the number of elements(%d).", startIndex, __count);
298 SysTryReturnResult(NID_BASE_COL, count <= __count && (startIndex + count <= __count), E_OUT_OF_RANGE,
299 "The startIndex(%d) + count(%d) MUST be less than or equal to the number of elements(%d).", startIndex, count, __count);
301 int arrayListCount = startIndex + count;
302 for (int i = startIndex; i < arrayListCount; i++)
304 if (__pObjArray[i]->Equals(obj))
311 return E_OBJ_NOT_FOUND;
315 ArrayList::LastIndexOf(const Object& obj, int& index) const
317 for (int i = (__count - 1); i >= 0; i--)
319 if (__pObjArray[i]->Equals(obj))
326 SysLogException(NID_BASE_COL, E_OBJ_NOT_FOUND, "The object is not in the list.");
327 return E_OBJ_NOT_FOUND;
331 ArrayList::InsertAt(Object* pObj, int index)
333 SysTryReturnResult(NID_BASE_COL, pObj != null, E_INVALID_ARG, "Invalid argument used. The pObj is null");
334 SysTryReturnResult(NID_BASE_COL, index >= 0 && index <= __count, E_OUT_OF_RANGE, "The index(%d) MUST be greater than or equal to 0, and less than or equal to the number of elements(%d).", index, __count);
336 if (__count >= __capacity)
338 result r = SetCapacity(__capacity + DEFAULT_CAPACITY);
339 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
342 memmove(__pObjArray + index + 1, __pObjArray + index, sizeof(Object*) * (__count - index));
346 __pObjArray[index] = pObj;
352 ArrayList::InsertItemsFrom(const ICollection& collection, int startIndex)
354 SysTryReturnResult(NID_BASE_COL, startIndex >= 0 && startIndex <= __count, E_OUT_OF_RANGE, "The startIndex(%d) MUST be greater than or equal to 0, and less than or equal to the number of elements(%d).", startIndex, __count);
356 result r = E_SUCCESS;
357 int insertingCount = collection.GetCount();
359 if (insertingCount <= 0)
364 if (insertingCount > (__capacity - __count))
366 r = SetCapacity(__count + insertingCount);
367 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
370 memmove(__pObjArray + startIndex + insertingCount, __pObjArray + startIndex, sizeof(Object*) * (__count - startIndex));
371 __count += insertingCount;
373 std::unique_ptr< IEnumerator > pEnum(collection.GetEnumeratorN());
374 SysTryReturnResult(NID_BASE_COL, pEnum != null, GetLastResult(), "Propagating.");
378 Object* pItem = null;
379 while ((r = pEnum->MoveNext()) != E_OUT_OF_RANGE)
381 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
383 pItem = pEnum->GetCurrent();
384 SysTryReturnResult(NID_BASE_COL, pItem != null, GetLastResult(), "Propagating.");
386 __pObjArray[startIndex++] = pItem;
393 ArrayList::Remove(const Object& obj)
396 result r = IndexOf(obj, index);
397 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
399 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.")
404 ArrayList::RemoveAt(int index)
406 SysTryReturnResult(NID_BASE_COL, index < __count && index >= 0, E_OUT_OF_RANGE, "The index MUST be greater than or equal to 0, and less than the number of elements(%d).", index, __count);
411 __deleter(__pObjArray[index]);
413 memmove(__pObjArray + index, __pObjArray + index + 1, sizeof(Object*) * (__count - index));
419 ArrayList::RemoveItems(int startIndex, int count)
421 SysTryReturnResult(NID_BASE_COL, startIndex >= 0 && count >= 0, E_OUT_OF_RANGE, "Both of the startIndex(%d) and count(%d) MUST be greater than or equal to 0.", startIndex, count);
422 SysTryReturnResult(NID_BASE_COL, startIndex < __count, E_OUT_OF_RANGE,
423 "The startIndex(%d) MUST be less than the number of elements(%d).", startIndex, __count);
424 SysTryReturnResult(NID_BASE_COL, count <= __count && (startIndex + count <= __count), E_OUT_OF_RANGE,
425 "The startIndex(%d) + count(%d) MUST be less than or equal to the number of elements(%d).", startIndex, count, __count);
434 int arrayListCount = startIndex + count;
435 for (i = startIndex; i < arrayListCount; i++)
437 __deleter(__pObjArray[i]);
440 memmove(__pObjArray + startIndex, __pObjArray + arrayListCount, sizeof(Object*) * (__count - startIndex));
447 ArrayList::RemoveItems(const ICollection& collection)
449 result r = E_SUCCESS;
451 std::unique_ptr< IEnumerator > pEnum(collection.GetEnumeratorN());
452 SysTryReturnResult(NID_BASE_COL, pEnum != null, GetLastResult(), "Propagating.");
454 while ((r = pEnum->MoveNext()) != E_OUT_OF_RANGE)
456 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
458 Object* pItem = pEnum->GetCurrent();
459 SysTryReturnResult(NID_BASE_COL, pItem != null, GetLastResult(), "Propagating.");
462 SysTryLog(NID_BASE_COL, !IsFailed(r), "[%s] Propagating.", GetErrorMessage(r));
468 ArrayList::RemoveAll()
470 for (int i = 0; i < __count; i++)
472 __deleter(__pObjArray[i]);
473 __pObjArray[i] = null;
481 ArrayList::SetAt(Object* pObj, int index)
483 SysTryReturnResult(NID_BASE_COL, pObj != null, E_INVALID_ARG, "Invalid argument used. The pObj is null");
484 SysTryReturnResult(NID_BASE_COL, index >= 0 && index < __count, E_OUT_OF_RANGE, "The index(%d) MUST be greater than or equal to 0, less than the number of elements(%d).", index, __count);
488 __deleter(__pObjArray[index]);
490 __pObjArray[index] = pObj;
496 ArrayList::SetCapacity(int newCapacity)
498 SysTryReturnResult(NID_BASE_COL, (newCapacity >= 0), E_INVALID_ARG, "The newCapacity(%d) MUST be greater than or equal to 0.", newCapacity);
500 if (__capacity == newCapacity)
505 Object** pNewArray = null;
508 pNewArray = new (std::nothrow) Object*[newCapacity];
509 SysTryReturn(NID_BASE_COL, pNewArray != null, E_OUT_OF_MEMORY, E_OUT_OF_RANGE, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
511 if (__pObjArray != null)
513 int count = __count < newCapacity ? __count : newCapacity;
514 memcpy(pNewArray, __pObjArray, sizeof(Object*) * count);
517 if (__pObjArray != null)
519 delete[] __pObjArray;
522 if (__count > newCapacity)
524 __count = newCapacity;
527 __pObjArray = pNewArray;
528 __capacity = newCapacity;
534 ArrayList::Sort(const IComparer& comparer)
541 __pComparer = const_cast< IComparer* >(&comparer);
542 result r = QuickSort(0, (__count - 1));
545 SysLogException(NID_BASE_COL, r, "[%s] Propagating.", GetErrorMessage(r));
555 ArrayList::Trim(void)
557 result r = E_SUCCESS;
558 r = SetCapacity(__count);
559 if (IsFailed(r) == true)
566 ArrayList::GetCapacity(void) const
572 ArrayList::GetCount(void) const
578 ArrayList::Contains(const Object& obj) const
580 for (int i = 0; i < __count; i++)
582 if (__pObjArray[i]->Equals(obj))
592 ArrayList::ContainsAll(const ICollection& collection) const
594 result r = E_SUCCESS;
597 if (collection.GetCount() == 0)
602 std::unique_ptr< IEnumerator > pEnum(collection.GetEnumeratorN());
603 SysTryReturn(NID_BASE_COL, pEnum != null, false, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
605 while ((r = pEnum->MoveNext()) != E_OUT_OF_RANGE)
607 SysTryReturn(NID_BASE_COL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
609 Object* pItem = pEnum->GetCurrent();
610 SysTryReturn(NID_BASE_COL, pItem != null, false, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
612 if (!Contains(*pItem))
622 ArrayList::Equals(const Object& obj) const
629 const ArrayList* pOther = dynamic_cast< const ArrayList* >(&obj);
634 else if (__count != pOther->__count)
640 for (int i = 0; i < __count; i++)
642 if (!(__pObjArray[i]->Equals(*(pOther->__pObjArray[i]))))
653 ArrayList::GetHashCode(void) const
656 for (int i = 0; i < __count; i++)
658 hash += __pObjArray[i]->GetHashCode();
665 ArrayList::GetDeleter(void) const
671 ArrayList::QuickSort(int startIndex, int endIndex)
673 result r = E_SUCCESS;
675 if (startIndex < endIndex)
678 int i = startIndex - 1;
679 int j = endIndex + 1;
683 int compareResult = 1;
685 while ((compareResult > 0) && (j > static_cast< int >(startIndex)))
688 r = __pComparer->Compare(*(__pObjArray[j]), *(__pObjArray[startIndex]), compareResult);
689 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
693 while ((compareResult < 0) && (i < endIndex))
696 r = __pComparer->Compare(*(__pObjArray[i]), *(__pObjArray[startIndex]), compareResult);
697 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
702 Object* pTemp = __pObjArray[j];
703 __pObjArray[j] = __pObjArray[i];
704 __pObjArray[i] = pTemp;
713 r = QuickSort(startIndex, middleIndex);
714 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
716 r = QuickSort(middleIndex + 1, endIndex);
717 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
724 ArrayList::SetDeleter(DeleterFunctionType deleter)
729 }}} // Tizen::Base::Collection