Merge branch 'Archiver'

This commit is contained in:
IlushaShurupov 2023-07-30 08:32:21 +03:00
commit ba95747ef9
25 changed files with 685 additions and 125 deletions

15
CMakeSettings.json Normal file
View file

@ -0,0 +1,15 @@
{
"configurations": [
{
"name": "x64-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"inheritEnvironments": [ "msvc_x64_x64" ],
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": ""
}
]
}

View file

@ -93,7 +93,7 @@ CommandLine::Arg::~Arg() {
} }
} }
CommandLine::CommandLine(const init_list<Arg>& args) { CommandLine::CommandLine(const InitialierList<Arg>& args) {
bool optional_start = false; bool optional_start = false;
for (auto& arg : args) { for (auto& arg : args) {

View file

@ -67,7 +67,7 @@ namespace tp {
operator bool() { return mDescr != nullptr; } operator bool() { return mDescr != nullptr; }
} mError; } mError;
CommandLine(const init_list<Arg>& args); CommandLine(const InitialierList<Arg>& args);
~CommandLine(); ~CommandLine();
void resetError() { mError.mDescr = nullptr; } void resetError() { mError.mDescr = nullptr; }

View file

@ -20,7 +20,7 @@ namespace tp {
template<typename tType, ualni tSize> template<typename tType, ualni tSize>
class ConstSizeBuffer { class ConstSizeBuffer {
typedef SelCopyArg<tType> Arg; typedef SelectValueOrReference<tType> Arg;
private: private:
tType mBuff[tSize]; tType mBuff[tSize];
@ -29,6 +29,12 @@ namespace tp {
public: public:
ConstSizeBuffer() = default; ConstSizeBuffer() = default;
~ConstSizeBuffer() {
for (auto i = 0; i < mLoad; i++) {
mBuff[i].~tType();
}
}
public: public:
[[nodiscard]] ualni size() const { return mLoad; } [[nodiscard]] ualni size() const { return mLoad; }
[[nodiscard]] ualni getBuffSize() const { return tSize; } [[nodiscard]] ualni getBuffSize() const { return tSize; }
@ -75,13 +81,18 @@ namespace tp {
mLoad--; mLoad--;
} }
ConstSizeBuffer& operator=(const tp::init_list<tType>& init) { ConstSizeBuffer& operator=(const tp::InitialierList<tType>& init) {
for (auto arg : init) { for (auto arg : init) {
append(arg); append(arg);
} }
return *this; return *this;
} }
void clear() {
this->~ConstSizeBuffer();
new (this) ConstSizeBuffer();
}
public: public:
class IteratorPointer { class IteratorPointer {
@ -125,6 +136,24 @@ namespace tp {
[[nodiscard]] Iterator end() const { [[nodiscard]] Iterator end() const {
return Iterator(mBuff + mLoad); return Iterator(mBuff + mLoad);
} }
public:
template<class tArchiver>
void archiveWrite(tArchiver& ar) const {
ar << mLoad;
for (auto item : *this) {
ar << item.data();
}
}
template<class tArchiver>
void archiveRead(tArchiver& ar) {
clear();
ar >> mLoad;
for (auto i = 0; i < mLoad; i++) {
ar >> mBuff[i];
}
}
}; };
template< template<
@ -135,7 +164,7 @@ namespace tp {
ualni tMinSize = 4 ualni tMinSize = 4
> >
class Buffer { class Buffer {
typedef SelCopyArg<tType> Arg; typedef SelectValueOrReference<tType> Arg;
private: private:
tType* mBuff; tType* mBuff;
@ -157,10 +186,14 @@ namespace tp {
for (ualni i = 0; i < mLoad; i++) new (&mBuff[i]) tType(in.mBuff[i]); for (ualni i = 0; i < mLoad; i++) new (&mBuff[i]) tType(in.mBuff[i]);
} }
void clear() {
this->~Buffer();
new (this) Buffer();
}
Buffer& operator=(const Buffer& in) { Buffer& operator=(const Buffer& in) {
if (this == &in) return *this; if (this == &in) return *this;
this->~Buffer(); clear();
new (this) Buffer(in);
return *this; return *this;
} }
@ -219,7 +252,7 @@ namespace tp {
} }
public: public:
Buffer& operator=(const tp::init_list<tType>& init) { Buffer& operator=(const tp::InitialierList<tType>& init) {
// TODO : optimize // TODO : optimize
for (auto arg : init) { for (auto arg : init) {
append(arg); append(arg);
@ -307,6 +340,29 @@ namespace tp {
return Iterator(mBuff + mLoad); return Iterator(mBuff + mLoad);
} }
public:
template<class tArchiver>
void archiveWrite(tArchiver& ar) const {
ar << mLoad;
for (auto item : *this) {
ar << item.data();
}
}
template<class tArchiver>
void archiveRead(tArchiver& ar) {
clear();
decltype(mLoad) len;
ar >> len;
for (auto i = len; i; i--) {
// TODO : optimize
if (mLoad == mSize) resizeBuffer(tResizePolicy(mSize));
ar >> mBuff[mLoad];
mLoad++;
}
}
private: private:
void resizeBuffer(ualni newSize) { void resizeBuffer(ualni newSize) {
DEBUG_ASSERT(newSize >= mLoad) DEBUG_ASSERT(newSize >= mLoad)
@ -318,4 +374,36 @@ namespace tp {
mSize = newSize; mSize = newSize;
} }
}; };
template<typename tType>
void generatePermutations(const Buffer<Buffer<tType>>& in, Buffer<Buffer<tType>>& out) {
typedef long long Idx;
// sanity check
for (const auto & vec : in) {
if (!vec.size()) return;
}
out.resize(in.size());
auto len = Idx(1);
for (const auto & vec : in) len *= (Idx) vec.size();
for (auto i = 0; i < in.size(); i++) out[i].resize(len);
auto dub = Idx(1);
for (auto power = (Idx) in.size() - 1; power >= 0; power--) {
auto& vec = in[power];
long long i = 0;
while (i < len) {
for (auto val : vec) {
for (auto j = 0; j < dub; j++) {
out[power][i] = val;
i++;
}
}
}
dub *= (Idx) vec.size();
}
}
} }

View file

@ -15,7 +15,7 @@ namespace tp {
public: public:
typedef ualni Index; typedef ualni Index;
typedef Pair<Index, Index> Index2D; typedef Pair<Index, Index> Index2D;
typedef SelCopyArg<tType> tTypeArg; typedef SelectValueOrReference<tType> tTypeArg;
private: private:
tAllocator mAlloc; tAllocator mAlloc;
@ -40,6 +40,7 @@ namespace tp {
~Buffer2D() { ~Buffer2D() {
deleteBuffer(); deleteBuffer();
mSize = { 0, 0 };
} }
explicit Buffer2D(Index2D aSize) { explicit Buffer2D(Index2D aSize) {
@ -55,17 +56,17 @@ namespace tp {
} }
inline tType& get(const Index2D& at) { inline tType& get(const Index2D& at) {
DEBUG_ASSERT(at.x < mSize.x && at.y < mSize.y && at.x >= 0 && at.y >= 0) DEBUG_ASSERT(mBuff && at.x < mSize.x && at.y < mSize.y && at.x >= 0 && at.y >= 0)
return *(mBuff + mSize.x * at.y + at.x); return *(mBuff + mSize.x * at.y + at.x);
} }
inline const tType& get(const Index2D& at) const { inline const tType& get(const Index2D& at) const {
DEBUG_ASSERT(at.x < mSize.x && at.y < mSize.y && at.x >= 0 && at.y >= 0) DEBUG_ASSERT(mBuff && at.x < mSize.x && at.y < mSize.y && at.x >= 0 && at.y >= 0)
return *(mBuff + mSize.x * at.y + at.x); return *(mBuff + mSize.x * at.y + at.x);
} }
inline void set(const Index2D& at, tTypeArg value) { inline void set(const Index2D& at, tTypeArg value) {
DEBUG_ASSERT(at.x < mSize.x && at.y < mSize.y && at.x >= 0 && at.y >= 0) DEBUG_ASSERT(mBuff && at.x < mSize.x && at.y < mSize.y && at.x >= 0 && at.y >= 0)
*(mBuff + mSize.x * at.y + at.x) = value; *(mBuff + mSize.x * at.y + at.x) = value;
} }
@ -77,10 +78,35 @@ namespace tp {
} }
void assign(tType value) { void assign(tType value) {
DEBUG_ASSERT(mBuff);
Index len = mSize.x * mSize.y; Index len = mSize.x * mSize.y;
for (Index i = 0; i < len; i++) { for (Index i = 0; i < len; i++) {
mBuff[i] = value; mBuff[i] = value;
} }
} }
public:
template<class tArchiver>
void archiveWrite(tArchiver& ar) const {
ar << mSize;
for (auto i = 0; i < mSize.x; i++) {
for (auto j = 0; j < mSize.y; j++) {
ar << get(i, j);
}
}
}
template<class tArchiver>
void archiveRead(tArchiver& ar) {
decltype(mSize) size;
deleteBuffer();
ar >> size;
reserve(size);
for (auto i = 0; i < mSize.x; i++) {
for (auto j = 0; j < mSize.y; j++) {
ar >> get(i, j);
}
}
}
}; };
} }

View file

@ -10,7 +10,7 @@ namespace tp {
template <typename Type, class Allocator = DefaultAllocator> template <typename Type, class Allocator = DefaultAllocator>
class List { class List {
typedef SelCopyArg<Type> TypeArg; typedef SelectValueOrReference<Type> TypeArg;
typedef ualni Index; typedef ualni Index;
public: public:
@ -73,7 +73,7 @@ namespace tp {
List() = default; List() = default;
List(const init_list<Type>& list) { operator=(list); } List(const InitialierList<Type>& list) { operator=(list); }
[[nodiscard]] inline Node* first() const { return mFirst; } [[nodiscard]] inline Node* first() const { return mFirst; }
[[nodiscard]] inline Node* last() const { return mLast; } [[nodiscard]] inline Node* last() const { return mLast; }
@ -221,7 +221,7 @@ namespace tp {
return *this; return *this;
} }
List& operator+=(const init_list<Type>& list) { List& operator+=(const InitialierList<Type>& list) {
for (auto item : list) { for (auto item : list) {
pushBack(item); pushBack(item);
} }
@ -235,7 +235,7 @@ namespace tp {
return *this; return *this;
} }
List& operator=(const init_list<Type>& list) { List& operator=(const InitialierList<Type>& list) {
removeAll(); removeAll();
*this += list; *this += list;
return *this; return *this;
@ -295,22 +295,23 @@ namespace tp {
} }
} }
template<class Saver> public:
void write(Saver& file) const { template<class tArchiver>
file.write(mLength); void archiveWrite(tArchiver& ar) const {
ar << mLength;
for (auto item : *this) { for (auto item : *this) {
file.write(item.data()); ar << item.data();
} }
} }
template<class Loader> template<class tArchiver>
void read(Loader& file) { void archiveRead(tArchiver& ar) {
removeAll(); removeAll();
ualni len; decltype(mLength) len;
file.read(len); ar >> len;
for (auto i = len; i; i--) { for (auto i = len; i; i--) {
auto node = newNodeNotConstructed(); auto node = newNodeNotConstructed();
file.read(node->data); ar >> node->data;
pushBack(node); pushBack(node);
} }
} }

View file

@ -7,11 +7,11 @@
namespace tp { namespace tp {
template<typename Key> template<typename Key>
ualni DefaultHashFunc(SelCopyArg<Key> key) { ualni DefaultHashFunc(SelectValueOrReference<Key> key) {
return hash(key); return hash(key);
} }
template<typename tKey, typename tVal, class tAllocator = DefaultAllocator, ualni(*tHashFunc)(SelCopyArg<tKey>) = DefaultHashFunc<tKey>, int tTableInitialSize = 4> template<typename tKey, typename tVal, class tAllocator = DefaultAllocator, ualni(*tHashFunc)(SelectValueOrReference<tKey>) = DefaultHashFunc<tKey>, int tTableInitialSize = 4>
class Map { class Map {
enum { enum {
@ -20,8 +20,8 @@ namespace tp {
MAP_MAX_LOAD_PERCENTAGE = 66, MAP_MAX_LOAD_PERCENTAGE = 66,
}; };
typedef SelCopyArg<tKey> KeyArg; typedef SelectValueOrReference<tKey> KeyArg;
typedef SelCopyArg<tVal> ValArg; typedef SelectValueOrReference<tVal> ValArg;
public: public:
@ -35,7 +35,8 @@ namespace tp {
struct Idx { struct Idx {
alni idx = -1; alni idx = -1;
operator bool() { return idx != -1; } [[nodiscard]] bool isValid() const { return bool(*this); }
explicit operator bool() const { return idx != -1; }
}; };
private: private:
@ -365,24 +366,24 @@ namespace tp {
return mNSlots; return mNSlots;
} }
template<class Saver> template<class Archiver>
void write(Saver& file) { void archiveWrite(Archiver& ar) const {
file.write(mNEntries); ar << mNEntries;
for (auto item : *this) { for (auto item : *this) {
file.write(item->val); ar << item->val;
file.write(item->key); ar << item->key;
} }
} }
template<class Loader> template<class Archiver>
void read(Loader& file) { void archiveRead(Archiver& ar) {
removeAll(); removeAll();
ualni len; decltype(mNSlots) len;
file.read(len); ar >> len;
for (auto i = len; i; i--) { for (auto i = len; i; i--) {
auto node = newNodeNotConstructed(); auto node = newNodeNotConstructed();
file.read(node->val); ar >> node->val;
file.read(node->key); ar >> node->key;
put(node); put(node);
} }
} }

View file

@ -25,8 +25,8 @@ namespace tp {
template <typename Key, typename Data, class Allocator = DefaultAllocator> template <typename Key, typename Data, class Allocator = DefaultAllocator>
class AvlTree { class AvlTree {
typedef SelCopyArg<Key> KeyArg; typedef SelectValueOrReference<Key> KeyArg;
typedef SelCopyArg<Data> DataArg; typedef SelectValueOrReference<Data> DataArg;
public: public:
class Node { class Node {
@ -369,5 +369,32 @@ namespace tp {
} }
bool isValid() { return findInvalidNode(head()) == nullptr; } bool isValid() { return findInvalidNode(head()) == nullptr; }
template<typename tFunctor>
void traverse(Node* node, bool after, tFunctor functor) {
if (!after) functor(node);
if (node->mLeft) traverse(node->mLeft, after, functor);
if (node->mRight) traverse(node->mRight, after, functor);
if (after) functor(node);
}
void removeAll() {
traverse(mRoot, true, [this](Node* node) {
deleteNode(node);
});
mRoot = nullptr;
mSize = 0;
}
public:
template<class tArchiver>
void archiveWrite(tArchiver& file) const {
FAIL("not implemented")
}
template<class tArchiver>
void archiveRead(tArchiver&) {
FAIL("not implemented")
}
}; };
} }

View file

@ -2,6 +2,7 @@
#include "Tests.hpp" #include "Tests.hpp"
#include "Testing.hpp" #include "Testing.hpp"
#include "Archiver.hpp"
using namespace tp; using namespace tp;
@ -53,18 +54,19 @@ TEST_DEF_STATIC(Copy) {
list2.removeAll(); list2.removeAll();
} }
TEST_DEF_STATIC(SaveLoad) { TEST_DEF_STATIC(Serialization) {
tp::List<TestClass, HeapAlloc> list = { TestClass(1), TestClass(2), TestClass(3), TestClass(4) }; tp::List<TestClass, HeapAlloc> list = { TestClass(1), TestClass(2), TestClass(3), TestClass(4) };
TestFile file; ArchiverExample<1024, false> write;
ArchiverExample<1024, true> read;
list.write(file); write % list;
list.removeAll(); list.removeAll();
file.setAddress(0); memCopy(read.mBuff, write.mBuff, sizeof(write.mBuff));
list.read(file); read % list;
ualni i = 0; ualni i = 0;
for (auto iter : list) { for (auto iter : list) {
@ -79,5 +81,5 @@ TEST_DEF_STATIC(SaveLoad) {
TEST_DEF(List) { TEST_DEF(List) {
testSimplePointer(); testSimplePointer();
testSimpleReference(); testSimpleReference();
testSaveLoad(); testSerialization();
} }

View file

@ -3,6 +3,7 @@
#include "Tests.hpp" #include "Tests.hpp"
#include "Testing.hpp" #include "Testing.hpp"
#include "Map.hpp" #include "Map.hpp"
#include "Archiver.hpp"
using namespace tp; using namespace tp;
@ -100,17 +101,18 @@ TEST_DEF_STATIC(SaveLoad) {
map.put(i, TestClass(i)); map.put(i, TestClass(i));
} }
TestFile file; ArchiverExample<1024, false> write;
ArchiverExample<1024, true> read;
map.write(file); write % map;
map.removeAll(); map.removeAll();
TEST(map.size() == 0); TEST(map.size() == 0);
file.setAddress(0); memCopy(read.mBuff, write.mBuff, sizeof(write.mBuff));
map.read(file); read % map;
TEST(map.size() == 10); TEST(map.size() == 10);

View file

@ -28,37 +28,6 @@ public:
void setVal(tp::ualni val) { val1 = val; } void setVal(tp::ualni val) { val1 = val; }
}; };
class TestFile {
tp::ualni mem[1024] = { 0 };
tp::ualni address = 0;
public:
TestFile() = default;
template<typename Type>
void write(const Type& val) {
val.write(*this);
}
template<>
void write<tp::ualni>(const tp::ualni& val) {
mem[address] = val;
address++;
}
void setAddress(tp::ualni addr) { address = addr; }
template<typename Type>
void read(Type& val) {
val.read(*this);
}
template<>
void read<tp::ualni>(tp::ualni& val) {
val = mem[address];
address++;
}
};
void testList(); void testList();
void testMap(); void testMap();

View file

@ -67,7 +67,7 @@ Vec3F Camera::project(Vec2F normalized) {
halnf w = halnf((mTarget - mPos).length()); halnf w = halnf((mTarget - mPos).length());
Vec4<halnf> world_pos4(normalized.x * w, normalized.y * w, z, w); Vec4<halnf> world_pos4(normalized.x * w, normalized.y * w, z, w);
return inv * world_pos4; return Vec3F(inv * world_pos4);
} }
Vec2F Camera::project(const Vec3F& world) { Vec2F Camera::project(const Vec3F& world) {

View file

@ -6,7 +6,7 @@ namespace tp {
template <typename Type, const ualni tSize> template <typename Type, const ualni tSize>
class Vec { class Vec {
typedef SelCopyArg<Type> TypeArg; typedef SelectValueOrReference<Type> TypeArg;
private: private:
Type mBuff[tSize]; Type mBuff[tSize];
@ -21,7 +21,7 @@ namespace tp {
MODULE_SANITY_CHECK(gModuleMath) MODULE_SANITY_CHECK(gModuleMath)
} }
Vec(TypeArg val) { explicit Vec(TypeArg val) {
assign(val); assign(val);
} }
@ -185,7 +185,7 @@ namespace tp {
return dot(in); return dot(in);
} }
alnf length2() const { [[nodiscard]] alnf length2() const {
alnf sum = 0; alnf sum = 0;
for (ualni i = 0; i < tSize; i++) { for (ualni i = 0; i < tSize; i++) {
Type val = get(i); Type val = get(i);
@ -194,7 +194,7 @@ namespace tp {
return sum; return sum;
} }
alnf length() const { [[nodiscard]] alnf length() const {
return sqrt(length2()); return sqrt(length2());
} }
@ -250,18 +250,18 @@ namespace tp {
} }
template <typename TypeIn> template <typename TypeIn>
Vec(TypeIn Vec[2]) { explicit Vec(TypeIn Vec[2]) {
x = (Type) Vec[0]; x = (Type) Vec[0];
y = (Type) Vec[1]; y = (Type) Vec[1];
} }
template <typename TypeIn> template <typename TypeIn>
Vec(TypeIn val) { explicit Vec(TypeIn val) {
x = y = (Type) val; x = y = (Type) val;
} }
template <typename TypeIn> template <typename TypeIn>
Vec(Vec<TypeIn, 2>& Vec) { explicit Vec(Vec<TypeIn, 2>& Vec) {
x = (Type) Vec.x; x = (Type) Vec.x;
y = (Type) Vec.y; y = (Type) Vec.y;
} }
@ -381,11 +381,11 @@ namespace tp {
return { -y, x }; return { -y, x };
} }
alnf length2() const { [[nodiscard]] alnf length2() const {
return (x * x + y * y); return (x * x + y * y);
} }
alnf length() const { [[nodiscard]] alnf length() const {
Type const tmp = (Type) (x * x + y * y); Type const tmp = (Type) (x * x + y * y);
return sqrt(tmp); return sqrt(tmp);
} }
@ -419,9 +419,9 @@ namespace tp {
Type z; Type z;
// Initialization // Initialization
Vec() {} Vec() = default;
Vec(const Vec<Type, 4>& in) { explicit Vec(const Vec<Type, 4>& in) {
x = in[0]; x = in[0];
y = in[1]; y = in[1];
z = in[2]; z = in[2];
@ -433,13 +433,13 @@ namespace tp {
z = aZ; z = aZ;
} }
Vec(Type Vec[3]) { explicit Vec(Type Vec[3]) {
x = Vec[0]; x = Vec[0];
y = Vec[1]; y = Vec[1];
z = Vec[2]; z = Vec[2];
} }
Vec(Type x) { explicit Vec(Type x) {
assign(x); assign(x);
} }
@ -584,7 +584,7 @@ namespace tp {
return (x * in.x + y * in.y + z * in.z); return (x * in.x + y * in.y + z * in.z);
} }
alnf length() const { [[nodiscard]] alnf length() const {
return sqrt((halnf) (x * x + y * y + z * z)); return sqrt((halnf) (x * x + y * y + z * z));
} }
@ -632,11 +632,11 @@ namespace tp {
z = (Type) (tmp * sinA + z * cosA); z = (Type) (tmp * sinA + z * cosA);
} }
halnf angelX() const { [[nodiscard]] halnf angelX() const {
return (halnf) atan2(y, z); return (halnf) atan2(y, z);
} }
halnf angelY() const { [[nodiscard]] halnf angelY() const {
return (halnf) atan2(x, z); return (halnf) atan2(x, z);
} }
}; };

BIN
Modules/.vs/slnx.sqlite Normal file

Binary file not shown.

View file

@ -12,7 +12,8 @@ target_include_directories(${PROJECT_NAME} PUBLIC ./public/)
### -------------------------- Tests -------------------------- ### ### -------------------------- Tests -------------------------- ###
enable_testing() enable_testing()
add_executable(${PROJECT_NAME}Tests ${CMAKE_CURRENT_SOURCE_DIR}/tests/Tests.cpp) file(GLOB SOURCES_TEST "./tests/*.cpp")
add_executable(${PROJECT_NAME}Tests ${SOURCES_TEST})
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME}) target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME})
add_test(NAME ${PROJECT_NAME}Tests COMMAND ${PROJECT_NAME}Tests) add_test(NAME ${PROJECT_NAME}Tests COMMAND ${PROJECT_NAME}Tests)

146
Modules/public/Archiver.hpp Normal file
View file

@ -0,0 +1,146 @@
#pragma once
#include "Common.hpp"
namespace tp {
// Used to transfer data to or from some sort of archive
// Abstracts interface so that actual archive must only overload readBytes and writeBytes
// The main idea is that it transfers data as bytes only if this type of data does not have special API functions
template <bool tRead>
class ArchiverTemplate {
public:
struct HasFunc {
typedef ArchiverTemplate& ArchRef;
template <typename T, typename = void> struct Write : FalseType {};
template <typename T> struct Write<T, VoidType<decltype(DeclareValue<T>()().archiveWrite(DeclareValue<ArchRef>()()))>> : TrueType {};
template <typename T, typename = void> struct Read : FalseType {};
template <typename T> struct Read<T, VoidType<decltype(DeclareValue<T>()().archiveRead(DeclareValue<ArchRef>()()))>> : TrueType {};
template <typename T, typename = void> struct Archive : FalseType {};
template <typename T> struct Archive<T, VoidType<decltype(DeclareValue<T>()().archive(DeclareValue<ArchRef>()()))>> : TrueType {};
template <typename T>
struct AssertCombinations {
static constexpr auto assert() {
if (HasFunc::template Read<T>::value != HasFunc::template Write<T>::value) return false;
if (HasFunc::template Read<T>::value) {
if (HasFunc::template Read<T>::value == HasFunc::template Archive<T>::value) return false;
}
return true;
}
};
};
public:
virtual void writeBytes(const int1* val, ualni size) = 0;
virtual void readBytes(int1* val, ualni size) = 0;
public:
ArchiverTemplate() = default;
// check if type has explicit write method. if not write as bytes
template<typename Type>
void operator <<(const Type& val) {
static_assert(!tRead);
static_assert(HasFunc::template AssertCombinations<Type>::assert());
if constexpr (HasFunc::template Write<Type>::value) {
val.archiveWrite(*this);
} else {
writeBytes((const int1*) &val, sizeof(val));
}
}
// check if type has explicit read method. if not read as bytes
template<typename Type>
void operator >>(Type& val) {
static_assert(tRead);
static_assert(HasFunc::template AssertCombinations<Type>::assert());
if constexpr (HasFunc::template Read<Type>::value) {
val.archiveRead(*this);
} else {
readBytes((int1*) &val, sizeof(val));
}
}
// check if type has explicit archive method. if not read/write as bytes
template<typename Type>
void operator %(Type& val) {
static_assert(HasFunc::template AssertCombinations<Type>::assert());
if constexpr (HasFunc::template Archive<Type>::value) {
val.archive(*this);
} else {
if constexpr (tRead) {
operator>>(val);
} else {
operator<<(val);
}
}
}
template<typename Type>
void operator %(const Type& val) {
static_assert(HasFunc::template AssertCombinations<Type>::assert());
if constexpr (HasFunc::template Archive<Type>::value) {
((Type&)val).archive(*this);
} else {
if constexpr (tRead) {
operator>>(val);
} else {
operator<<(val);
}
}
}
};
template<ualni tMaxMemory, bool tRead>
class ArchiverExample : public ArchiverTemplate<tRead> {
public:
ArchiverExample() = default;
protected:
void incrementAddresses(ualni size) {
if (mFirstNotWritten == mAddress) mFirstNotWritten += size;
mAddress += size;
}
void writeBytes(const int1* val, ualni size) override {
for (auto i = 0; i < size; i++) mBuff[mAddress + i] = val[i];
incrementAddresses(size);
}
void readBytes(int1* val, ualni size) override {
for (auto i = 0; i < size; i++) val[i] = mBuff[mAddress + i];
incrementAddresses(size);
}
template<typename tType>
static void test() {
const tType val;
tType res;
res.change();
ArchiverExample<tMaxMemory, false> write;
ArchiverExample<tMaxMemory, true> read;
write % val;
for (auto i = 0; i < tMaxMemory; i++) read.mBuff[i] = write.mBuff[i];
read % res;
if (val != res) {
throw "test failed";
}
}
public:
int1 mBuff[tMaxMemory]{};
private:
ualni mAddress = 0;
ualni mFirstNotWritten = 0;
};
}

View file

@ -18,8 +18,6 @@ namespace tp {
#define DEBUG_ASSERT(exp) {} #define DEBUG_ASSERT(exp) {}
#endif #endif
#if defined(ENV_OS_WINDOWS) #if defined(ENV_OS_WINDOWS)
#define DEBUG_BREAK(expr) if (expr) { __debugbreak(); } #define DEBUG_BREAK(expr) if (expr) { __debugbreak(); }
#elif defined(ENV_OS_ANDROID) #elif defined(ENV_OS_ANDROID)

View file

@ -4,15 +4,40 @@
#include "Environment.hpp" #include "Environment.hpp"
#include "TypeInfo.hpp" #include "TypeInfo.hpp"
#include <initializer_list> #include <initializer_list>
#include <typeinfo>
#include <utility>
namespace tp { namespace tp {
template<typename Type> template<typename Type>
using init_list = std::initializer_list<Type>; using InitialierList = std::initializer_list<Type>;
// Selects whether to pass by constant reference or by value // Selects whether to pass by constant reference or by value
template <typename tType> template <typename tType>
using SelCopyArg = typename TypeSelect<(sizeof(tType) > sizeof(tp::alni)), const tType&, tType>::Result; using SelectValueOrReference = typename TypeSelect<(sizeof(tType) > sizeof(tp::alni)), const tType&, tType>::Result;
template <typename tType>
using VoidType = void;
template <typename tType>
struct Reference {
tType& operator()() {}
};
template <typename tType>
struct DeclareValue {
tType operator()() {}
};
struct TrueType {
static constexpr auto value = true;
};
struct FalseType {
static constexpr auto value = false;
};
}
namespace tp {
ualni next2pow(ualni v); ualni next2pow(ualni v);
uhalni next2pow(uhalni v); uhalni next2pow(uhalni v);
ufalni next2pow(ufalni v); ufalni next2pow(ufalni v);

View file

@ -0,0 +1,50 @@
#pragma once
#include "Common.hpp"
namespace tp {
// TODO
template <bool tRecursive>
class SizeCounter {
typedef SizeCounter& ArchRef;
template <typename T, typename = void> struct HasSizeCounter : FalseType {};
template <typename T> struct HasSizeCounter<T, VoidType<decltype(DeclareValue<T>()().count(DeclareValue<ArchRef>()()))>> : TrueType {};
public:
SizeCounter() = default;
template<typename Type>
void count(const Type& val) {
if constexpr (HasSizeCounter<Type>::value) {
val.count(*this);
} else {
if constexpr (tRecursive) {
count(sizeof(val));
} else {
mSize += sizeof(Type);
}
}
}
void countSizeUnused(ualni size) {
mSizeUnused += size;
}
void countSize(ualni size) {
mSize += size;
}
[[nodiscard]] ualni getSizeUnused() const {
return mSizeUnused;
}
[[nodiscard]] ualni getSize() const {
return mSize;
}
private:
ualni mSize = 0;
ualni mSizeUnused = 0;
};
}

View file

@ -0,0 +1,202 @@
#include "Archiver.hpp"
#include <cstdio>
#include <cstdlib>
using namespace tp;
bool sFailed = false;
struct Undef {
char character1 = 'a';
bool boolean = true;
ualni integer = 321;
char character2 = 'a';
void change() {
character1++;
character2--;
integer++;
boolean = !boolean;
}
[[nodiscard]] bool operator!=(const Undef& in) const {
if (character1 != in.character1) return true;
if (character2 != in.character2) return true;
if (integer != in.integer) return true;
if (boolean != in.boolean) return true;
return false;
}
};
struct SimpleArchive {
char character = 'a';
ualni integer = 123;
bool boolean = true;
Undef undef;
template<typename tArchiver>
void archive(tArchiver& ar) {
ar % character;
ar % integer;
ar % boolean;
ar % undef;
}
void change() {
character++;
integer++;
boolean = !boolean;
undef.change();
}
[[nodiscard]] bool operator!=(const SimpleArchive& in) const {
if (character != in.character) return true;
if (integer != in.integer) return true;
if (boolean != in.boolean) return true;
if (undef != in.undef) return true;
return false;
}
};
struct Simple {
char character = 'a';
ualni integer = 123;
bool boolean = true;
Undef undef;
template<typename tArchiver>
void archiveRead(tArchiver& ar) {
ar >> character;
ar >> integer;
ar >> boolean;
ar >> undef;
}
template<typename tArchiver>
void archiveWrite(tArchiver& ar) const {
ar << character;
ar << integer;
ar << boolean;
ar << undef;
}
void change() {
character++;
integer++;
boolean = !boolean;
undef.change();
}
[[nodiscard]] bool operator!=(const Simple& in) const {
if (character != in.character) return true;
if (integer != in.integer) return true;
if (boolean != in.boolean) return true;
if (undef != in.undef) return true;
return false;
}
};
template<typename tType>
struct Set {
tType buff[10];
ualni len = 5;
template<typename tArchiver>
void archiveRead(tArchiver& ar) {
ar >> len;
for (auto i = 0; i < len; i++) {
ar >> buff[i];
}
}
template<typename tArchiver>
void archiveWrite(tArchiver& ar) const {
ar << len;
for (auto i = 0; i < len; i++) {
ar << buff[i];
}
}
void change() {
len = 2;
for (auto i = 0; i < len; i++) {
buff[i].change();
}
}
[[nodiscard]] bool operator!=(const Set& in) const {
for (auto i = 0; i < len; i++) {
if (buff[i] != in.buff[i]) return true;
}
if (len != in.len) return true;
return false;
}
};
template<typename tType>
struct Complex {
Undef undef;
Set<tType> set;
template<typename tArchiver>
void archive(tArchiver& ar) {
ar % set;
ar % undef;
}
void change() {
undef.change();
set.change();
}
[[nodiscard]] bool operator!=(const Complex& in) const {
return undef != in.undef || set != in.set;
}
};
template<typename tType>
void test() {
constexpr auto size = 1024;
const tType val;
tType res;
res.change();
ArchiverExample<size, false> write;
ArchiverExample<size, true> read;
write % val;
for (auto i = 0; i < size; i++) read.mBuff[i] = write.mBuff[i];
read % res;
if (val != res) {
printf("Test %s Failed\n", typeid(tType).name());
sFailed = true;
}
}
template <typename T, typename A, typename = void> struct HasArchive : FalseType {};
template <typename T, typename A> struct HasArchive<T, A, VoidType<decltype(DeclareValue<T>()().archive(DeclareValue<A&>()()))>> : TrueType {};
void testArchiver() {
printf("has archive method - %i\n", HasArchive<SimpleArchive, ArchiverExample<10, false>>::value);
printf("has archive method - %i\n", ArchiverExample<10, false>::HasFunc::Archive<SimpleArchive>::value);
printf("has archive method - %i\n", ArchiverExample<10, false>::HasFunc::Archive<Simple>::value);
test<SimpleArchive>();
test<Simple>();
test<Set<Simple>>();
test<Complex<Simple>>();
if (sFailed) {
exit(1);
}
}

View file

@ -1,7 +1,7 @@
#include "Module.hpp" #include "Module.hpp"
#include "Common.hpp" void testArchiver();
int main() { int main() {
tp::ModuleManifest* ModuleDependencies[] = { &tp::gModuleBase, nullptr }; tp::ModuleManifest* ModuleDependencies[] = { &tp::gModuleBase, nullptr };
@ -13,10 +13,12 @@ int main() {
ASSERT(tp::gEnvironment.mWidth == tp::Environment::ArchWidth::X64); ASSERT(tp::gEnvironment.mWidth == tp::Environment::ArchWidth::X64);
ASSERT(tp::max(2, 1) == 2); ASSERT(tp::max(2, 1) == 2)
ASSERT(tp::max(-1, 0) == 0); ASSERT(tp::max(-1, 0) == 0)
ASSERT(tp::max(0, -1) == 0); ASSERT(tp::max(0, -1) == 0)
ASSERT(tp::min(0, -1) == -1); ASSERT(tp::min(0, -1) == -1)
testArchiver();
TestModule.deinitialize(); TestModule.deinitialize();
} }

23
TODO
View file

@ -1,7 +1,7 @@
Testing ! Testing !!
Serialization !
Objects: Objects:
Testing
Serialization Serialization
Alloc Size queries Alloc Size queries
Compile !! Compile !!
@ -16,24 +16,29 @@ Objects:
rename classes rename classes
move functions around move functions around
Storage:
Finish networking
Enable preloads
Graphics: Graphics:
Window event system Window event system
Graphics API Graphics API
FPS count & Performance control FPS count & Performance control
Utils:
Stack trace fixes
Containers: Containers:
Test generatePermutations
Add variant size buffer Add variant size buffer
Buffer add resize function
Buffer improvements Buffer improvements
Buff serialization
Tree serialization
Write Traverse Avl test
Add mem leakage tests Add mem leakage tests
Add check copy times Add check copy times
AVL dont copy data just swap AVL dont copy data just swap
Storage:
Finish networking
Enable preloads
Utils:
Stack trace fixes
TextEditor: TextEditor:
Implement Implement

View file

@ -342,7 +342,7 @@ namespace tp::RegEx {
return compileUtil(regex, state); return compileUtil(regex, state);
} }
Node compile(Graph& aGraph, init_list<Pair<const tAlphabetType*, tStateType>> aRules) { Node compile(Graph& aGraph, InitialierList<Pair<const tAlphabetType*, tStateType>> aRules) {
mGraph = &aGraph; mGraph = &aGraph;
auto left = mGraph->addVertex(); auto left = mGraph->addVertex();
@ -513,7 +513,7 @@ namespace tp::RegEx {
} }
template <typename tAlphabetType, typename tStateType, tStateType tNoStateVal, tStateType tFailedStateVal> template <typename tAlphabetType, typename tStateType, tStateType tNoStateVal, tStateType tFailedStateVal>
CompileError<tStateType> compile(NFA<tAlphabetType, tStateType, tNoStateVal, tFailedStateVal>& out, const init_list<Pair<const tAlphabetType*, tStateType>>& rules) { CompileError<tStateType> compile(NFA<tAlphabetType, tStateType, tNoStateVal, tFailedStateVal>& out, const InitialierList<Pair<const tAlphabetType*, tStateType>>& rules) {
Compiler<tAlphabetType, tStateType, tNoStateVal, tFailedStateVal> compiler; Compiler<tAlphabetType, tStateType, tNoStateVal, tFailedStateVal> compiler;
compiler.compile(out, rules); compiler.compile(out, rules);
return compiler.mError; return compiler.mError;

View file

@ -25,7 +25,7 @@ namespace tp {
MODULE_SANITY_CHECK(gModuleTokenizer) MODULE_SANITY_CHECK(gModuleTokenizer)
} }
void build(const init_list<Pair<const tAlphabetType*, tTokType>>& rules) { void build(const InitialierList<Pair<const tAlphabetType*, tTokType>>& rules) {
NFA<tAlphabetType, tTokType, tNoTokVal, tFailedTokVal> nfa; NFA<tAlphabetType, tTokType, tNoTokVal, tFailedTokVal> nfa;
mError = RegEx::compile(nfa, rules); mError = RegEx::compile(nfa, rules);
@ -89,7 +89,7 @@ namespace tp {
SimpleTokenizer() = default; SimpleTokenizer() = default;
void build(const init_list<Pair<const tAlphabetType*, tTokType>>& rules) { void build(const InitialierList<Pair<const tAlphabetType*, tTokType>>& rules) {
mTokenizer.build(rules); mTokenizer.build(rules);
} }

View file

@ -17,7 +17,7 @@ void printSnapshot(const tp::CallStackCapture::CallStack* snapshot) {
} }
void common() { void common() {
gCSCapture->getSnapshot(); auto tmp = gCSCapture->getSnapshot();
} }
void first() { void first() {