summaryrefslogtreecommitdiff
path: root/src/memory.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/memory.hpp')
-rw-r--r--src/memory.hpp23
1 files changed, 21 insertions, 2 deletions
diff --git a/src/memory.hpp b/src/memory.hpp
index bde3f2b..6d431fc 100644
--- a/src/memory.hpp
+++ b/src/memory.hpp
@@ -8,6 +8,8 @@
#include <cstdlib>
#include <cstdio>
#include <cassert>
+#include <type_traits>
+#include <new>
// 256MB
#define DEFAULT_BUCKET_SIZE 1UL << 27
@@ -35,18 +37,35 @@ void Pke_MemoryFlush();
template <typename T>
inline T *Pke_New() {
void *ptr = Pke_New(sizeof(T));
- return new (ptr) T{};
+ if IS_CONSTRUCTIBLE(T) {
+ return new (ptr) T{};
+ }
+ return reinterpret_cast<T *>(ptr);
}
template <typename T>
inline T *Pke_New(long count) {
- return reinterpret_cast<T *>(Pke_New(sizeof(T) * count));
+ char *ptr = static_cast<char *>(Pke_New(sizeof(T) * count));
+ if IS_CONSTRUCTIBLE(T) {
+ for (long i = 0; i < count; ++i) {
+ new (ptr + (i * sizeof(T))) T{};
+ }
+ }
+ return reinterpret_cast<T *>(ptr);
}
template <typename T>
inline void Pke_Delete(const void *ptr) {
+ if IS_DESTRUCTIBLE(T) {
+ reinterpret_cast<const T *>(ptr)->~T();
+ }
return Pke_Delete(ptr, sizeof(T));
}
template <typename T>
inline void Pke_Delete(const void *ptr, long count) {
+ if IS_DESTRUCTIBLE(T) {
+ for (long i = 0; i < count; ++i) {
+ reinterpret_cast<const T *>(reinterpret_cast<const char *>(ptr) + (i * sizeof(T)))->~T();
+ }
+ }
return Pke_Delete(ptr, sizeof(T) * count);
}