mirror of
https://github.com/s1lentq/ReGameDLL_CS.git
synced 2024-12-27 07:05:38 +03:00
304 lines
7.0 KiB
C++
304 lines
7.0 KiB
C++
/*
|
|
*
|
|
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
|
*
|
|
* This product contains software technology licensed from Id
|
|
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
|
* All Rights Reserved.
|
|
*
|
|
* Use, distribution, and modification of this source code and/or resulting
|
|
* object code is restricted to non-commercial enhancements to products from
|
|
* Valve LLC. All other use, distribution, or modification is prohibited
|
|
* without written permission from Valve LLC.
|
|
*
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
// A growable array class that maintains a free list and keeps elements
|
|
// in the same location
|
|
#include "tier0/platform.h"
|
|
#include "tier0/dbg.h"
|
|
|
|
#include <algorithm>
|
|
|
|
#define FOR_EACH_ARRAY(vecName, iteratorName)\
|
|
for (int iteratorName = 0; (vecName).IsUtlArray && iteratorName < (vecName).Count(); iteratorName++)
|
|
|
|
#define FOR_EACH_ARRAY_BACK(vecName, iteratorName)\
|
|
for (int iteratorName = (vecName).Count() - 1; (vecName).IsUtlArray && iteratorName >= 0; iteratorName--)
|
|
|
|
template <class T, size_t MAX_SIZE>
|
|
class CUtlArray
|
|
{
|
|
public:
|
|
typedef T ElemType_t;
|
|
enum { IsUtlArray = true }; // Used to match this at compiletime
|
|
|
|
CUtlArray();
|
|
CUtlArray(T *pMemory, size_t count);
|
|
~CUtlArray();
|
|
|
|
CUtlArray<T, MAX_SIZE> &operator=(const CUtlArray<T, MAX_SIZE> &other);
|
|
CUtlArray(CUtlArray const &vec);
|
|
|
|
// element access
|
|
T &operator[](int i);
|
|
const T &operator[](int i) const;
|
|
T &Element(int i);
|
|
const T &Element(int i) const;
|
|
T &Random();
|
|
const T &Random() const;
|
|
|
|
T *Base();
|
|
const T *Base() const;
|
|
|
|
// Returns the number of elements in the array, NumAllocated() is included for consistency with UtlVector
|
|
int Count() const;
|
|
int NumAllocated() const;
|
|
|
|
// Is element index valid?
|
|
bool IsValidIndex(int i) const;
|
|
static int InvalidIndex();
|
|
|
|
void CopyArray(const T *pArray, size_t count);
|
|
|
|
void Clear();
|
|
void RemoveAll();
|
|
void Swap(CUtlArray< T, MAX_SIZE> &vec);
|
|
|
|
// Finds an element (element needs operator== defined)
|
|
int Find(const T &src) const;
|
|
void FillWithValue(const T &src);
|
|
|
|
bool HasElement(const T &src) const;
|
|
|
|
// sort using std:: and expecting a "<" function to be defined for the type
|
|
void Sort();
|
|
void Sort(bool (*pfnLessFunc)(const T &src1, const T &src2));
|
|
|
|
#if defined(_WIN32)
|
|
void Sort(int (__cdecl *pfnCompare)(const T *, const T *));
|
|
#else
|
|
void Sort(int (*pfnCompare)(const T *, const T *));
|
|
#endif
|
|
|
|
// sort using std:: with a predicate. e.g. [] -> bool (const T &a, const T &b) const { return a < b; }
|
|
template <class F>
|
|
void SortPredicate(F &&predicate);
|
|
|
|
protected:
|
|
T m_Memory[MAX_SIZE];
|
|
};
|
|
|
|
// Constructor
|
|
template <typename T, size_t MAX_SIZE>
|
|
inline CUtlArray<T, MAX_SIZE>::CUtlArray()
|
|
{
|
|
}
|
|
|
|
template <typename T, size_t MAX_SIZE>
|
|
inline CUtlArray<T, MAX_SIZE>::CUtlArray(T *pMemory, size_t count)
|
|
{
|
|
CopyArray(pMemory, count);
|
|
}
|
|
|
|
// Destructor
|
|
template <typename T, size_t MAX_SIZE>
|
|
inline CUtlArray<T, MAX_SIZE>::~CUtlArray()
|
|
{
|
|
}
|
|
|
|
template <typename T, size_t MAX_SIZE>
|
|
inline CUtlArray<T, MAX_SIZE> &CUtlArray<T, MAX_SIZE>::operator=(const CUtlArray<T, MAX_SIZE> &other)
|
|
{
|
|
if (this != &other)
|
|
{
|
|
for (size_t n = 0; n < MAX_SIZE; n++)
|
|
m_Memory[n] = other.m_Memory[n];
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
template <typename T, size_t MAX_SIZE>
|
|
inline CUtlArray<T, MAX_SIZE>::CUtlArray(CUtlArray const &vec)
|
|
{
|
|
for (size_t n = 0; n < MAX_SIZE; n++)
|
|
m_Memory[n] = vec.m_Memory[n];
|
|
}
|
|
|
|
template <typename T, size_t MAX_SIZE>
|
|
inline T *CUtlArray<T, MAX_SIZE>::Base()
|
|
{
|
|
return &m_Memory[0];
|
|
}
|
|
|
|
template <typename T, size_t MAX_SIZE>
|
|
inline const T *CUtlArray<T, MAX_SIZE>::Base() const
|
|
{
|
|
return &m_Memory[0];
|
|
}
|
|
|
|
// Element access
|
|
template <typename T, size_t MAX_SIZE>
|
|
inline T &CUtlArray<T, MAX_SIZE>::operator[](int i)
|
|
{
|
|
DbgAssert(IsValidIndex(i));
|
|
return m_Memory[i];
|
|
}
|
|
|
|
template <typename T, size_t MAX_SIZE>
|
|
inline const T &CUtlArray<T, MAX_SIZE>::operator[](int i) const
|
|
{
|
|
DbgAssert(IsValidIndex(i));
|
|
return m_Memory[i];
|
|
}
|
|
|
|
template <typename T, size_t MAX_SIZE>
|
|
inline T &CUtlArray<T, MAX_SIZE>::Element(int i)
|
|
{
|
|
DbgAssert(IsValidIndex(i));
|
|
return m_Memory[i];
|
|
}
|
|
|
|
template <typename T, size_t MAX_SIZE>
|
|
inline const T &CUtlArray<T, MAX_SIZE>::Element(int i) const
|
|
{
|
|
DbgAssert(IsValidIndex(i));
|
|
return m_Memory[i];
|
|
}
|
|
|
|
// Count
|
|
template <typename T, size_t MAX_SIZE>
|
|
inline int CUtlArray<T, MAX_SIZE>::Count() const
|
|
{
|
|
return (int)MAX_SIZE;
|
|
}
|
|
|
|
template <typename T, size_t MAX_SIZE>
|
|
inline int CUtlArray<T, MAX_SIZE>::NumAllocated() const
|
|
{
|
|
return (int)MAX_SIZE;
|
|
}
|
|
|
|
// Is element index valid?
|
|
template <typename T, size_t MAX_SIZE>
|
|
inline bool CUtlArray<T, MAX_SIZE>::IsValidIndex(int i) const
|
|
{
|
|
return (i >= 0) && (i < MAX_SIZE);
|
|
}
|
|
|
|
// Returns in invalid index
|
|
template <typename T, size_t MAX_SIZE>
|
|
inline int CUtlArray<T, MAX_SIZE>::InvalidIndex()
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
// Sort methods
|
|
template <typename T, size_t MAX_SIZE>
|
|
void CUtlArray<T, MAX_SIZE>::Sort()
|
|
{
|
|
std::sort(Base(), Base() + Count());
|
|
}
|
|
|
|
template <typename T, size_t MAX_SIZE>
|
|
void CUtlArray<T, MAX_SIZE>::Sort(bool (*pfnLessFunc)(const T &src1, const T &src2))
|
|
{
|
|
std::sort(Base(), Base() + Count(),
|
|
[pfnLessFunc](const T &a, const T &b) -> bool
|
|
{
|
|
if (&a == &b)
|
|
return false;
|
|
|
|
return (*pfnLessFunc)(a, b);
|
|
});
|
|
}
|
|
|
|
#if defined(_WIN32)
|
|
|
|
template <typename T, size_t MAX_SIZE>
|
|
void CUtlArray<T, MAX_SIZE>::Sort(int (__cdecl *pfnCompare)(const T *, const T *))
|
|
{
|
|
typedef int (__cdecl *QSortCompareFunc_t)(const void *, const void *);
|
|
if (Count() <= 1)
|
|
return;
|
|
|
|
qsort(Base(), Count(), sizeof(T), (QSortCompareFunc_t)(pfnCompare));
|
|
}
|
|
|
|
#else // #if defined(_LINUX)
|
|
|
|
template <typename T, size_t MAX_SIZE>
|
|
void CUtlArray<T, MAX_SIZE>::Sort(int (*pfnCompare)(const T *, const T *))
|
|
{
|
|
typedef int (*QSortCompareFunc_t)(const void *, const void *);
|
|
if (Count() <= 1)
|
|
return;
|
|
|
|
qsort(Base(), Count(), sizeof(T), (QSortCompareFunc_t)(pfnCompare));
|
|
}
|
|
#endif // #if defined(_LINUX)
|
|
|
|
template <typename T, size_t MAX_SIZE>
|
|
template <class F>
|
|
void CUtlArray<T, MAX_SIZE>::SortPredicate(F &&predicate)
|
|
{
|
|
std::sort(Base(), Base() + Count(), predicate);
|
|
}
|
|
|
|
template <typename T, size_t MAX_SIZE>
|
|
void CUtlArray<T, MAX_SIZE>::CopyArray(const T *pArray, size_t count)
|
|
{
|
|
DbgAssert(count < MAX_SIZE);
|
|
|
|
for (size_t n = 0; n < count; n++)
|
|
m_Memory[n] = pArray[n];
|
|
}
|
|
|
|
template <typename T, size_t MAX_SIZE>
|
|
void CUtlArray<T, MAX_SIZE>::Clear()
|
|
{
|
|
Q_memset(m_Memory, 0, MAX_SIZE * sizeof(T));
|
|
}
|
|
|
|
template <typename T, size_t MAX_SIZE>
|
|
void CUtlArray<T, MAX_SIZE>::RemoveAll()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
template <typename T, size_t MAX_SIZE>
|
|
void CUtlArray<T, MAX_SIZE>::Swap(CUtlArray< T, MAX_SIZE> &vec)
|
|
{
|
|
for (size_t n = 0; n < MAX_SIZE; n++)
|
|
SWAP(m_Memory[n], vec.m_Memory[n]);
|
|
}
|
|
|
|
// Finds an element (element needs operator== defined)
|
|
template <typename T, size_t MAX_SIZE>
|
|
int CUtlArray<T, MAX_SIZE>::Find(const T &src) const
|
|
{
|
|
for (int i = 0; i < Count(); i++)
|
|
{
|
|
if (Element(i) == src)
|
|
return i;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
template <typename T, size_t MAX_SIZE>
|
|
void CUtlArray<T, MAX_SIZE>::FillWithValue(const T &src)
|
|
{
|
|
for (int i = 0; i < Count(); i++)
|
|
Element(i) = src;
|
|
}
|
|
|
|
template <typename T, size_t MAX_SIZE>
|
|
bool CUtlArray<T, MAX_SIZE>::HasElement(const T &src) const
|
|
{
|
|
return (Find(src) >= 0);
|
|
}
|