Adding Strings tests

This commit is contained in:
IlushaShurupov 2023-07-17 22:32:30 +03:00
parent 91b00817e3
commit 6bca7431b7
7 changed files with 357 additions and 121 deletions

View file

@ -1,8 +1,10 @@
#pragma once
#include "Allocators.hpp"
#include "Utils.hpp"
#include "Buffer.hpp"
#include "Utils.hpp"
#include <cstdio>
#include <cstdlib>
namespace tp {
@ -18,51 +20,52 @@ namespace tp {
static inline bool isEndChar(tChar in) { return in == '\0'; }
static constexpr tChar getEndChar() { return '\0'; }
static ualni calcLength(const tChar* in) {
static Index calcLength(const tChar* in) {
const tChar* iter = in;
while (*iter != '\0') iter++;
return iter - in;
}
static tChar* insertLogic(const tChar* cur, const tChar* tar, ualni at, ualni len) {
ualni curLen = calcLength(cur);
ualni allLen = curLen + len;
static tChar* insertLogic(const tChar* cur, const tChar* tar, Index at, Index len) {
auto curLen = calcLength(cur);
auto allLen = curLen + len;
auto* out = new tChar[allLen + 1];
DEBUG_ASSERT(curLen >= 0)
DEBUG_ASSERT(len >= 0)
DEBUG_ASSERT(at < curLen + 1 && at >= 0)
for (ualni idx = 0; idx < at; idx++) {
for (Index idx = 0; idx < at; idx++) {
out[idx] = cur[idx];
}
for (ualni idx = 0; idx < len; idx++) {
for (Index idx = 0; idx < len; idx++) {
out[idx + at] = tar[idx];
}
for (ualni idx = at + len; idx < allLen; idx++) {
for (Index idx = at + len; idx < allLen; idx++) {
out[idx] = cur[idx - len];
}
out[allLen] = '\0';
return out;
}
static tChar* removeLogic(const tChar* cur, ualni start, ualni end) {
ualni curLen = calcLength(cur);
ualni rangeLen = end - start;
ualni newLen = curLen - rangeLen;
// including end not including start
static tChar* removeLogic(const tChar* cur, Index start, Index end) {
auto curLen = calcLength(cur);
auto rangeLen = end - start;
auto newLen = curLen - rangeLen;
auto* out = new tChar[newLen + 1];
out[newLen] = '\0';
for (ualni idx = 0; idx < start; idx++) {
for (Index idx = 0; idx < start; idx++) {
out[idx] = cur[idx];
}
for (ualni idx = end; idx < curLen; idx++) {
for (Index idx = end; idx < curLen; idx++) {
out[idx - rangeLen] = cur[idx];
}
return out;
}
static bool isEqualLogic(const tChar* left, const tChar* right) {
ualni idx = 0;
Index idx = 0;
LOOP:
if (left[idx] == '\0' || right[idx] == '\0') {
if (left[idx] == '\0' && right[idx] == '\0') {
@ -77,88 +80,6 @@ namespace tp {
goto LOOP;
}
static ualni fromValueLength(alni val, ualni base) {
ualni iter = val;
ualni len = 0;
while (iter /= base) {
len++;
}
bool neg = val < 0;
len += 1 + ualni(neg);
return len;
}
static tChar* stringFromValue(alni val, tChar* ownBuff, ualni base) {
tChar* out;
bool neg = val < 0;
ualni len = fromValueLength(val, base);
out = ownBuff ? ownBuff : new tChar[len + 1];
out[len] = '\0';
val = abs(val);
for (ualni i = len - 1; i >= int(neg); i--) {
out[i] = (tChar) (val % base + 48);
val /= (alni) base;
}
if (neg) {
out[0] = '-';
}
return out;
}
static ualni fromValueLength(alnf val, ualni base) {
auto rounded = (alni) val;
ualni mantissa = ( (alni) val - rounded) * 100000;
alni rounded_len = 0;
alni mantissa_len = 0;
while (rounded /= (alni) base) {
rounded_len++;
}
if (!rounded_len) {
rounded_len++;
}
while (mantissa /= base) {
mantissa_len++;
}
bool neg = val < 0;
bool dot = mantissa_len & 1;
alni tot_len = mantissa_len + rounded_len + dot + neg;
return tot_len;
}
static tChar* fromValue(alnf, ualni, tChar*) {
DEBUG_BREAK(false)
return nullptr;
}
static tChar* fromValue(bool val, tChar* ownBuff) {
alni len = val ? 4 : 5;
tChar* out = ownBuff ? ownBuff : new tChar[len + 1];
out[len] = '\0';
memCopy(out, val ? "True" : "False", len);
return out;
}
static tChar* stringFromValue(int val, ualni base) {
return fromValue((alni) val, nullptr, base);
}
static tChar* fromValue(tChar val) {
auto* out = new tChar[2];
out[1] = '\0';
out[0] = val;
return out;
}
static bool toValue(const tChar*, alni&, ualni) {
ASSERT(false)
return false;
}
static bool toValue(const tChar*, alnf&, ualni) {
ASSERT(false)
return false;
}
static bool toValue(const tChar* in, bool& val) {
if (!calcLength(in)) return false;
if (isEqual(in, "False") || isEqual(in, "false") || isEqual(in, "0")) {
@ -169,8 +90,9 @@ namespace tp {
return true;
}
// returns 0 : nl1 + 1 : nl2 + 1 : nl3 + 1 : ... : size
static void calcLineOffsets(const tChar* aBuff, Index aLength, Buffer<Index>& aOut) {
halni lines = 0;
Index lines = 0;
for (auto idx : Range(aLength)) {
if (isNewLineChar(aBuff[idx])) {
lines++;
@ -187,5 +109,42 @@ namespace tp {
aOut[0] = 0;
aOut[lines + 1] = aLength;
}
[[nodiscard]] static bool convertStringToValue(const tChar* input, alni& output) {
char* endPtr;
output = std::strtoll(input, &endPtr, 10);
return (endPtr == input + calcLength(input));
}
[[nodiscard]] static bool convertStringToValue(const tChar* input, alnf& output) {
char* endPtr;
output = std::strtod(input, &endPtr);
return (endPtr == input + calcLength(input));
}
[[nodiscard]] static bool convertStringToValue(const tChar* input, bool& output) {
output = !(isEqualLogic(input, "False") || isEqualLogic(input, "false") || isEqualLogic(input, "0"));
return true;
}
[[nodiscard]] static bool convertValueToString(alni input, tChar* output, Index bufferSize) {
int result = std::snprintf(output, bufferSize, "%lld", input);
return result >= 0;
}
[[nodiscard]] static bool convertValueToString(alnf input, tChar* output, Index bufferSize) {
int result = std::snprintf(output, bufferSize, "%f", input);
return result >= 0;
}
[[nodiscard]] static bool convertValueToString(bool input, tChar* output, Index bufferSize) {
const char* str = (input ? "true" : "false");
Index length = calcLength(str);
if (length >= bufferSize)
return false;
memCopy(output, str, length + 1);
return true;
}
};
}

View file

@ -24,7 +24,7 @@ namespace tp {
StringData() {
mBuff = (tChar*) "*";
mReferenceCount = 0;
mReferenceCount = 1;
mIsConst = true;
mEditedIdx = 0;
}
@ -73,7 +73,7 @@ namespace tp {
typedef typename Logic::Index Index;
enum { STRINGS_POOL_SIZE = 1024, };
static PoolAlloc<StringData<tChar>, STRINGS_POOL_SIZE>* sStringPool;
static PoolAlloc<StringData<tChar>, STRINGS_POOL_SIZE> sStringPool;
static Data sNullString;
private:
@ -94,14 +94,14 @@ namespace tp {
// Creates new string data from raw data pointer.
// Does not own string buffer - string buffer will not be freed. Initializes as const memory.
explicit StringTemplate(const tChar* raw) {
mData = new (sStringPool->allocate(0)) StringData(raw, true);
StringTemplate(const tChar* raw) {
mData = new (sStringPool.allocate(0)) StringData(raw, true);
incReference(mData);
}
// Copies raw data and claims ownership over it
explicit StringTemplate(tChar* raw) {
mData = new (sStringPool->allocate(0)) StringData(raw);
StringTemplate(tChar* raw) {
mData = new (sStringPool.allocate(0)) StringData(raw);
incReference(mData);
}
@ -117,8 +117,8 @@ namespace tp {
void decReference(Data* dp) {
dp->mReferenceCount--;
if (!dp->mReferenceCount) {
sStringPool->deallocate(mData);
mData->~StringData();
sStringPool.deallocate(mData);
}
}
@ -146,7 +146,7 @@ namespace tp {
// We have no rights to modify if someone references that memory too
// So we need to create new copy of StringData
if (mData->mReferenceCount > 1) {
mData = new (sStringPool->allocate(0)) StringData(mData->mBuff);
mData = new (sStringPool.allocate(0)) StringData(mData->mBuff);
incReference(mData);
return;
}
@ -154,7 +154,7 @@ namespace tp {
// Also if initial raw data was marked as const - create copy of raw data
// Note - raw data will be lost at this point if no other record of such is stored
if (mData->mIsConst) {
mData = new (sStringPool->allocate(0)) StringData(mData->mBuff);
mData = new (sStringPool.allocate(0)) StringData(mData->mBuff);
incReference(mData);
}
}
@ -176,14 +176,18 @@ namespace tp {
StringTemplate& operator=(const StringTemplate& in) {
if (&in == this) return *this;
~StringTemplate();
this->~StringTemplate();
new (this) StringTemplate(in);
return *this;
}
public: // Debugging
[[nodiscard]] ualni getReferenceCount() const { return mData->mReferenceCount; }
[[nodiscard]] bool getIsConstFlag() const { return mData->mIsConst; }
};
template<typename tChar>
PoolAlloc<StringData<tChar>, StringTemplate<tChar>::STRINGS_POOL_SIZE>* StringTemplate<tChar>::sStringPool;
PoolAlloc<StringData<tChar>, StringTemplate<tChar>::STRINGS_POOL_SIZE> StringTemplate<tChar>::sStringPool;
template<typename tChar>
StringData<tChar> StringTemplate<tChar>::sNullString;