#pragma once #include "BeefySysLib/Common.h" NS_BF_BEGIN template 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 class SetAndRestoreValue { public: T* mVarPtr; T mPrevVal; T mNewVal; public: SetAndRestoreValue() { mVarPtr = NULL; } SetAndRestoreValue(T& varRef) { mPrevVal = varRef; mVarPtr = &varRef; mNewVal = mPrevVal; } SetAndRestoreValue(T& varRef, T newVal) { mPrevVal = varRef; mVarPtr = &varRef; varRef = newVal; mNewVal = newVal; } SetAndRestoreValue(T& varRef, T newVal, bool doSet) { mPrevVal = varRef; 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 class OwnedVector : public Array { public: typedef Array _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 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 class BfAllocPool { public: Array mVals; T* mNext; bool mOwnsAll; public: BfAllocPool(bool ownsAll = false) { mOwnsAll = ownsAll; mNext = NULL; } ~BfAllocPool() { if ((mNext != NULL) && (!mOwnsAll)) delete mNext; for (auto val : mVals) { val->~T(); free(val); } } T* Get() { T* val = mNext; if (val == NULL) { if ((mVals.size() > 0) && (!mOwnsAll)) { val = mVals.back(); mVals.pop_back(); return val; } //val = new T(); void* addr = malloc(sizeof(T)); memset(addr, 0, sizeof(T)); val = new(addr) T(); 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 { uint8 curByte = (uint8)(value & 0x7f); value >>= 7; hasMore = !((((value == 0) && ((curByte & 0x40) == 0)) || ((value == -1) && ((curByte & 0x40) != 0)))); if (hasMore) curByte |= 0x80; *(buf++) = curByte; } while (hasMore); } inline void EncodeSLEB128(uint8*& buf, int64_t value) { bool hasMore; do { uint8 curByte = (uint8)(value & 0x7f); value >>= 7; hasMore = !((((value == 0) && ((curByte & 0x40) == 0)) || ((value == -1) && ((curByte & 0x40) != 0)))); if (hasMore) curByte |= 0x80; *(buf++) = curByte; } while (hasMore); } #pragma warning(push) #pragma warning(disable:4146) /// Utility function to decode a SLEB128 value. inline int64_t DecodeSLEB128(const uint8*& p) { 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); void* ZeroedAlloc(int size); /*template T* ZeroedAlloc() { return new (ZeroedAlloc(sizeof(T))) T(); }*/ template T* PlaceNew(void* addr) { return new(addr) T(); } template 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(TOKENPASTE2(_data__, __LINE__)); NS_BF_END uint64 stouln(const char* str, int len); namespace std { template<> struct hash { 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; } }; }