mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-22 12:11:25 +00:00
TArray Binary Search
This commit is contained in:
parent
b2cb4b0a6d
commit
cc51b486e0
1 changed files with 125 additions and 0 deletions
|
@ -355,6 +355,105 @@ public:
|
|||
return i;
|
||||
}
|
||||
|
||||
// !!! THIS REQUIRES AN ELEMENT TYPE THAT'S COMPARABLE WITH THE LT OPERATOR !!!
|
||||
bool IsSorted()
|
||||
{
|
||||
for(unsigned i = 1; i < Count; i++)
|
||||
{
|
||||
if(Array[i] < Array[i-1]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename Func>
|
||||
bool IsSorted(Func lt)
|
||||
{
|
||||
for(unsigned i = 1; i < Count; i++)
|
||||
{
|
||||
if(lt(Array[i], Array[i-1])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// !!! THIS REQUIRES A SORTED OR EMPTY ARRAY !!!
|
||||
// !!! AND AN ELEMENT TYPE THAT'S COMPARABLE WITH THE LT OPERATOR !!!
|
||||
//
|
||||
// exact = false returns the closest match, to be used for, ex., insertions, exact = true returns Size() when no match, like Find does
|
||||
unsigned int SortedFind(const T& item, bool exact = true) const
|
||||
{
|
||||
if(Count == 0) return 0;
|
||||
if(Count == 1) return (item < Array[0]) ? 0 : 1;
|
||||
|
||||
unsigned int lo = 0;
|
||||
unsigned int hi = Count - 1;
|
||||
|
||||
while(lo <= hi)
|
||||
{
|
||||
int mid = lo + ((hi - lo) / 2);
|
||||
|
||||
if(Array[mid] < item)
|
||||
{
|
||||
lo = mid + 1;
|
||||
}
|
||||
else if(item < Array[mid])
|
||||
{
|
||||
hi = mid - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return mid;
|
||||
}
|
||||
}
|
||||
if(exact)
|
||||
{
|
||||
return Count;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (lo == Count || (item < Array[lo])) ? lo : lo + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// !!! THIS REQUIRES A SORTED OR EMPTY ARRAY !!!
|
||||
//
|
||||
// exact = false returns the closest match, to be used for, ex., insertions, exact = true returns Size() when no match, like Find does
|
||||
template<typename Func>
|
||||
unsigned int SortedFind(const T& item, Func lt, bool exact = true) const
|
||||
{
|
||||
if(Count == 0) return 0;
|
||||
if(Count == 1) return lt(item, Array[0]) ? 0 : 1;
|
||||
|
||||
unsigned int lo = 0;
|
||||
unsigned int hi = Count - 1;
|
||||
|
||||
while(lo <= hi)
|
||||
{
|
||||
int mid = lo + ((hi - lo) / 2);
|
||||
|
||||
if(lt(Array[mid], item))
|
||||
{
|
||||
lo = mid + 1;
|
||||
}
|
||||
else if(lt(item, Array[mid]))
|
||||
{
|
||||
if(mid == 0) break; // prevent negative overflow due to unsigned numbers
|
||||
hi = mid - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return mid;
|
||||
}
|
||||
}
|
||||
if(exact)
|
||||
{
|
||||
return Count;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (lo == Count || lt(item, Array[lo])) ? lo : lo + 1;
|
||||
}
|
||||
}
|
||||
|
||||
bool Contains(const T& item) const
|
||||
{
|
||||
unsigned int i;
|
||||
|
@ -462,6 +561,21 @@ public:
|
|||
return f;
|
||||
}
|
||||
|
||||
unsigned SortedAddUnique(const T& obj)
|
||||
{
|
||||
auto f = SortedFind(obj, true);
|
||||
if (f == Size()) Push(obj);
|
||||
return f;
|
||||
}
|
||||
|
||||
template<typename Func>
|
||||
unsigned SortedAddUnique(const T& obj, Func lt)
|
||||
{
|
||||
auto f = SortedFind(obj, lt, true);
|
||||
if (f == Size()) Push(obj);
|
||||
return f;
|
||||
}
|
||||
|
||||
bool Pop ()
|
||||
{
|
||||
if (Count > 0)
|
||||
|
@ -542,6 +656,17 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void SortedInsert (const T &item)
|
||||
{
|
||||
Insert (SortedFind (item, false), item);
|
||||
}
|
||||
|
||||
template<typename Func>
|
||||
void SortedInsert (const T &item, Func lt)
|
||||
{
|
||||
Insert (SortedFind (item, lt, false), item);
|
||||
}
|
||||
|
||||
void ShrinkToFit ()
|
||||
{
|
||||
if (Most > Count)
|
||||
|
|
Loading…
Reference in a new issue