2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @file FBaseColArrayList.cpp
19 * @brief This is the implementation for ArrayList class.
23 #include <unique_ptr.h>
25 #include <FBaseColArrayList.h>
26 #include <FBaseResult.h>
27 #include <FBaseSysLog.h>
30 namespace Tizen { namespace Base { namespace Collection
34 * @class _ArrayListEnumerator
35 * @brief This is an implementation of IEnumerator for ArrayList.
37 class _ArrayListEnumerator
38 : public IBidirectionalEnumerator
42 _ArrayListEnumerator(const ArrayList& list, int modCount);
43 virtual ~_ArrayListEnumerator(void);
45 virtual Object* GetCurrent(void) const;
46 virtual result MoveNext(void);
47 virtual result Reset(void);
49 virtual result MovePrevious();
50 virtual result ResetLast();
53 const ArrayList& __list;
58 _ArrayListEnumerator::_ArrayListEnumerator(const ArrayList& list, int modCount)
60 , __modCount(modCount)
65 _ArrayListEnumerator::~_ArrayListEnumerator(void)
70 _ArrayListEnumerator::GetCurrent(void) const
72 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));
73 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);
75 SetLastResult(E_SUCCESS);
77 return __list.__pObjArray[__position];
81 _ArrayListEnumerator::MoveNext(void)
83 SysTryReturnResult(NID_BASE_COL, (__modCount == __list.__modCount), E_INVALID_OPERATION, "The source collection was modified after the creation of this enumerator.");
85 if ((__position + 1) >= static_cast< int >(__list.__count))
87 return E_OUT_OF_RANGE;
98 _ArrayListEnumerator::Reset(void)
100 SysTryReturnResult(NID_BASE_COL, (__modCount == __list.__modCount), E_INVALID_OPERATION, "The source collection was modified after the creation of this enumerator.");
108 _ArrayListEnumerator::MovePrevious(void)
110 SysTryReturnResult(NID_BASE_COL, (__modCount == __list.__modCount), E_INVALID_OPERATION, "The source collection was modified after the creation of this enumerator.");
111 SysTryReturnResult(NID_BASE_COL, __position > 0, E_OUT_OF_RANGE, "Reached start of the list, no previous element.");
119 _ArrayListEnumerator::ResetLast(void)
121 SysTryReturnResult(NID_BASE_COL, (__modCount == __list.__modCount), E_INVALID_OPERATION, "The source collection was modified after the creation of this enumerator.");
123 __position = __list.__count;
127 ArrayList::ArrayList(DeleterFunctionType deleter)
134 , __pArrayListImpl(null)
139 ArrayList::Construct(int capacity)
141 SysTryReturnResult(NID_BASE_COL, capacity >= 0, E_INVALID_ARG, "The capacity(%d) MUST be greater than or equal to 0.", capacity);
143 result r = SetCapacity(capacity);
144 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
150 ArrayList::Construct(const ICollection& collection)
152 result r = AddItems(collection);
153 SysTryCatch(NID_BASE_COL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
158 delete[] __pObjArray;
164 ArrayList::~ArrayList(void)
167 delete[] __pObjArray;
171 ArrayList::Add(Object* pObj)
173 SysTryReturnResult(NID_BASE_COL, pObj != null, E_INVALID_ARG, "Invalid argument used. The pObj is null");
175 if (__count >= __capacity)
177 result r = SetCapacity(__capacity + DEFAULT_CAPACITY);
178 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
181 __pObjArray[__count++] = pObj;
189 ArrayList::AddItems(const ICollection& collection)
191 result r = E_SUCCESS;
193 int insertingCount = collection.GetCount();
194 if (insertingCount <= 0)
199 if (insertingCount > (__capacity - __count))
201 r = SetCapacity(__count + insertingCount);
202 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
205 std::unique_ptr< IEnumerator > pEnum(collection.GetEnumeratorN());
206 SysTryReturnResult(NID_BASE_COL, pEnum != null, GetLastResult(), "Propagating.");
209 while ((r = pEnum->MoveNext()) != E_OUT_OF_RANGE)
211 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
213 Object* pItem = pEnum->GetCurrent();
214 SysTryReturnResult(NID_BASE_COL, pItem != null, GetLastResult(), "Propagating.");
216 __pObjArray[__count++] = pItem;
223 ArrayList::GetEnumeratorN(void) const
225 return GetBidirectionalEnumeratorN();
228 IBidirectionalEnumerator*
229 ArrayList::GetBidirectionalEnumeratorN(void) const
231 std::unique_ptr< _ArrayListEnumerator > pEnum(new (std::nothrow) _ArrayListEnumerator(*this, __modCount));
232 SysTryReturn(NID_BASE_COL, pEnum != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
234 SetLastResult(E_SUCCESS);
235 return pEnum.release();
239 ArrayList::GetAt(int index) const
241 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);
243 SetLastResult(E_SUCCESS);
244 return __pObjArray[index];
248 ArrayList::GetAt(int index)
250 const Object* pObj = (static_cast< const ArrayList* >(this))->GetAt(index);
251 return const_cast< Object* >(pObj);
255 ArrayList::GetItemsN(int startIndex, int count) const
257 result r = E_SUCCESS;
258 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);
259 SysTryReturn(NID_BASE_COL, startIndex < __count, null, E_OUT_OF_RANGE,
260 "[%s] The startIndex(%d) MUST be less than the number of elements(%d).", GetErrorMessage(E_OUT_OF_RANGE), startIndex, __count);
261 SysTryReturn(NID_BASE_COL, count <= __count && (startIndex + count <= __count), null, E_OUT_OF_RANGE,
262 "[%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);
264 std::unique_ptr< ArrayList > pList(new (std::nothrow) ArrayList());
265 SysTryReturn(NID_BASE_COL, pList != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
267 r = pList->Construct(count);
268 SysTryReturn(NID_BASE_COL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
270 memcpy(pList->__pObjArray, __pObjArray + startIndex, sizeof(Object*) * count);
271 pList->__count = count;
273 SetLastResult(E_SUCCESS);
274 return pList.release();
278 ArrayList::IndexOf(const Object& obj, int& index) const
280 return IndexOf(obj, 0, __count, index);
284 ArrayList::IndexOf(const Object& obj, int startIndex, int& index) const
286 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);
287 return IndexOf(obj, startIndex, (__count - startIndex), index);
291 ArrayList::IndexOf(const Object& obj, int startIndex, int count, int& index) const
293 SysTryReturnResult(NID_BASE_COL, __count != 0, E_OBJ_NOT_FOUND, "The arraylist is empty.");
294 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);
295 SysTryReturnResult(NID_BASE_COL, startIndex < __count, E_OUT_OF_RANGE,
296 "The startIndex(%d) MUST be less than the number of elements(%d).", startIndex, __count);
297 SysTryReturnResult(NID_BASE_COL, count <= __count && (startIndex + count <= __count), E_OUT_OF_RANGE,
298 "The startIndex(%d) + count(%d) MUST be less than or equal to the number of elements(%d).", startIndex, count, __count);
300 int arrayListCount = startIndex + count;
301 for (int i = startIndex; i < arrayListCount; i++)
303 if (__pObjArray[i]->Equals(obj))
310 return E_OBJ_NOT_FOUND;
314 ArrayList::LastIndexOf(const Object& obj, int& index) const
316 for (int i = (__count - 1); i >= 0; i--)
318 if (__pObjArray[i]->Equals(obj))
325 SysLogException(NID_BASE_COL, E_OBJ_NOT_FOUND, "The object is not in the list.");
326 return E_OBJ_NOT_FOUND;
330 ArrayList::InsertAt(Object* pObj, int index)
332 SysTryReturnResult(NID_BASE_COL, pObj != null, E_INVALID_ARG, "Invalid argument used. The pObj is null");
333 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);
335 if (__count >= __capacity)
337 result r = SetCapacity(__capacity + DEFAULT_CAPACITY);
338 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
341 memmove(__pObjArray + index + 1, __pObjArray + index, sizeof(Object*) * (__count - index));
345 __pObjArray[index] = pObj;
351 ArrayList::InsertItemsFrom(const ICollection& collection, int startIndex)
353 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);
355 result r = E_SUCCESS;
356 int insertingCount = collection.GetCount();
358 if (insertingCount <= 0)
363 if (insertingCount > (__capacity - __count))
365 r = SetCapacity(__count + insertingCount);
366 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
369 memmove(__pObjArray + startIndex + insertingCount, __pObjArray + startIndex, sizeof(Object*) * (__count - startIndex));
370 __count += insertingCount;
372 std::unique_ptr< IEnumerator > pEnum(collection.GetEnumeratorN());
373 SysTryReturnResult(NID_BASE_COL, pEnum != null, GetLastResult(), "Propagating.");
377 Object* pItem = null;
378 while ((r = pEnum->MoveNext()) != E_OUT_OF_RANGE)
380 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
382 pItem = pEnum->GetCurrent();
383 SysTryReturnResult(NID_BASE_COL, pItem != null, GetLastResult(), "Propagating.");
385 __pObjArray[startIndex++] = pItem;
392 ArrayList::Remove(const Object& obj)
395 result r = IndexOf(obj, index);
396 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
398 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.")
403 ArrayList::RemoveAt(int index)
405 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);
410 __deleter(__pObjArray[index]);
412 memmove(__pObjArray + index, __pObjArray + index + 1, sizeof(Object*) * (__count - index));
418 ArrayList::RemoveItems(int startIndex, int count)
420 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);
421 SysTryReturnResult(NID_BASE_COL, startIndex < __count, E_OUT_OF_RANGE,
422 "The startIndex(%d) MUST be less than the number of elements(%d).", startIndex, __count);
423 SysTryReturnResult(NID_BASE_COL, count <= __count && (startIndex + count <= __count), E_OUT_OF_RANGE,
424 "The startIndex(%d) + count(%d) MUST be less than or equal to the number of elements(%d).", startIndex, count, __count);
433 int arrayListCount = startIndex + count;
434 for (i = startIndex; i < arrayListCount; i++)
436 __deleter(__pObjArray[i]);
439 memmove(__pObjArray + startIndex, __pObjArray + arrayListCount, sizeof(Object*) * (__count - startIndex));
446 ArrayList::RemoveItems(const ICollection& collection)
448 result r = E_SUCCESS;
450 std::unique_ptr< IEnumerator > pEnum(collection.GetEnumeratorN());
451 SysTryReturnResult(NID_BASE_COL, pEnum != null, GetLastResult(), "Propagating.");
453 while ((r = pEnum->MoveNext()) != E_OUT_OF_RANGE)
455 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
457 Object* pItem = pEnum->GetCurrent();
458 SysTryReturnResult(NID_BASE_COL, pItem != null, GetLastResult(), "Propagating.");
461 SysTryLog(NID_BASE_COL, !IsFailed(r), "[%s] Propagating.", GetErrorMessage(r));
467 ArrayList::RemoveAll()
469 for (int i = 0; i < __count; i++)
471 __deleter(__pObjArray[i]);
472 __pObjArray[i] = null;
480 ArrayList::SetAt(Object* pObj, int index)
482 SysTryReturnResult(NID_BASE_COL, pObj != null, E_INVALID_ARG, "Invalid argument used. The pObj is null");
483 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);
487 __deleter(__pObjArray[index]);
489 __pObjArray[index] = pObj;
495 ArrayList::SetCapacity(int newCapacity)
497 SysTryReturnResult(NID_BASE_COL, (newCapacity >= 0), E_INVALID_ARG, "The newCapacity(%d) MUST be greater than or equal to 0.", newCapacity);
499 if (__capacity == newCapacity)
504 Object** pNewArray = null;
507 pNewArray = new (std::nothrow) Object*[newCapacity];
508 SysTryReturn(NID_BASE_COL, pNewArray != null, E_OUT_OF_MEMORY, E_OUT_OF_RANGE, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
510 if (__pObjArray != null)
512 int count = __count < newCapacity ? __count : newCapacity;
513 memcpy(pNewArray, __pObjArray, sizeof(Object*) * count);
516 if (__pObjArray != null)
518 delete[] __pObjArray;
521 if (__count > newCapacity)
523 __count = newCapacity;
526 __pObjArray = pNewArray;
527 __capacity = newCapacity;
533 ArrayList::Sort(const IComparer& comparer)
540 __pComparer = const_cast< IComparer* >(&comparer);
541 result r = QuickSort(0, (__count - 1));
544 SysLogException(NID_BASE_COL, r, "[%s] Propagating.", GetErrorMessage(r));
554 ArrayList::Trim(void)
556 result r = E_SUCCESS;
557 r = SetCapacity(__count);
558 if (IsFailed(r) == true)
565 ArrayList::GetCapacity(void) const
571 ArrayList::GetCount(void) const
577 ArrayList::Contains(const Object& obj) const
579 for (int i = 0; i < __count; i++)
581 if (__pObjArray[i]->Equals(obj))
591 ArrayList::ContainsAll(const ICollection& collection) const
593 result r = E_SUCCESS;
596 if (collection.GetCount() == 0)
601 std::unique_ptr< IEnumerator > pEnum(collection.GetEnumeratorN());
602 SysTryReturn(NID_BASE_COL, pEnum != null, false, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
604 while ((r = pEnum->MoveNext()) != E_OUT_OF_RANGE)
606 SysTryReturn(NID_BASE_COL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
608 Object* pItem = pEnum->GetCurrent();
609 SysTryReturn(NID_BASE_COL, pItem != null, false, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
611 if (!Contains(*pItem))
621 ArrayList::Equals(const Object& obj) const
628 const ArrayList* pOther = dynamic_cast< const ArrayList* >(&obj);
633 else if (__count != pOther->__count)
639 for (int i = 0; i < __count; i++)
641 if (!(__pObjArray[i]->Equals(*(pOther->__pObjArray[i]))))
652 ArrayList::GetHashCode(void) const
655 for (int i = 0; i < __count; i++)
657 hash += __pObjArray[i]->GetHashCode();
664 ArrayList::GetDeleter(void) const
670 ArrayList::QuickSort(int startIndex, int endIndex)
672 result r = E_SUCCESS;
674 if (startIndex < endIndex)
677 int i = startIndex - 1;
678 int j = endIndex + 1;
682 int compareResult = 1;
684 while ((compareResult > 0) && (j > static_cast< int >(startIndex)))
687 r = __pComparer->Compare(*(__pObjArray[j]), *(__pObjArray[startIndex]), compareResult);
688 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
692 while ((compareResult < 0) && (i < endIndex))
695 r = __pComparer->Compare(*(__pObjArray[i]), *(__pObjArray[startIndex]), compareResult);
696 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
701 Object* pTemp = __pObjArray[j];
702 __pObjArray[j] = __pObjArray[i];
703 __pObjArray[i] = pTemp;
712 r = QuickSort(startIndex, middleIndex);
713 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
715 r = QuickSort(middleIndex + 1, endIndex);
716 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
723 ArrayList::SetDeleter(DeleterFunctionType deleter)
728 }}} // Tizen::Base::Collection