Containers New Features
This commit is contained in:
parent
ec2a71ccdb
commit
72a25600a2
10 changed files with 1192 additions and 0 deletions
77
Containers/outdated/public/AddBuff.h
Normal file
77
Containers/outdated/public/AddBuff.h
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
namespace tp {
|
||||||
|
extern ModuleManifest gModuleContainer;
|
||||||
|
|
||||||
|
template <typename Type, halni Step, halni Start=0, typename Index = halni, typename tAllocator>
|
||||||
|
class AddBuffer {
|
||||||
|
|
||||||
|
tAllocator mAlloc;
|
||||||
|
Type* mBuff = NULL;
|
||||||
|
Index mLoadIdx = 0;
|
||||||
|
Index mLength = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
AddBuffer() {
|
||||||
|
MODULE_SANITY_CHECK(gModuleContainer);
|
||||||
|
mLength = Step + Start;
|
||||||
|
mBuff = new(mAlloc) [mLength];
|
||||||
|
}
|
||||||
|
|
||||||
|
void extend(Index aInputLen) {
|
||||||
|
auto old = mBuff;
|
||||||
|
auto old_len = mLength;
|
||||||
|
|
||||||
|
mLength += (aInputLen / Step) + Step;
|
||||||
|
mBuff = new(mAlloc) [mLength];
|
||||||
|
|
||||||
|
for (auto i = 0; i < old_len; i++) {
|
||||||
|
mBuff[i] = old[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] (mAlloc, old);
|
||||||
|
}
|
||||||
|
|
||||||
|
void append(const Type* input, Index input_len) {
|
||||||
|
if (mLoadIdx >= mLength) {
|
||||||
|
extend(input_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto i = 0; i < input_len; i++) {
|
||||||
|
mBuff[mLoadIdx + i] = input[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
mLoadIdx += input_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type& operator[] (Index idx) {
|
||||||
|
assert(idx >= 0 && idx <= mLoadIdx && "out of range");
|
||||||
|
return mBuff[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
const Type* buff() const {
|
||||||
|
return mBuff;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Type& operator[] (Index idx) const {
|
||||||
|
assert(idx >= 0 && idx <= mLoadIdx && "out of range");
|
||||||
|
return mBuff[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
Index len() {
|
||||||
|
return mLoadIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
Index lenReserved() {
|
||||||
|
return mLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
~AddBuffer() {
|
||||||
|
delete[] (mAlloc, mBuff);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
257
Containers/outdated/public/Array.h
Normal file
257
Containers/outdated/public/Array.h
Normal file
|
|
@ -0,0 +1,257 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Cassert.hpp"
|
||||||
|
#include "Sort.h"
|
||||||
|
#include "Filesystem.hpp"
|
||||||
|
|
||||||
|
namespace tp {
|
||||||
|
extern ModuleManifest gModuleContainer;
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
class ArrayIterator;
|
||||||
|
|
||||||
|
template <typename Type, typename tAllocator>
|
||||||
|
class Array {
|
||||||
|
|
||||||
|
void allocate(alni p_bufflen) {
|
||||||
|
mLength = p_bufflen;
|
||||||
|
mBuff = new(mAlloc.Allocate(mLength * sizeof(Type))) Type[mLength]();
|
||||||
|
}
|
||||||
|
|
||||||
|
void free() {
|
||||||
|
if (mBuff) {
|
||||||
|
mLength = 0;
|
||||||
|
delete[] (mAlloc, mBuff);
|
||||||
|
mBuff = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tAllocator mAlloc;
|
||||||
|
Type* mBuff;
|
||||||
|
alni mLength;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Array() {
|
||||||
|
MODULE_SANITY_CHECK(gModuleContainer);
|
||||||
|
mLength = 0;
|
||||||
|
mBuff = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array(tp::init_list<Type> list) {
|
||||||
|
mLength = 0;
|
||||||
|
mBuff = nullptr;
|
||||||
|
this->operator=(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
Array(alni p_length) {
|
||||||
|
mLength = p_length;
|
||||||
|
mBuff = nullptr;
|
||||||
|
reserve(mLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
alni length() const {
|
||||||
|
return mLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type* buff() const {
|
||||||
|
return mBuff;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reserve(alni p_bufflen) {
|
||||||
|
free();
|
||||||
|
allocate(alni p_bufflen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert(Type& p_block, alni idx) {
|
||||||
|
Type* current = mBuff;
|
||||||
|
allocate(mLength + 1);
|
||||||
|
|
||||||
|
for (alni befor = 0; befor < idx; befor++) {
|
||||||
|
mBuff[befor] = current[befor];
|
||||||
|
}
|
||||||
|
for (alni after = idx; after < mLength - 1; after++) {
|
||||||
|
mBuff[after + 1] = current[after];
|
||||||
|
}
|
||||||
|
|
||||||
|
mBuff[idx] = p_block;
|
||||||
|
|
||||||
|
if (current) {
|
||||||
|
delete[] (mAlloc, current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove(alni p_idx) {
|
||||||
|
Type* current = mBuff;
|
||||||
|
allocate(mLength - 1);
|
||||||
|
|
||||||
|
for (alni befor = 0; befor < p_idx; befor++) {
|
||||||
|
mBuff[befor] = current[befor];
|
||||||
|
}
|
||||||
|
for (alni after = p_idx + 1; after < mLength + 1; after++) {
|
||||||
|
mBuff[after - 1] = current[after];
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] (mAlloc, current);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeVal(Type val) {
|
||||||
|
for (int i = 0; i < mLength; i++) {
|
||||||
|
if (mBuff[i] == val) {
|
||||||
|
remove(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Type& last() {
|
||||||
|
return mBuff[mLength - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
void extend(tp::ualni new_len) {
|
||||||
|
if ((tp::ualni)mLength >= new_len) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mBuff) {
|
||||||
|
reserve(new_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto old_buff = mBuff;
|
||||||
|
auto old_len = (tp::ualni) mLength;
|
||||||
|
|
||||||
|
mBuff = new Type[new_len]();
|
||||||
|
mLength = new_len;
|
||||||
|
|
||||||
|
for (tp::ualni idx = 0; idx < old_len; idx++) {
|
||||||
|
mBuff[idx] = old_buff[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] (mAlloc, old_buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator=(const Array& array) {
|
||||||
|
reserve(array.mLength);
|
||||||
|
for (int i = 0; i < array.mLength; i++) {
|
||||||
|
mBuff[i] = array.mBuff[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator+=(const Array& array) {
|
||||||
|
if (!mBuff) {
|
||||||
|
return operator=(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
alni new_len = array.mLength + mLength;
|
||||||
|
Type* newbuff = new Type[new_len]();
|
||||||
|
|
||||||
|
for (halni i = 0; i < mLength; i++) {
|
||||||
|
newbuff[i] = mBuff[i];
|
||||||
|
}
|
||||||
|
for (halni i = 0; i < array.mLength; i++) {
|
||||||
|
newbuff[mLength + i] = array.mBuff[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] (mAlloc, mBuff);
|
||||||
|
mBuff = newbuff;
|
||||||
|
mLength = new_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator=(tp::init_list<Type> list) {
|
||||||
|
reserve(list.size());
|
||||||
|
uhalni idx = 0;
|
||||||
|
for (Type item : list) {
|
||||||
|
mBuff[idx] = item;
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Type& operator[](alni idx) {
|
||||||
|
assert(idx >= 0 && idx < mLength);
|
||||||
|
return mBuff[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const Type& operator[](alni idx) const {
|
||||||
|
assert(idx >= 0 && idx < mLength);
|
||||||
|
return mBuff[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
void pushBack(Type block) {
|
||||||
|
insert(block, mLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
Array(const Array& array) {
|
||||||
|
allocate(array.mLength);
|
||||||
|
for (int i = 0; i < array.mLength; i++) {
|
||||||
|
mBuff[i] = array.mBuff[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayIterator<Type> begin() { return ArrayIterator<Type>(this); }
|
||||||
|
alni end() { return mLength; }
|
||||||
|
|
||||||
|
alni saveSize() {
|
||||||
|
return mLength * sizeof(Type) + sizeof(mLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
void save(File& file) {
|
||||||
|
file.write(&mLength);
|
||||||
|
file.write_bytes((int1*) mBuff, mLength * sizeof(Type));
|
||||||
|
}
|
||||||
|
|
||||||
|
void load(File& file) {
|
||||||
|
file.read(&mLength);
|
||||||
|
reserve(mLength);
|
||||||
|
file.read_bytes((int1*) mBuff, mLength * sizeof(Type));
|
||||||
|
}
|
||||||
|
|
||||||
|
~Array() {
|
||||||
|
free();
|
||||||
|
}
|
||||||
|
|
||||||
|
alni sizeAllocatedMem() {
|
||||||
|
alni out = 0;
|
||||||
|
out += sizeof(alni);
|
||||||
|
out += sizeof(Type*);
|
||||||
|
if (mBuff) {
|
||||||
|
out += sizeof(Type) * mLength;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename SortPolicy = SortMerge>
|
||||||
|
void sort(bool (*grater)(Type const& item1, Type const& item2)) {
|
||||||
|
SortPolicy sorter;
|
||||||
|
sorter.sort(mBuff, (int) mLength, grater);
|
||||||
|
}
|
||||||
|
|
||||||
|
alni sizeUsedMem() {
|
||||||
|
return sizeAllocatedMem();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
class ArrayIterator {
|
||||||
|
alni mIdx = 0;
|
||||||
|
Array<Type>* mArrayPtr;
|
||||||
|
public:
|
||||||
|
|
||||||
|
ArrayIterator(Array<Type>* array) : mArrayPtr(array) {}
|
||||||
|
|
||||||
|
Type& data() const { return (*mArrayPtr)[mIdx]; }
|
||||||
|
ualni idx() const { return mIdx; }
|
||||||
|
operator alni() { return mIdx; }
|
||||||
|
|
||||||
|
Type* operator->() { return &(*mArrayPtr)[mIdx]; }
|
||||||
|
const ArrayIterator& operator*() { return *this; }
|
||||||
|
|
||||||
|
inline void operator++() { mIdx++; }
|
||||||
|
bool operator==(alni p_idx) { return mIdx == p_idx; }
|
||||||
|
bool operator!=(alni p_idx) { return mIdx != p_idx; }
|
||||||
|
bool operator>(alni p_idx) { return mIdx > p_idx; }
|
||||||
|
bool operator<(alni p_idx) { return mIdx < p_idx; }
|
||||||
|
bool operator>=(alni p_idx) { return mIdx >= p_idx; }
|
||||||
|
bool operator<=(alni p_idx) { return mIdx <= p_idx; }
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
123
Containers/outdated/public/Array2D.h
Normal file
123
Containers/outdated/public/Array2D.h
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "allocators.h"
|
||||||
|
#include "vec.h"
|
||||||
|
#include "rect.h"
|
||||||
|
|
||||||
|
namespace tp {
|
||||||
|
extern ModuleManifest gModuleContainer;
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
class Array2D {
|
||||||
|
|
||||||
|
vec2<uhalni> mSize;
|
||||||
|
Type* mBuff = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Array2D() {
|
||||||
|
MODULE_SANITY_CHECK(gModuleContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
Array2D(vec2<uhalni> size) { reserve(size); }
|
||||||
|
|
||||||
|
vec2<uhalni> size() const { return mSize; }
|
||||||
|
Type* buff() const { return mBuff; }
|
||||||
|
|
||||||
|
inline Type& get(uhalni x, uhalni y) {
|
||||||
|
assert(x < mSize.x && y < mSize.y && x >= 0 && y >= 0);
|
||||||
|
return *(mBuff + mSize.x * y + x);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void set(uhalni x, uhalni y, Type value) {
|
||||||
|
assert(x < mSize.x && y < mSize.y && x >= 0 && y >= 0);
|
||||||
|
*(mBuff + mSize.x * y + x) = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reserve(vec2<uhalni> newsize) {
|
||||||
|
if (mSize.x != newsize.x || mSize.y != newsize.y) {
|
||||||
|
if (mBuff)
|
||||||
|
delete mBuff;
|
||||||
|
mBuff = new Type[newsize.x * newsize.y];
|
||||||
|
mSize = newsize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void project(Array2D<Type>* in, vec2<uhalni> pos) {
|
||||||
|
|
||||||
|
recti unclamped_fromrect(pos, in->mBuff);
|
||||||
|
recti fromrect;
|
||||||
|
recti torect(vec2<uhalni>(), mBuff);
|
||||||
|
|
||||||
|
torect.intersection(unclamped_fromrect, fromrect);
|
||||||
|
|
||||||
|
vec2<uhalni> clampsize(unclamped_fromrect.size - fromrect.size);
|
||||||
|
|
||||||
|
vec2<bool> mns(unclamped_fromrect.pos.x < 0, unclamped_fromrect.pos.y < 0);
|
||||||
|
|
||||||
|
if (mns.x && mns.y) {
|
||||||
|
for (int i = 0; i < fromrect.size.x; i++) {
|
||||||
|
for (int j = 0; j < fromrect.size.y; j++) {
|
||||||
|
int to = mSize.x * (fromrect.pos.y + j) + (fromrect.pos.x + i);
|
||||||
|
mBuff[to] = in->mBuff[in->mSize.x * (j + clampsize.y) + (i + clampsize.x)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!mns.x && !mns.y) {
|
||||||
|
for (int i = 0; i < fromrect.size.x; i++) {
|
||||||
|
for (int j = 0; j < fromrect.size.y; j++) {
|
||||||
|
int to = mSize.x * (fromrect.pos.y + j) + (fromrect.pos.x + i);
|
||||||
|
mBuff[to] = in->mBuff[in->mSize.x * j + i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!mns.x && mns.y) {
|
||||||
|
for (int i = 0; i < fromrect.size.x; i++) {
|
||||||
|
for (int j = 0; j < fromrect.size.y; j++) {
|
||||||
|
int to = mSize.x * (fromrect.pos.y + j) + (fromrect.pos.x + i);
|
||||||
|
mBuff[to] = in->mBuff[in->mSize.x * (j + clampsize.y) + i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < fromrect.size.x; i++) {
|
||||||
|
for (int j = 0; j < fromrect.size.y; j++) {
|
||||||
|
int to = mSize.x * (fromrect.pos.y + j) + (fromrect.pos.x + i);
|
||||||
|
mBuff[to] = in->mBuff[in->mSize.x * j + (i + clampsize.x)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void assign(Type value) {
|
||||||
|
uhalni len = mSize.x * mSize.y;
|
||||||
|
for (uhalni i = 0; i < len; i++) {
|
||||||
|
mBuff[i] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
alni sizeAllocatedMem() {
|
||||||
|
alni out = 0;
|
||||||
|
out += mSize.sizeAllocatedMem();
|
||||||
|
out += sizeof(Type*);
|
||||||
|
if (mBuff) {
|
||||||
|
out += sizeof(Type) * mSize.x * mSize.y;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
alni sizeUsedMem() {
|
||||||
|
alni out = 0;
|
||||||
|
out += mSize.sizeAllocatedMem();
|
||||||
|
out += sizeof(Type*);
|
||||||
|
if (mBuff) {
|
||||||
|
out += sizeof(Type) * mSize.x * mSize.y;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
~Array2D() {
|
||||||
|
delete mBuff;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
115
Containers/outdated/public/PersistentList.h
Normal file
115
Containers/outdated/public/PersistentList.h
Normal file
|
|
@ -0,0 +1,115 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "List.h"
|
||||||
|
|
||||||
|
namespace tp {
|
||||||
|
|
||||||
|
// TODO : insert and remove by range
|
||||||
|
// IN DEVELOPMENT
|
||||||
|
template <typename Type>
|
||||||
|
class PersistentList {
|
||||||
|
|
||||||
|
public:
|
||||||
|
struct UndoNode {
|
||||||
|
ListNode<Type>* mNode = NULL;
|
||||||
|
enum { NONE, ADD, REMOVE, UNDO_MARK } mType = NONE;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
List<Type> mList;
|
||||||
|
List<UndoNode> mHystory;
|
||||||
|
ListNode<UndoNode>* mCurrentState = NULL;
|
||||||
|
|
||||||
|
void clearFuture() {
|
||||||
|
auto iter = mHystory.last();
|
||||||
|
while (iter && iter != mCurrentState) {
|
||||||
|
auto del = iter;
|
||||||
|
iter = iter->prev;
|
||||||
|
mHystory.detach(del);
|
||||||
|
mHystory.deleteNode(del);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
PersistentList() {
|
||||||
|
pushUndoPoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
void pushUndoPoint() {
|
||||||
|
mHystory.pushBack(UndoNode{ 0, UndoNode::UNDO_MARK });
|
||||||
|
mCurrentState = mHystory.last();
|
||||||
|
}
|
||||||
|
|
||||||
|
const List<Type>& list() const {
|
||||||
|
return mList;
|
||||||
|
}
|
||||||
|
|
||||||
|
const List<UndoNode>& hystory() const {
|
||||||
|
return mHystory;
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns new node inserted after aNode
|
||||||
|
ListNode<Type>* insertAfter(ListNode<Type>* aNode) {
|
||||||
|
|
||||||
|
clearFuture();
|
||||||
|
|
||||||
|
auto node = mList.newNode();
|
||||||
|
mList.attach(node, aNode);
|
||||||
|
mHystory.pushBack(UndoNode{ node, UndoNode::ADD });
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove(ListNode<Type>* aNode) {
|
||||||
|
|
||||||
|
clearFuture();
|
||||||
|
|
||||||
|
mHystory.pushBack(UndoNode{ aNode, UndoNode::REMOVE });
|
||||||
|
mList.detach(aNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void undo() {
|
||||||
|
if (!mCurrentState->prev) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (mCurrentState->data.mType != UndoNode::UNDO_MARK) {
|
||||||
|
if (mCurrentState->data.mType != UndoNode::ADD) {
|
||||||
|
mList.detach(mCurrentState->data.mNode);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mList.attach(mCurrentState->data.mNode, mCurrentState->data.mNode->prev);
|
||||||
|
}
|
||||||
|
mCurrentState = mCurrentState->prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void redo() {
|
||||||
|
if (!mCurrentState->next) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (mCurrentState->data.mType != UndoNode::UNDO_MARK) {
|
||||||
|
if (mCurrentState->data.mType != UndoNode::ADD) {
|
||||||
|
mList.attach(mCurrentState->data.mNode, mCurrentState->data.mNode->prev);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mList.detach(mCurrentState->data.mNode);
|
||||||
|
}
|
||||||
|
mCurrentState = mCurrentState->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearHystory() {
|
||||||
|
// TODO : mem leaks
|
||||||
|
//for (auto node : mHystory) {
|
||||||
|
//delete node->data();
|
||||||
|
//}
|
||||||
|
//mHystory.free();
|
||||||
|
}
|
||||||
|
|
||||||
|
~PersistentList() {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
112
Containers/outdated/public/Queue.h
Normal file
112
Containers/outdated/public/Queue.h
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "allocators.h"
|
||||||
|
|
||||||
|
namespace tp {
|
||||||
|
extern ModuleManifest gModuleContainer;
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
class Queue {
|
||||||
|
public:
|
||||||
|
|
||||||
|
template <typename NodeType>
|
||||||
|
class Node {
|
||||||
|
public:
|
||||||
|
Node<NodeType>* below;
|
||||||
|
NodeType data;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Node(NodeType data, Node<NodeType>* below) {
|
||||||
|
this->below = below;
|
||||||
|
this->data = data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename IterType>
|
||||||
|
struct Iterator {
|
||||||
|
Node<IterType>* mIter;
|
||||||
|
IterType& operator->() { return mIter->data; }
|
||||||
|
IterType& data() { return mIter->data; }
|
||||||
|
const Iterator& operator*() { return *this; }
|
||||||
|
inline void operator++() { mIter = mIter->below; }
|
||||||
|
bool operator==(const Iterator& end) { return mIter == NULL; }
|
||||||
|
bool operator!=(const Iterator& end) { return mIter != NULL; }
|
||||||
|
};
|
||||||
|
|
||||||
|
alni length;
|
||||||
|
Node<Type>* top;
|
||||||
|
Node<Type>* bottom;
|
||||||
|
|
||||||
|
Queue() {
|
||||||
|
MODULE_SANITY_CHECK(gModuleContainer);
|
||||||
|
length = 0;
|
||||||
|
top = nullptr;
|
||||||
|
bottom = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
~Queue() {
|
||||||
|
free();
|
||||||
|
}
|
||||||
|
|
||||||
|
// pushes the node on the bottom of the stack
|
||||||
|
void push(Type data) {
|
||||||
|
Node<Type>* new_node = new Node<Type>(data, NULL);
|
||||||
|
|
||||||
|
if (bottom) {
|
||||||
|
bottom->below = new_node;
|
||||||
|
} else {
|
||||||
|
top = new_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
bottom = new_node;
|
||||||
|
|
||||||
|
length++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// pops the top node of the stack
|
||||||
|
void pop() {
|
||||||
|
assert(top);
|
||||||
|
Node<Type>* del = top;
|
||||||
|
top = top->below;
|
||||||
|
delete del;
|
||||||
|
length--;
|
||||||
|
|
||||||
|
if (!top) {
|
||||||
|
bottom = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// deletes all nodes
|
||||||
|
void free() {
|
||||||
|
Node<Type>* del = top;
|
||||||
|
for (alni i = 0; i < length; i++) {
|
||||||
|
Node<Type>* below = del->below;
|
||||||
|
delete del;
|
||||||
|
del = below;
|
||||||
|
}
|
||||||
|
length = 0;
|
||||||
|
top = NULL;
|
||||||
|
bottom = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
alni sizeAllocatedMem() {
|
||||||
|
alni out = 0;
|
||||||
|
out += sizeof(Node<Type>*) * 2;
|
||||||
|
out += sizeof(alni);
|
||||||
|
out += sizeof(Node<Type>) * length;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
alni sizeUsedMem() {
|
||||||
|
return sizeAllocatedMem();
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator<Type> begin() const {
|
||||||
|
return {top};
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator<Type> end() const {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
158
Containers/outdated/public/Stack.h
Normal file
158
Containers/outdated/public/Stack.h
Normal file
|
|
@ -0,0 +1,158 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "allocators.h"
|
||||||
|
|
||||||
|
namespace tp {
|
||||||
|
extern ModuleManifest gModuleContainer;
|
||||||
|
|
||||||
|
template <typename Type, typename Allocator = tp::PickAlloc>
|
||||||
|
class Stack {
|
||||||
|
public:
|
||||||
|
|
||||||
|
template <typename NodeType>
|
||||||
|
class Node {
|
||||||
|
public:
|
||||||
|
Node<NodeType>* below;
|
||||||
|
NodeType data;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Node(NodeType data, Node<NodeType>* below) {
|
||||||
|
this->below = below;
|
||||||
|
this->data = data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename IterType>
|
||||||
|
struct Iterator {
|
||||||
|
Node<IterType>* mIter;
|
||||||
|
IterType& operator->() { return mIter->data; }
|
||||||
|
const Iterator& operator*() { return *this; }
|
||||||
|
inline void operator++() { mIter = mIter->below; }
|
||||||
|
bool operator==(alni end) { return mIter == NULL; }
|
||||||
|
};
|
||||||
|
|
||||||
|
alni length;
|
||||||
|
Node<Type>* top;
|
||||||
|
|
||||||
|
Allocator alloc;
|
||||||
|
|
||||||
|
Stack() {
|
||||||
|
MODULE_SANITY_CHECK(gModuleContainer);
|
||||||
|
length = 0;
|
||||||
|
top = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
~Stack() {
|
||||||
|
free();
|
||||||
|
}
|
||||||
|
|
||||||
|
// pushes the node on top of the stack
|
||||||
|
void push(Type data) {
|
||||||
|
Node<Type>* NewNode = new (alloc) Node<Type>(data, top);
|
||||||
|
top = NewNode;
|
||||||
|
length++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// pops the top node of the stack
|
||||||
|
void pop() {
|
||||||
|
assert(top);
|
||||||
|
Node<Type>* del = top;
|
||||||
|
top = top->below;
|
||||||
|
delete del;
|
||||||
|
length--;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node<Type>* last() {
|
||||||
|
return top;
|
||||||
|
}
|
||||||
|
|
||||||
|
// deletes all nodes
|
||||||
|
void free() {
|
||||||
|
Node<Type>* del = top;
|
||||||
|
for (alni i = 0; i < length; i++) {
|
||||||
|
Node<Type>* below = del->below;
|
||||||
|
delete del;
|
||||||
|
del = below;
|
||||||
|
}
|
||||||
|
length = 0;
|
||||||
|
top = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
alni sizeAllocatedMem() {
|
||||||
|
alni out = 0;
|
||||||
|
out += sizeof(Node<Type>*);
|
||||||
|
out += sizeof(alni);
|
||||||
|
out += sizeof(Node<Type>) * length;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
alni sizeUsedMem() {
|
||||||
|
return sizeAllocatedMem();
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator<Type> begin() const {
|
||||||
|
return {top};
|
||||||
|
}
|
||||||
|
|
||||||
|
alni end() const {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Type, const halni tSize, typename Index = halni>
|
||||||
|
class ConstSizeStack {
|
||||||
|
|
||||||
|
Type mBuff[tSize];
|
||||||
|
Index mLoadIdx = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ConstSizeStack() {}
|
||||||
|
|
||||||
|
Index loadLen() const {
|
||||||
|
return mLoadIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void push(const Type& in) {
|
||||||
|
assert(mLoadIdx >= 0 && mLoadIdx < tSize && "out of range");
|
||||||
|
mBuff[mLoadIdx] = in;
|
||||||
|
mLoadIdx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop() {
|
||||||
|
mLoadIdx--;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type& last() {
|
||||||
|
assert(mLoadIdx >= 0 && mLoadIdx < tSize && "out of range");
|
||||||
|
return mBuff[mLoadIdx - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
const Type& last() const {
|
||||||
|
assert(mLoadIdx >= 0 && mLoadIdx < tSize && "out of range");
|
||||||
|
return mBuff[mLoadIdx - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
Type* buff() {
|
||||||
|
return mBuff;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type& operator[] (Index idx) {
|
||||||
|
assert(idx >= 0 && idx < tSize && "out of range");
|
||||||
|
return mBuff[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
const Type* buff() const {
|
||||||
|
return mBuff;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Type& operator[] (Index idx) const {
|
||||||
|
assert(idx >= 0 && idx < tSize && "out of range");
|
||||||
|
return mBuff[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr Index len() {
|
||||||
|
return tSize;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
97
Containers/outdated/public/Timeline.h
Normal file
97
Containers/outdated/public/Timeline.h
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Array.h"
|
||||||
|
|
||||||
|
namespace tp {
|
||||||
|
extern ModuleManifest gModuleContainer;
|
||||||
|
|
||||||
|
template <typename Type, bool DEBUG = true>
|
||||||
|
class TimeLine {
|
||||||
|
tp::Array<Type> mMem;
|
||||||
|
tp::halni mStart = 0;
|
||||||
|
tp::halni mLoad = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TimeLine(tp::halni aNSnapshots) {
|
||||||
|
MODULE_SANITY_CHECK(gModuleContainer);
|
||||||
|
mMem.reserve(aNSnapshots);
|
||||||
|
}
|
||||||
|
|
||||||
|
Type* operator[](tp::halni aIdx) const {
|
||||||
|
assert(aIdx < mLoad);
|
||||||
|
auto const idx = mStart + aIdx;
|
||||||
|
if (idx >= mMem.length()) {
|
||||||
|
idx -= mMem.length();
|
||||||
|
}
|
||||||
|
return &mMem[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
void add(const Type& val) {
|
||||||
|
auto const len = mMem.length() - 1;
|
||||||
|
if (mLoad == len) {
|
||||||
|
if (mStart == len) {
|
||||||
|
mStart = 0;
|
||||||
|
}
|
||||||
|
mMem[mStart] = val;
|
||||||
|
mStart++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mMem[mLoad] = val;
|
||||||
|
mLoad++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Type* left() {
|
||||||
|
return &mMem[mStart];
|
||||||
|
}
|
||||||
|
|
||||||
|
Type* right() {
|
||||||
|
if (mLoad == mMem.length() - 1) {
|
||||||
|
return &mMem[0];
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Type* left() const {
|
||||||
|
return &mMem[mStart];
|
||||||
|
}
|
||||||
|
|
||||||
|
const Type* right() const {
|
||||||
|
if (mLoad == mMem.length() - 1) {
|
||||||
|
return &mMem[0];
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
tp::halni leftLen() const {
|
||||||
|
if (mLoad == mMem.length() - 1) {
|
||||||
|
return mMem.length() - (mStart + 1);
|
||||||
|
}
|
||||||
|
return mLoad + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tp::halni rightLen() const {
|
||||||
|
if (mLoad == mMem.length() - 1) {
|
||||||
|
return mStart + 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
class TimeLine<Type, false> {
|
||||||
|
public:
|
||||||
|
TimeLine(tp::halni dummy) {}
|
||||||
|
Type* operator[](tp::halni aIdx) const { return NULL; }
|
||||||
|
void add(const Type& val) {}
|
||||||
|
Type* left() { return NULL; }
|
||||||
|
Type* right() { return NULL; }
|
||||||
|
const Type* left() const { return NULL; }
|
||||||
|
const Type* right() const { return NULL; }
|
||||||
|
tp::halni leftLen() const { return NULL; }
|
||||||
|
tp::halni rightLen() const { return NULL; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
using DebugTimeline = TimeLine<Type, ENV_BUILD_DEBUG_VAR>;
|
||||||
|
};
|
||||||
89
Containers/outdated/tests/fat_nodes.cpp
Normal file
89
Containers/outdated/tests/fat_nodes.cpp
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
|
||||||
|
#include "containers.h"
|
||||||
|
|
||||||
|
namespace tp {
|
||||||
|
|
||||||
|
struct AvlNode {
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
struct EphemeralNode {
|
||||||
|
Type mVal = NULL;
|
||||||
|
halni mVersion = NULL;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
struct EphemeralsContainer {
|
||||||
|
List<EphemeralNode<Type>> mList;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PesistentLink {
|
||||||
|
static EphemeralsContainer<AvlNode*> sContainer;
|
||||||
|
EphemeralNode<AvlNode*>* mNode = NULL;
|
||||||
|
PesistentLink& operator=(const PesistentLink& field) {
|
||||||
|
}
|
||||||
|
PesistentLink& operator=(AvlNode* val) {
|
||||||
|
}
|
||||||
|
//Type& operator->() { return mNode->mVal; }
|
||||||
|
//const ListIterator& operator*() { return *this; }
|
||||||
|
operator AvlNode*() {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PesistentValue {
|
||||||
|
static EphemeralsContainer<halni> sContainer;
|
||||||
|
EphemeralNode<halni>* mNode = NULL;
|
||||||
|
PesistentLink& operator=(const PesistentLink& field) {}
|
||||||
|
PesistentLink& operator=(halni val) {}
|
||||||
|
operator halni() {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
PesistentLink mLeft;
|
||||||
|
PesistentLink mRight;
|
||||||
|
PesistentLink mParent;
|
||||||
|
PesistentValue mHeight;
|
||||||
|
|
||||||
|
PesistentValue mVal;
|
||||||
|
halni mRefCount = 0;
|
||||||
|
|
||||||
|
AvlNode() { mVal = 0; }
|
||||||
|
AvlNode(halni aKey) {
|
||||||
|
mVal = aKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool disentRight(halni aKey) {
|
||||||
|
return aKey > mVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool disentLeft(halni aKey) {
|
||||||
|
return aKey < mVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool exactNode(halni aKey) {
|
||||||
|
return aKey == mVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
halni getFindKey(AvlNode* node = NULL) {
|
||||||
|
return mVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
void copyData(const AvlNode& in) {
|
||||||
|
mVal = in.mVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
halni keyInRightSubtree(halni key) { return key; }
|
||||||
|
halni keyInLeftSubtree(halni key) { return key; }
|
||||||
|
|
||||||
|
void updateTreeCahceCallBack() {}
|
||||||
|
|
||||||
|
void* operator new(std::size_t) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator delete(void* p) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
void fat_nodes_test() {
|
||||||
|
tp::AvlTree<tp::AvlNode, tp::halni> avl;
|
||||||
|
}
|
||||||
148
Containers/outdated/tests/quick.cpp
Normal file
148
Containers/outdated/tests/quick.cpp
Normal file
|
|
@ -0,0 +1,148 @@
|
||||||
|
|
||||||
|
#include "containers.h"
|
||||||
|
|
||||||
|
using namespace tp;
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
void list_test() {
|
||||||
|
tp::List<int> q;
|
||||||
|
|
||||||
|
q.pushBack(0);
|
||||||
|
q.pushBack(1);
|
||||||
|
q.pushBack(2);
|
||||||
|
q.pushBack(3);
|
||||||
|
q.pushBack(4);
|
||||||
|
q.pushBack(5);
|
||||||
|
|
||||||
|
for (auto node : q) {
|
||||||
|
printf("%i ", node.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
q.popBack();
|
||||||
|
q.popFront();
|
||||||
|
|
||||||
|
q.pushBack(4);
|
||||||
|
q.pushFront(1);
|
||||||
|
|
||||||
|
q.invert();
|
||||||
|
|
||||||
|
for (auto node : q) {
|
||||||
|
printf("%i ", node.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
q.sort([](ListNode<int>* const& node1, ListNode<int>* const& node2) { return node1->data > node2->data; });
|
||||||
|
|
||||||
|
for (auto node : q) {
|
||||||
|
printf("%i ", node.data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// numeric node test
|
||||||
|
void avl_test() {
|
||||||
|
AvlTree<NumericNode<float>, float> avl;
|
||||||
|
|
||||||
|
for (auto i : Range<ualni>(100)) {
|
||||||
|
//avl.insert(i, halnf(i));
|
||||||
|
auto ret = avl.isInvalid(avl.head());
|
||||||
|
DBG_BREAK(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto node : avl) {
|
||||||
|
printf("%f ", node.node()->mVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto p = avl.find(0);
|
||||||
|
p = avl.find(50);
|
||||||
|
//p = avl.find(avl_ts(100));
|
||||||
|
|
||||||
|
auto t = avl.find_less_or_eq(50);
|
||||||
|
t = avl.find_less_or_eq(50.5);
|
||||||
|
t = avl.find_less_or_eq(100.5);
|
||||||
|
t = avl.find_less_or_eq(0.5);
|
||||||
|
|
||||||
|
auto end = avl.end(avl.find(99));
|
||||||
|
for (auto iter = avl.begin(p); iter != end; ++iter) {
|
||||||
|
printf("%f ", iter.node()->mVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <typeinfo>
|
||||||
|
|
||||||
|
void map_test() {
|
||||||
|
|
||||||
|
struct CheckData {
|
||||||
|
ualni mDummy = 0;
|
||||||
|
bool mAddedToMap = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
HashMap<alni, alni> map;
|
||||||
|
|
||||||
|
const uhalni test_scale = 1000;
|
||||||
|
const uhalni test_iterations = 100000;
|
||||||
|
|
||||||
|
Array<CheckData> checker(test_scale);
|
||||||
|
|
||||||
|
for (auto test : Range<ualni>(test_iterations)) {
|
||||||
|
auto idx = alni(tp::randf() * (test_scale - 1));
|
||||||
|
|
||||||
|
auto map_idx = map.presents(idx);
|
||||||
|
if (checker[idx].mAddedToMap != map_idx) {
|
||||||
|
DBG_BREAK("Presentment mismatch");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (map_idx) {
|
||||||
|
if (idx != map.getSlotVal(map_idx)) {
|
||||||
|
DBG_BREAK("Data mismatch");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checker[idx].mAddedToMap) {
|
||||||
|
map.remove(idx);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
map.put(idx, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
checker[idx].mAddedToMap = !checker[idx].mAddedToMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto iter : map) {
|
||||||
|
iter->val = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void queue_test() {
|
||||||
|
tp::Queue<int> q;
|
||||||
|
|
||||||
|
q.push(0);
|
||||||
|
q.push(1);
|
||||||
|
q.push(2);
|
||||||
|
q.push(3);
|
||||||
|
q.push(4);
|
||||||
|
q.push(5);
|
||||||
|
|
||||||
|
for (auto node : q) {
|
||||||
|
printf("%i ", node.mIter->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
q.pop();
|
||||||
|
q.pop();
|
||||||
|
q.pop();
|
||||||
|
q.pop();
|
||||||
|
q.pop();
|
||||||
|
q.pop();
|
||||||
|
|
||||||
|
q.push(3);
|
||||||
|
q.push(4);
|
||||||
|
q.push(5);
|
||||||
|
|
||||||
|
for (auto node : q) {
|
||||||
|
printf("%i ", node.mIter->data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void timeline_test() {
|
||||||
|
tp::DebugTimeline<tp::halni> tl(100);
|
||||||
|
tl.add(1);
|
||||||
|
}
|
||||||
16
Containers/outdated/tests/tests.cpp
Normal file
16
Containers/outdated/tests/tests.cpp
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
#include "containers.h"
|
||||||
|
|
||||||
|
void avl_test();
|
||||||
|
void map_test();
|
||||||
|
void queue_test();
|
||||||
|
void list_test();
|
||||||
|
void fat_nodes_test();
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
tp::alloc_init();
|
||||||
|
|
||||||
|
map_test();
|
||||||
|
|
||||||
|
tp::alloc_uninit();
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue