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.
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.
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>
32 // TODO: The implementation of _PointerList_ should be completely rewritten to
33 // use STL in a more efficent way!
38 class AbstractPointerListHelper
{
40 AbstractPointerListHelper() {};
41 virtual ~AbstractPointerListHelper();
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
);
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
);
55 Sorts the items in list.
57 void SortItems(BList
*list
);
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
;
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.
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
,
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()
105 AbstractPointerListHelper::Swap(void **items
, int32 i
, int32 j
)
107 void *swap
= items
[i
];
114 AbstractPointerListHelper::BinarySearchIndex(const void *key
, const BList
*list
)
117 const void **items
= static_cast<const void**>(list
->Items());
118 BinarySearch(key
, items
, list
->CountItems(), index
);
124 AbstractPointerListHelper::BinarySearch(const void *key
, const BList
*list
)
127 const void **items
= static_cast<const void**>(list
->Items());
128 return BinarySearch(key
, items
, list
->CountItems(), index
);
133 AbstractPointerListHelper::SortItems(BList
*list
)
135 void **items
= static_cast<void**>(list
->Items());
136 QuickSort(items
, 0, list
->CountItems()-1);
141 AbstractPointerListHelper::HSortItems(BList
*list
)
143 void **items
= static_cast<void**>(list
->Items());
144 int32 numItems
= list
->CountItems();
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);
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
);
164 index
= -(index
+ 1);
171 AbstractPointerListHelper::QuickSort(void **items
, int32 low
, int32 high
)
174 sort(&items
[low
], &items
[high
+1], comparator(this));
179 class PointerListHelper
: public AbstractPointerListHelper
{
181 PointerListHelper(_PointerList_::GenericCompareFunction compareFunc
)
182 : fCompareFunc(compareFunc
)
187 int Compare(const void *a
, const void *b
)
189 return fCompareFunc(a
, b
);
193 _PointerList_::GenericCompareFunction fCompareFunc
;
197 class PointerListHelperWithState
: public AbstractPointerListHelper
200 PointerListHelperWithState(
201 _PointerList_::GenericCompareFunctionWithState compareFunc
,
203 : fCompareFunc(compareFunc
)
209 int Compare(const void *a
, const void *b
)
211 return fCompareFunc(a
, b
, fState
);
215 _PointerList_::GenericCompareFunctionWithState fCompareFunc
;
220 class PointerListHelperUsePredicate
: public AbstractPointerListHelper
223 PointerListHelperUsePredicate(
224 _PointerList_::UnaryPredicateGlue predicate
)
225 : fPredicate(predicate
)
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
));
237 _PointerList_::UnaryPredicateGlue fPredicate
;
241 // Implementation of class _PointerList_
243 _PointerList_::_PointerList_(int32 itemsPerBlock
, bool own
)
245 BList(itemsPerBlock
),
252 _PointerList_::_PointerList_(const _PointerList_
&list
)
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!!!
270 _PointerList_::EachElement(GenericEachFunction function
, void *arg
)
272 int32 numItems
= CountItems();
275 for (int32 index
= 0; index
< numItems
; index
++) {
276 result
= function(ItemAtFast(index
), arg
);
286 _PointerList_::SortItems(GenericCompareFunction compareFunc
)
288 PointerListHelper
helper(compareFunc
);
289 helper
.SortItems(this);
294 _PointerList_::SortItems(GenericCompareFunctionWithState compareFunc
,
297 PointerListHelperWithState
helper(compareFunc
, state
);
298 helper
.SortItems(this);
303 _PointerList_::HSortItems(GenericCompareFunction compareFunc
)
305 PointerListHelper
helper(compareFunc
);
306 helper
.HSortItems(this);
311 _PointerList_::HSortItems(GenericCompareFunctionWithState compareFunc
,
314 PointerListHelperWithState
helper(compareFunc
, state
);
315 helper
.HSortItems(this);
320 _PointerList_::BinarySearch(const void *key
,
321 GenericCompareFunction compareFunc
) const
323 PointerListHelper
helper(compareFunc
);
324 return helper
.BinarySearch(key
, this);
329 _PointerList_::BinarySearch(const void *key
,
330 GenericCompareFunctionWithState compareFunc
, void *state
) const
332 PointerListHelperWithState
helper(compareFunc
, state
);
333 return helper
.BinarySearch(key
, this);
338 _PointerList_::BinarySearchIndex(const void *key
,
339 GenericCompareFunction compareFunc
) const
341 PointerListHelper
helper(compareFunc
);
342 return helper
.BinarySearchIndex(key
, this);
347 _PointerList_::BinarySearchIndex(const void *key
,
348 GenericCompareFunctionWithState compareFunc
, void *state
) const
350 PointerListHelperWithState
helper(compareFunc
, state
);
351 return helper
.BinarySearchIndex(key
, this);
356 _PointerList_::BinarySearchIndexByPredicate(const void *key
,
357 UnaryPredicateGlue predicate
) const
359 PointerListHelperUsePredicate
helper(predicate
);
360 return helper
.BinarySearchIndex(key
, this);
364 _PointerList_::ReplaceItem(int32 index
, void *newItem
)
366 if (index
< 0 || index
>= CountItems())
369 void **items
= static_cast<void **>(Items());
370 items
[index
] = newItem
;
377 _PointerList_::MoveItem(int32 from
, int32 to
)
382 void* fromItem
= ItemAt(from
);
383 void* toItem
= ItemAt(to
);
384 if (fromItem
== NULL
|| toItem
== NULL
)
387 void** items
= static_cast<void**>(Items());
389 memmove(items
+ from
, items
+ from
+ 1, (to
- from
) * sizeof(void*));
391 memmove(items
+ to
+ 1, items
+ to
, (from
- to
) * sizeof(void*));
393 items
[to
] = fromItem
;