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:
@@ -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;
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ SUPPORT_KIT_SOURCE =
|
|||||||
Flattenable.cpp
|
Flattenable.cpp
|
||||||
List.cpp
|
List.cpp
|
||||||
Locker.cpp
|
Locker.cpp
|
||||||
|
PointerList.cpp
|
||||||
StopWatch.cpp
|
StopWatch.cpp
|
||||||
String.cpp
|
String.cpp
|
||||||
string_helper.cpp
|
string_helper.cpp
|
||||||
|
|||||||
Reference in New Issue
Block a user