Added a (mostly not tested) _PointerList_ class. Please (Michael Pfeiffer or Ingo, whoever comes here first ) have a look at it :)

Note that I needed to write my own BSearch() because the compare functions used by _PointerList_ wants items as arguments, while the C bsearch() wants pointers to items as arguments.
The same applies to qsort(), though it's not been written yet.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@8744 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stefano Ceccherini
2004-08-31 10:10:23 +00:00
parent b00721dd1e
commit 4826cc5f6a
2 changed files with 264 additions and 0 deletions
+263
View File
@@ -0,0 +1,263 @@
/*
** Copyright 2003-2004, Stefano Ceccherini ([email protected]). All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
// TODO: we need to include this as _PointerList_ is declared there.
// I wonder if we should add a PointerList.h file, then ObjectList.h would contain
// a copy of the declaration
#include <ObjectList.h>
#include <stdlib.h>
// TODO: I used bubble sort, which is notably the slowest possible sorting algorithm
// Why ? Laziness. Fix that!
// Test the class.
typedef int (* GenericCompareFunction)(const void *, const void *);
typedef int (* GenericCompareFunctionWithState)(const void *, const void *, void *);
static void *BSearch(const void *key, const void *start,
size_t numItems, size_t size,
GenericCompareFunction compareFunc);
static void *BSearchWithState(const void *key, const void *start,
size_t numItems, size_t size,
GenericCompareFunctionWithState compareFunc, void *state);
_PointerList_::_PointerList_(int32 itemsPerBlock, bool own)
:
BList(itemsPerBlock),
owning(own)
{
}
_PointerList_::_PointerList_(const _PointerList_ &list)
:
BList(list),
owning(list.owning)
{
}
_PointerList_::~_PointerList_()
{
// This is empty by design, the "owning" variable
// is used by the BObjectList subclass
}
void *
_PointerList_::EachElement(GenericEachFunction function, void *arg)
{
int32 numItems = CountItems();
void *result = NULL;
if (function) {
for (int32 index = 0; index < numItems; index++) {
result = function(ItemAtFast(index), arg);
if (result != NULL)
break;
}
}
return result;
}
void
_PointerList_::SortItems(GenericCompareFunction compareFunc)
{
if (compareFunc) {
int32 numItems = CountItems();
if (numItems > 1) {
void **items = (void **)Items();
for (int32 i = 0; i < numItems - 1; i++) {
for (int32 j = 0; j < numItems - 1 - i; j++) {
if (compareFunc(items[j + 1], items[j]) < 0) {
void *tmp = items[j];
items[j] = items[j + 1];
items[j + 1] = tmp;
}
}
}
}
}
}
void
_PointerList_::SortItems(GenericCompareFunctionWithState compareFunc, void *state)
{
if (compareFunc) {
int32 numItems = CountItems();
if (numItems > 1) {
void **items = (void **)Items();
for (int32 i = 0; i < numItems - 1; i++) {
for (int32 j = 0; j < numItems - 1 - i; j++) {
if (compareFunc(items[j + 1], items[j], state) < 0) {
void *tmp = items[j];
items[j] = items[j + 1];
items[j + 1] = tmp;
}
}
}
}
}
}
void
_PointerList_::HSortItems(GenericCompareFunction sortFunction)
{
//TODO: Does "H" stand for "Heap" ? Should we use Heap Sort here ?
SortItems(sortFunction);
}
void
_PointerList_::HSortItems(GenericCompareFunctionWithState sortFunc, void *state)
{
//TODO: Same as above
SortItems(sortFunc, state);
}
void *
_PointerList_::BinarySearch(const void *key, GenericCompareFunction compareFunc) const
{
return BSearch(key, Items(), CountItems(), sizeof(void *), compareFunc);
}
void *
_PointerList_::BinarySearch(const void *key,
GenericCompareFunctionWithState compareFunc, void *state) const
{
return BSearchWithState(key, Items(), CountItems(), sizeof(void *), compareFunc, state);
}
int32
_PointerList_::BinarySearchIndex(const void *key, GenericCompareFunction compareFunc) const
{
void *item = BSearch(key, Items(), CountItems(), sizeof(void *), compareFunc);
if (item)
return IndexOf(item);
return -1;
}
int32
_PointerList_::BinarySearchIndex(const void *key,
GenericCompareFunctionWithState compareFunc, void *state) const
{
void *item = BSearchWithState(key, Items(), CountItems(),
sizeof(void *), compareFunc, state);
if (item)
return IndexOf(item);
return -1;
}
int32
_PointerList_::BinarySearchIndexByPredicate(const void *key, UnaryPredicateGlue predicate) const
{
int32 numItems = CountItems();
int32 result = -1;
for (int32 index = 0; index < numItems; index++) {
result = predicate(ItemAtFast(index), (void *)key);
if (result)
break;
}
return result;
}
bool
_PointerList_::ReplaceItem(int32 index, void *newItem)
{
if (index < 0 || index >= CountItems())
return false;
void **items = static_cast<void **>(Items());
items[index] = newItem;
return true;
}
static void *
BSearch(const void *key, const void *start,
size_t numItems, size_t size,
GenericCompareFunction compareFunc)
{
const char *base = (const char *)start;
const void *p;
int low;
int high;
int result;
size_t i;
for (low = -1, high = numItems; high - low > 1;) {
i = (high + low) >> 1;
p = (void *)(base + (i * size));
result = compareFunc(key, *(void **)p);
if (result == 0)
break;
else if (result < 0)
high = i;
else
low = i;
}
if (result == 0)
return *(void **)p;
return NULL;
}
static void *
BSearchWithState(const void *key, const void *start,
size_t numItems, size_t size,
GenericCompareFunctionWithState compareFunc, void *state)
{
const char *base = (const char *)start;
const void *p;
int low;
int high;
int result;
size_t i;
for (low = -1, high = numItems; high - low > 1;) {
i = (high + low) >> 1;
p = (void *)(base + (i * size));
result = compareFunc(key, *(void **)p, state);
if (result == 0)
break;
else if (result < 0)
high = i;
else
low = i;
}
if (result == 0)
return *(void **)p;
return NULL;
}
+1
View File
@@ -8,6 +8,7 @@ SUPPORT_KIT_SOURCE =
Flattenable.cpp
List.cpp
Locker.cpp
PointerList.cpp
StopWatch.cpp
String.cpp
string_helper.cpp