Add Add HashMap with dependices from mutils
This commit is contained in:
parent
6217aec6be
commit
9abc36be1c
4 changed files with 971 additions and 0 deletions
137
source/ecs/string_intern.d
Normal file
137
source/ecs/string_intern.d
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
module ecs.string_intern;
|
||||
|
||||
import ecs.hash_map;
|
||||
import ecs.traits : isForeachDelegateWithI;
|
||||
import std.experimental.allocator;
|
||||
import std.experimental.allocator.mallocator;
|
||||
import std.traits : Parameters;
|
||||
|
||||
private __gshared static HashMap!(const(char)[], StringIntern) gStringInterns;
|
||||
|
||||
struct StringIntern {
|
||||
private const(char)* strPtr;
|
||||
|
||||
this(const(char)[] fromStr) {
|
||||
opAssign(fromStr);
|
||||
}
|
||||
|
||||
void reset() {
|
||||
strPtr=null;
|
||||
}
|
||||
|
||||
size_t length() {
|
||||
if (strPtr is null) {
|
||||
return 0;
|
||||
}
|
||||
return *cast(size_t*)(strPtr - 8);
|
||||
}
|
||||
|
||||
const(char)[] str() {
|
||||
if (strPtr is null) {
|
||||
return null;
|
||||
}
|
||||
return strPtr[0 .. length];
|
||||
}
|
||||
|
||||
const(char)[] cstr() {
|
||||
if (strPtr is null) {
|
||||
return "\0";
|
||||
}
|
||||
return strPtr[0 .. length + 1];
|
||||
}
|
||||
|
||||
bool opEquals()(auto ref const StringIntern s) {
|
||||
return strPtr == s.strPtr;
|
||||
}
|
||||
|
||||
bool opEquals()(auto ref const(char[]) s) {
|
||||
return str() == s;
|
||||
}
|
||||
|
||||
void opAssign(const(char)[] fromStr) {
|
||||
if (fromStr.length == 0) {
|
||||
return;
|
||||
}
|
||||
StringIntern defaultValue;
|
||||
StringIntern internedStr = gStringInterns.get(fromStr, defaultValue);
|
||||
|
||||
if (internedStr.length == 0) {
|
||||
internedStr.strPtr = allocStr(fromStr).ptr;
|
||||
gStringInterns.add(internedStr.str, internedStr);
|
||||
}
|
||||
|
||||
strPtr = internedStr.strPtr;
|
||||
}
|
||||
|
||||
const(char)[] opSlice() {
|
||||
if (strPtr is null) {
|
||||
return null;
|
||||
}
|
||||
return strPtr[0 .. length];
|
||||
}
|
||||
|
||||
private const(char)[] allocStr(const(char)[] fromStr) {
|
||||
char[] data = Mallocator.instance.makeArray!(char)(fromStr.length + size_t.sizeof + 1);
|
||||
size_t* len = cast(size_t*) data.ptr;
|
||||
*len = fromStr.length;
|
||||
data[size_t.sizeof .. $ - 1] = fromStr;
|
||||
data[$ - 1] = '\0';
|
||||
return data[size_t.sizeof .. $ - 1];
|
||||
}
|
||||
}
|
||||
|
||||
unittest {
|
||||
static assert(StringIntern.sizeof == size_t.sizeof);
|
||||
const(char)[] chA = ['a', 'a'];
|
||||
char[] chB = ['o', 't', 'h', 'e', 'r'];
|
||||
const(char)[] chC = ['o', 't', 'h', 'e', 'r'];
|
||||
string chD = "other";
|
||||
|
||||
StringIntern strA;
|
||||
StringIntern strB = StringIntern("");
|
||||
StringIntern strC = StringIntern("a");
|
||||
StringIntern strD = "a";
|
||||
StringIntern strE = "aa";
|
||||
StringIntern strF = chA;
|
||||
StringIntern strG = chB;
|
||||
|
||||
assert(strA == strB);
|
||||
assert(strA != strC);
|
||||
assert(strC == strD);
|
||||
assert(strD != strE);
|
||||
assert(strE == strF);
|
||||
|
||||
assert(strD.length == 1);
|
||||
assert(strE.length == 2);
|
||||
assert(strG.length == 5);
|
||||
|
||||
strA = "other";
|
||||
assert(strA == "other");
|
||||
assert(strA == chB);
|
||||
assert(strA == chC);
|
||||
assert(strA == chD);
|
||||
assert(strA.str.ptr[strA.str.length] == '\0');
|
||||
assert(strA.cstr[$ - 1] == '\0');
|
||||
|
||||
foreach (char c; strA) {
|
||||
}
|
||||
foreach (int i, char c; strA) {
|
||||
}
|
||||
foreach (ubyte i, char c; strA) {
|
||||
}
|
||||
foreach (c; strA) {
|
||||
}
|
||||
}
|
||||
|
||||
unittest {
|
||||
import mutils.container.hash_map : HashMap;
|
||||
|
||||
HashMap!(StringIntern, StringIntern) map;
|
||||
|
||||
map.add(StringIntern("aaa"), StringIntern("bbb"));
|
||||
map.add(StringIntern("aaa"), StringIntern("bbb"));
|
||||
|
||||
assert(map.length == 1);
|
||||
assert(map.get(StringIntern("aaa")) == StringIntern("bbb"));
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue