HaikuDepot: notify work status from main window
[haiku.git] / src / kits / support / PointerList.cpp
blobff8207b32d3aa2753b572a4ad4a85b65561b336d
1 /*
2 ** Copyright 2003-2004, Stefano Ceccherini (burton666@libero.it). All rights reserved.
3 ** 2004, Michael Pfeiffer (laplace@users.sourceforge.net).
4 ** Distributed under the terms of the Haiku License.
5 **
6 ** History
7 ** 2003-2004 Initial implementation by Stefano Ceccerini.
8 ** 2004/08/03 Testing, bug fixing and implementation of quick sort, refactoring
9 ** by Michael Pfeiffer.
12 // TODO:
13 // - Rewrite to use STL
14 // - Include ObjectList.h
15 // - Test if building with jam works
17 // Note: Method Owning() is inlined in header file ObjectList.h
19 #include <ObjectList.h>
21 #include <algorithm>
22 #include <assert.h>
23 #include <functional>
24 #include <string.h>
26 #include <List.h>
29 using namespace std;
32 // TODO: The implementation of _PointerList_ should be completely rewritten to
33 // use STL in a more efficent way!
35 struct comparator;
38 class AbstractPointerListHelper {
39 public:
40 AbstractPointerListHelper() {};
41 virtual ~AbstractPointerListHelper();
43 /**
44 Returns the index of the item that matches key or
45 a negative number. Then -(index+1) is the insert position
46 of the item not in list.
48 int32 BinarySearchIndex(const void *key, const BList *list);
49 /**
50 Returns the item that matches key or NULL if the item could
51 not be found in the list.
53 void* BinarySearch(const void *key, const BList *list);
54 /**
55 Sorts the items in list.
57 void SortItems(BList *list);
58 /**
59 Removes the first item in list and appends it at the bottom of
60 the list and sorts all items but the last item.
62 void HSortItems(BList *list);
64 friend struct comparator;
66 private:
67 enum {
68 // Use insertion sort if number of elements in list is less than
69 // kQuickSortThreshold.
70 kQuickSortThreshold = 11,
71 // Use simple pivot element computation if number of elements in
72 // list is less than kPivotThreshold.
73 kPivotThreshold = 5,
74 };
76 // Methods that do the actual work:
77 inline void Swap(void **items, int32 i, int32 j);
79 void* BinarySearch(const void *key, const void **items, int32 numItems,
80 int32 &index);
81 void QuickSort(void **items, int32 low, int32 high);
83 // Method to be implemented by sub classes
84 int virtual Compare(const void *key, const void* item) = 0;
87 struct comparator : public binary_function<const void*, const void*, bool>
89 comparator(AbstractPointerListHelper* helper) : helper(helper) {}
91 bool operator()(const void* a, const void* b) {
92 return helper->Compare(b, a) > 0;
95 AbstractPointerListHelper* helper;
99 AbstractPointerListHelper::~AbstractPointerListHelper()
104 void
105 AbstractPointerListHelper::Swap(void **items, int32 i, int32 j)
107 void *swap = items[i];
108 items[i] = items[j];
109 items[j] = swap;
113 int32
114 AbstractPointerListHelper::BinarySearchIndex(const void *key, const BList *list)
116 int32 index;
117 const void **items = static_cast<const void**>(list->Items());
118 BinarySearch(key, items, list->CountItems(), index);
119 return index;
123 void *
124 AbstractPointerListHelper::BinarySearch(const void *key, const BList *list)
126 int32 index;
127 const void **items = static_cast<const void**>(list->Items());
128 return BinarySearch(key, items, list->CountItems(), index);
132 void
133 AbstractPointerListHelper::SortItems(BList *list)
135 void **items = static_cast<void**>(list->Items());
136 QuickSort(items, 0, list->CountItems()-1);
140 void
141 AbstractPointerListHelper::HSortItems(BList *list)
143 void **items = static_cast<void**>(list->Items());
144 int32 numItems = list->CountItems();
145 if (numItems > 1) {
146 // swap last with first item
147 Swap(items, 0, numItems-1);
149 // sort all items but last item
150 QuickSort(items, 0, numItems-2);
154 void *
155 AbstractPointerListHelper::BinarySearch(const void *key, const void **items,
156 int32 numItems, int32 &index)
158 const void** end = &items[numItems];
159 const void** found = lower_bound(items, end, key, comparator(this));
160 index = found - items;
161 if (index != numItems && Compare(key, *found) == 0) {
162 return const_cast<void*>(*found);
163 } else {
164 index = -(index + 1);
165 return NULL;
170 void
171 AbstractPointerListHelper::QuickSort(void **items, int32 low, int32 high)
173 if (low <= high) {
174 sort(&items[low], &items[high+1], comparator(this));
179 class PointerListHelper : public AbstractPointerListHelper {
180 public:
181 PointerListHelper(_PointerList_::GenericCompareFunction compareFunc)
182 : fCompareFunc(compareFunc)
184 // nothing to do
187 int Compare(const void *a, const void *b)
189 return fCompareFunc(a, b);
192 private:
193 _PointerList_::GenericCompareFunction fCompareFunc;
197 class PointerListHelperWithState : public AbstractPointerListHelper
199 public:
200 PointerListHelperWithState(
201 _PointerList_::GenericCompareFunctionWithState compareFunc,
202 void* state)
203 : fCompareFunc(compareFunc)
204 , fState(state)
206 // nothing to do
209 int Compare(const void *a, const void *b)
211 return fCompareFunc(a, b, fState);
214 private:
215 _PointerList_::GenericCompareFunctionWithState fCompareFunc;
216 void* fState;
220 class PointerListHelperUsePredicate : public AbstractPointerListHelper
222 public:
223 PointerListHelperUsePredicate(
224 _PointerList_::UnaryPredicateGlue predicate)
225 : fPredicate(predicate)
227 // nothing to do
230 int Compare(const void *arg, const void *item)
232 // need to adapt arguments and return value
233 return -fPredicate(item, const_cast<void *>(arg));
236 private:
237 _PointerList_::UnaryPredicateGlue fPredicate;
241 // Implementation of class _PointerList_
243 _PointerList_::_PointerList_(int32 itemsPerBlock, bool own)
245 BList(itemsPerBlock),
246 owning(own)
252 _PointerList_::_PointerList_(const _PointerList_ &list)
254 BList(list),
255 owning(list.owning)
260 _PointerList_::~_PointerList_()
262 // This is empty by design, the "owning" variable
263 // is used by the BObjectList subclass
267 // Note: function pointers must not be NULL!!!
269 void *
270 _PointerList_::EachElement(GenericEachFunction function, void *arg)
272 int32 numItems = CountItems();
273 void *result = NULL;
275 for (int32 index = 0; index < numItems; index++) {
276 result = function(ItemAtFast(index), arg);
277 if (result != NULL)
278 break;
281 return result;
285 void
286 _PointerList_::SortItems(GenericCompareFunction compareFunc)
288 PointerListHelper helper(compareFunc);
289 helper.SortItems(this);
293 void
294 _PointerList_::SortItems(GenericCompareFunctionWithState compareFunc,
295 void *state)
297 PointerListHelperWithState helper(compareFunc, state);
298 helper.SortItems(this);
302 void
303 _PointerList_::HSortItems(GenericCompareFunction compareFunc)
305 PointerListHelper helper(compareFunc);
306 helper.HSortItems(this);
310 void
311 _PointerList_::HSortItems(GenericCompareFunctionWithState compareFunc,
312 void *state)
314 PointerListHelperWithState helper(compareFunc, state);
315 helper.HSortItems(this);
319 void *
320 _PointerList_::BinarySearch(const void *key,
321 GenericCompareFunction compareFunc) const
323 PointerListHelper helper(compareFunc);
324 return helper.BinarySearch(key, this);
328 void *
329 _PointerList_::BinarySearch(const void *key,
330 GenericCompareFunctionWithState compareFunc, void *state) const
332 PointerListHelperWithState helper(compareFunc, state);
333 return helper.BinarySearch(key, this);
337 int32
338 _PointerList_::BinarySearchIndex(const void *key,
339 GenericCompareFunction compareFunc) const
341 PointerListHelper helper(compareFunc);
342 return helper.BinarySearchIndex(key, this);
346 int32
347 _PointerList_::BinarySearchIndex(const void *key,
348 GenericCompareFunctionWithState compareFunc, void *state) const
350 PointerListHelperWithState helper(compareFunc, state);
351 return helper.BinarySearchIndex(key, this);
355 int32
356 _PointerList_::BinarySearchIndexByPredicate(const void *key,
357 UnaryPredicateGlue predicate) const
359 PointerListHelperUsePredicate helper(predicate);
360 return helper.BinarySearchIndex(key, this);
363 bool
364 _PointerList_::ReplaceItem(int32 index, void *newItem)
366 if (index < 0 || index >= CountItems())
367 return false;
369 void **items = static_cast<void **>(Items());
370 items[index] = newItem;
372 return true;
376 bool
377 _PointerList_::MoveItem(int32 from, int32 to)
379 if (from == to)
380 return true;
382 void* fromItem = ItemAt(from);
383 void* toItem = ItemAt(to);
384 if (fromItem == NULL || toItem == NULL)
385 return false;
387 void** items = static_cast<void**>(Items());
388 if (from < to)
389 memmove(items + from, items + from + 1, (to - from) * sizeof(void*));
390 else
391 memmove(items + to + 1, items + to, (from - to) * sizeof(void*));
393 items[to] = fromItem;
394 return true;