3 #ifndef GRAIL_POOL_ALLOCATOR_H
4 #define GRAIL_POOL_ALLOCATOR_H
6 #include "../GrailCore/consts.h"
10 #include <type_traits>
21 Emplacer(
typename std::enable_if<std::is_trivially_destructible<T>::value>::type* = 0)
25 template <
typename... Arguments>
26 T& operator()(
void* memoryCell, Arguments&&... arguments)
28 return *(
new(memoryCell) T{std::forward<Arguments>(arguments)...});
36 template <
typename... Arguments>
37 std::string& operator()(
void* memoryCell, Arguments&&... arguments)
39 if(StringLength(std::forward<Arguments>(arguments)...) > consts::MAX_STRING_SIZE)
41 throw std::bad_alloc{};
43 return *(
new(memoryCell) std::string{std::forward<Arguments>(arguments)...});
47 std::size_t StringLength(
const std::string&
string)
const
57 template <
typename... Arguments>
58 const std::string& operator()(
void* memoryCell, Arguments&&... arguments)
60 if(StringLength(std::forward<Arguments>(arguments)...) > consts::MAX_STRING_SIZE)
62 throw std::bad_alloc{};
64 return *(
new(memoryCell)
const std::string{std::forward<Arguments>(arguments)...});
68 std::size_t StringLength(
const std::string&
string)
const
85 : blocks{
new char[BYTES]},
86 currentMemoryCell{&blocks[0]},
97 template <
typename T,
typename... ConstructorArguments>
98 T& Emplace(ConstructorArguments&&... arguments)
100 std::size_t memoryRequired =
sizeof(T);
101 std::size_t alignment =
alignof(T);
102 std::size_t leftoverBytes = _size % alignment;
104 if(leftoverBytes > 0)
106 std::size_t padding = (alignment - leftoverBytes);
110 currentMemoryCell =
static_cast<char*
>(currentMemoryCell) + padding;
114 _size += memoryRequired;
118 throw std::bad_alloc{};
121 Emplacer<T> emplacer;
122 T& result = emplacer(currentMemoryCell, std::forward<ConstructorArguments>(arguments)...);
123 currentMemoryCell =
static_cast<char*
>(currentMemoryCell) + memoryRequired;
127 std::size_t Size()
const
134 currentMemoryCell = &blocks[0];
140 void* currentMemoryCell;
142 const std::size_t BYTES;
147 #endif // GRAIL_POOL_ALLOCATOR_H