3 #ifndef GRAIL_POOL_ALLOCATOR_H
4 #define GRAIL_POOL_ALLOCATOR_H
6 #include "../GrailCore/consts.h"
7 #include "../GrailLogger/LoggerManager.hh"
11 #include <type_traits>
22 Emplacer(
typename std::enable_if<std::is_trivially_destructible<T>::value>::type* = 0)
26 template <
typename... Arguments>
27 T& operator()(
void* memoryCell, Arguments&&... arguments)
29 return *(
new(memoryCell) T{std::forward<Arguments>(arguments)...});
37 template <
typename... Arguments>
38 std::string& operator()(
void* memoryCell, Arguments&&... arguments)
40 if(StringLength(std::forward<Arguments>(arguments)...) > consts::MAX_STRING_SIZE)
42 throw std::bad_alloc{};
44 return *(
new(memoryCell) std::string{std::forward<Arguments>(arguments)...});
48 std::size_t StringLength(
const std::string&
string)
const
58 template <
typename... Arguments>
59 const std::string& operator()(
void* memoryCell, Arguments&&... arguments)
61 if(StringLength(std::forward<Arguments>(arguments)...) > consts::MAX_STRING_SIZE)
63 GRAIL_LOG(consts::DEFAULT_GRAIL_LOG_GROUP, logger::Severity::ERRORS,
"Planner memory pool out of memory");
64 throw std::bad_alloc{};
66 return *(
new(memoryCell)
const std::string{std::forward<Arguments>(arguments)...});
70 std::size_t StringLength(
const std::string&
string)
const
87 : blocks{
new char[BYTES]},
88 currentMemoryCell{&blocks[0]},
99 template <
typename T,
typename... ConstructorArguments>
100 T& Emplace(ConstructorArguments&&... arguments)
102 std::size_t memoryRequired =
sizeof(T);
103 std::size_t alignment =
alignof(T);
104 std::size_t leftoverBytes = _size % alignment;
106 if(leftoverBytes > 0)
108 std::size_t padding = (alignment - leftoverBytes);
112 currentMemoryCell =
static_cast<char*
>(currentMemoryCell) + padding;
116 _size += memoryRequired;
120 throw std::bad_alloc{};
123 Emplacer<T> emplacer;
124 T& result = emplacer(currentMemoryCell, std::forward<ConstructorArguments>(arguments)...);
125 currentMemoryCell =
static_cast<char*
>(currentMemoryCell) + memoryRequired;
129 std::size_t Size()
const
134 void Reset(std::size_t size = 0)
138 GRAIL_LOG(consts::DEFAULT_GRAIL_LOG_GROUP, logger::Severity::ERRORS,
"Pool reset to size exceeding allocated memory");
142 currentMemoryCell = &blocks[size];
148 void* currentMemoryCell;
150 const std::size_t BYTES;
155 #endif // GRAIL_POOL_ALLOCATOR_H