module ecs.std; import core.stdc.stdlib : malloc, free, realloc; import core.stdc.string : memcpy; import std.traits; import core.time; version (Windows) { import core.sys.windows.windows; extern(Windows) void* _aligned_malloc(size_t size,size_t alignment) @nogc nothrow @system; extern(Windows) void _aligned_free(void* ptr) @nogc nothrow @system; version(LDC) { /*extern(Windows) void* __alloca(size_t size) @nogc nothrow @system; alias alloca = __alloca;*/ private const uint max_alloca = 10000; private char[max_alloca] alloca_array; private uint alloca_pos = 0; void* alloca(size_t length) @nogc nothrow { if(alloca_pos + length > max_alloca)alloca_pos = 0; void* ret = &alloca_array[alloca_pos]; alloca_pos += length; return ret; } extern(Windows) void ___chkstk_ms() @nogc nothrow @system; extern(Windows) void __chkstk() { ___chkstk_ms(); } } else { private const uint max_alloca = 10000; private char[max_alloca] alloca_array; private uint alloca_pos = 0; void* alloca(size_t length) @nogc nothrow { if(alloca_pos + length > max_alloca)alloca_pos = 0; void* ret = &alloca_array[alloca_pos]; alloca_pos += length; return ret; } } } else version (Posix) { import core.sys.posix.pthread; import core.sys.posix.stdlib; public import core.stdc.stdlib : alloca; } static struct Mallocator { static T[] makeArray(T)(size_t length) nothrow @nogc { T[] ret = (cast(T*)malloc(T.sizeof * length))[0 .. length]; /*static if(__traits(isPOD, T)) { static immutable T init = T.init; foreach(i;0..ret.length) { memcpy(&ret[i], &init, T.sizeof); } } else {*/ static import std.conv; foreach(i;0..ret.length) { std.conv.emplace(&ret[i]); } // } //static if(is(T == struct))std.conv.emplace(ret); //static import std.conv; //emplace /*foreach(i;0..ret.length) { memcpy(ret); }*/ return ret; } static T[] makeArray(T)(size_t length, T initializer) nothrow @nogc { T[] ret = (cast(T*)malloc(T.sizeof * length))[0 .. length]; foreach(ref v; ret)v = initializer; return ret; //return (cast(T*)ret)[0 .. length]; } static T[] expandArray(T)(T[] array, size_t length) nothrow @nogc { size_t new_length = array.length + length; return (cast(T*)realloc(array.ptr, T.sizeof * new_length))[0 .. new_length]; } static T[] makeArray(T)(T[] array) nothrow @nogc { T[] ret = (cast(T*)malloc(T.sizeof * array.length))[0 .. array.length];//Mallocator.makeArray!(T)(array.length); foreach(i, ref v;ret)v = array[i]; //ret[0 .. $] = array; return ret; } static T* make(T, Args...)(Args args) { T* ret = cast(T*)malloc(T.sizeof); //*ret = T.init; //static immutable T init = T(); //memcpy(ret, &init, T.sizeof); //static if(__traits(hasMember, T, "__ctor"))ret.__ctor(args); static import std.conv; static if(__traits(isPOD, T)) { static immutable T init = T.init; memcpy(ret, &init, T.sizeof); } else static if(is(T == struct))std.conv.emplace(ret, args); //else std.conv.emplace(ret, args); return ret; } static void* alignAlloc(size_t length, size_t alignment) nothrow @nogc { void* ret; version(Posix)ret = aligned_alloc(alignment, length); else version(Windows)ret = _aligned_malloc(length, alignment); else static assert(0, "Unimplemented platform!"); //posix_memalign(&ret, alignment, length); return ret; } static void dispose(T)(T object) nothrow @nogc { static if(__traits(hasMember, T, "__dtor"))object.__dtor(); free(cast(void*)object); } static void alignDispose(T)(T object) { static if(__traits(hasMember, T, "__dtor"))object.__dtor(); version(Posix)aligned_free(cast(void*)object); else version(Windows)_aligned_free(cast(void*)object); else static assert(0, "Unimplemented platform!"); } } struct Mutex { version (Windows) { void initialize() nothrow @nogc { InitializeCriticalSection(cast(CRITICAL_SECTION*) &m_handle); } void destroy() nothrow @nogc { DeleteCriticalSection(&m_handle); } void lock() nothrow @nogc { EnterCriticalSection(&m_handle); } void unlock() nothrow @nogc { LeaveCriticalSection(&m_handle); } int tryLock() nothrow @nogc { return TryEnterCriticalSection(&m_handle) != 0; } CRITICAL_SECTION m_handle; } else version (Posix) { void initialize() nothrow @nogc { pthread_mutexattr_t attr = void; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(cast(pthread_mutex_t*) &m_handle, &attr); pthread_mutexattr_destroy(&attr); } void destroy() nothrow @nogc { pthread_mutex_destroy(&m_handle); } void lock() nothrow @nogc { pthread_mutex_lock(&m_handle); } void unlock() nothrow @nogc { pthread_mutex_unlock(&m_handle); } int tryLock() nothrow @nogc { return pthread_mutex_trylock(&m_handle) == 0; } private pthread_mutex_t m_handle; } }