1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 19:48:20 +02:00
Beef/IDEHelper/Compiler/BfUtil.h

356 lines
5.6 KiB
C
Raw Normal View History

2019-08-23 11:56:54 -07:00
#pragma once
#include "BeefySysLib/Common.h"
NS_BF_BEGIN
template <typename T>
class AutoPopBack
{
public:
T* mList;
public:
AutoPopBack(T* list)
{
mList = list;
}
~AutoPopBack()
{
if (mList != NULL)
mList->pop_back();
}
void Pop()
{
if (mList != NULL)
mList->pop_back();
mList = NULL;
}
};
template <typename T>
class SetAndRestoreValue
{
public:
T* mVarPtr;
T mPrevVal;
T mNewVal;
public:
SetAndRestoreValue()
{
2022-07-26 13:27:03 -04:00
mVarPtr = NULL;
2019-08-23 11:56:54 -07:00
}
SetAndRestoreValue(T& varRef)
{
mPrevVal = varRef;
mVarPtr = &varRef;
mNewVal = mPrevVal;
}
SetAndRestoreValue(T& varRef, T newVal)
{
mPrevVal = varRef;
2022-07-26 13:27:03 -04:00
mVarPtr = &varRef;
2019-08-23 11:56:54 -07:00
varRef = newVal;
mNewVal = newVal;
}
SetAndRestoreValue(T& varRef, T newVal, bool doSet)
{
2022-07-26 13:27:03 -04:00
mPrevVal = varRef;
2019-08-23 11:56:54 -07:00
mVarPtr = &varRef;
if (doSet)
varRef = newVal;
mNewVal = newVal;
}
void Init(T& varRef, T newVal)
{
mPrevVal = varRef;
mVarPtr = &varRef;
varRef = newVal;
mNewVal = newVal;
}
~SetAndRestoreValue()
{
Restore();
}
void Restore()
{
if (mVarPtr != NULL)
*mVarPtr = mPrevVal;
}
void CancelRestore()
{
mVarPtr = NULL;
}
void Set()
{
*mVarPtr = mNewVal;
}
};
template <typename T>
class OwnedVector : public Array<T*>
{
public:
typedef Array<T*> _Base;
~OwnedVector()
{
for (auto item : *this)
delete item;
}
void Clear()
{
for (auto item : *this)
delete item;
_Base::Clear();
}
void ClearWithoutDeleting()
{
_Base::Clear();
}
T* Alloc()
{
T* item = new T();
_Base::push_back(item);
return item;
}
template <typename T2>
T2* Alloc()
{
T2* item = new T2();
_Base::push_back(item);
return item;
}
};
// Optimized for Get and then immediate GiveBack - no allocation or vector access
template <typename T>
class BfAllocPool
{
public:
Array<T*> mVals;
T* mNext;
bool mOwnsAll;
2022-03-18 18:06:14 -07:00
bool mZeroAlloc;
2019-08-23 11:56:54 -07:00
public:
2022-03-18 18:06:14 -07:00
BfAllocPool(bool ownsAll = false, bool zeroAlloc = false)
2019-08-23 11:56:54 -07:00
{
mOwnsAll = ownsAll;
2022-03-18 18:06:14 -07:00
mZeroAlloc = zeroAlloc;
2019-08-23 11:56:54 -07:00
mNext = NULL;
}
~BfAllocPool()
{
if ((mNext != NULL) && (!mOwnsAll))
delete mNext;
for (auto val : mVals)
{
2022-03-18 18:06:14 -07:00
if (mZeroAlloc)
{
val->~T();
free(val);
}
else
delete val;
2019-08-23 11:56:54 -07:00
}
}
T* Get()
{
T* val = mNext;
if (val == NULL)
{
if ((mVals.size() > 0) && (!mOwnsAll))
{
val = mVals.back();
mVals.pop_back();
return val;
}
2022-07-26 13:27:03 -04:00
2022-03-18 18:06:14 -07:00
if (mZeroAlloc)
{
void* addr = malloc(sizeof(T));
memset(addr, 0, sizeof(T));
val = new(addr) T();
}
2022-07-26 13:27:03 -04:00
else
2022-03-18 18:06:14 -07:00
val = new T();
2019-08-23 11:56:54 -07:00
if (mOwnsAll)
mVals.push_back(val);
return val;
}
mNext = NULL;
return val;
}
void GiveBack(T* val)
{
if (mNext == NULL)
mNext = val;
else if (!mOwnsAll)
mVals.push_back(val);
}
};
inline uint64_t DecodeULEB128(const uint8*& p)
{
uint64_t val = 0;
unsigned shift = 0;
do
{
val += uint64_t(*p & 0x7f) << shift;
shift += 7;
} while ((*p++ & 0x80) != 0);
return val;
}
inline void EncodeSLEB128(uint8*& buf, int value)
{
bool hasMore;
do
{
2022-07-26 13:27:03 -04:00
uint8 curByte = (uint8)(value & 0x7f);
2019-08-23 11:56:54 -07:00
value >>= 7;
hasMore = !((((value == 0) && ((curByte & 0x40) == 0)) ||
((value == -1) && ((curByte & 0x40) != 0))));
if (hasMore)
curByte |= 0x80;
2022-07-26 13:27:03 -04:00
*(buf++) = curByte;
2019-08-23 11:56:54 -07:00
}
2022-07-26 13:27:03 -04:00
while (hasMore);
2019-08-23 11:56:54 -07:00
}
inline void EncodeSLEB128(uint8*& buf, int64_t value)
{
bool hasMore;
do
{
2022-07-26 13:27:03 -04:00
uint8 curByte = (uint8)(value & 0x7f);
2019-08-23 11:56:54 -07:00
value >>= 7;
hasMore = !((((value == 0) && ((curByte & 0x40) == 0)) ||
((value == -1) && ((curByte & 0x40) != 0))));
if (hasMore)
curByte |= 0x80;
2022-07-26 13:27:03 -04:00
*(buf++) = curByte;
2019-08-23 11:56:54 -07:00
}
2022-07-26 13:27:03 -04:00
while (hasMore);
2019-08-23 11:56:54 -07:00
}
#pragma warning(push)
#pragma warning(disable:4146)
/// Utility function to decode a SLEB128 value.
inline int64_t DecodeSLEB128(const uint8*& p)
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
int value = 0;
int shift = 0;
int curByte;
do
{
curByte = (uint8_t)*p++;
value |= ((curByte & 0x7f) << shift);
shift += 7;
} while (curByte >= 128);
// Sign extend negative numbers.
if (((curByte & 0x40) != 0) && (shift < 64))
value |= ~0LL << shift; //-V610
return value;
}
#pragma warning(pop)
void* DecodeLocalDataPtr(const char*& strRef);
String EncodeDataPtr(void* addr, bool doPrefix);
String EncodeDataPtr(uint32 addr, bool doPrefix);
String EncodeDataPtr(uint64 addr, bool doPrefix);
2022-03-08 06:27:06 -08:00
String EncodeDataPtr(int addr, bool doPrefix);
2019-08-23 11:56:54 -07:00
void* ZeroedAlloc(int size);
String EncodeFileName(const StringImpl& fromStr); // Make short, only legal chars, with a hash at end
2019-08-23 11:56:54 -07:00
/*template <typename T>
T* ZeroedAlloc()
{
return new (ZeroedAlloc(sizeof(T))) T();
}*/
2020-07-14 08:27:25 -07:00
bool BfCheckWildcard(const StringImpl& wildcard, const StringImpl& checkStr);
2019-08-23 11:56:54 -07:00
template <typename T>
T* PlaceNew(void* addr)
{
return new(addr) T();
}
template <typename T>
T* ZeroPlaceNew(void* addr)
{
memset(addr, 0, sizeof(T));
return new(addr) T();
}
class CaseInsensitiveString
{
public:
const char* mStr;
CaseInsensitiveString(const char* str)
{
mStr = str;
}
bool operator==(const CaseInsensitiveString& strB) const
{
return _stricmp(mStr, strB.mStr) == 0;
}
};
#define TOKENPASTE(X, Y) X ## Y
#define TOKENPASTE2(X, Y) TOKENPASTE(X, Y)
#define STACK_ZERO_INIT(T, NAME) \
alignas(16) uint8 TOKENPASTE2(_data__, __LINE__)[sizeof(T)]; \
memset(TOKENPASTE2(_data__, __LINE__), 0, sizeof(T)); \
T* NAME = PlaceNew<T>(TOKENPASTE2(_data__, __LINE__));
NS_BF_END
uint64 stouln(const char* str, int len);
namespace std
{
template<>
struct hash<Beefy::CaseInsensitiveString>
{
size_t operator()(const Beefy::CaseInsensitiveString& val) const
{
int curHash = 0;
const char* str = val.mStr;
while (true)
{
char c = *(str++);
if (c == 0)
break;
c = tolower(c);
curHash = ((curHash ^ c) << 5) - curHash;
}
return curHash;
}
};
}