(C++)  1.0.0
A multi-platform, modular, universal engine for embedding advanced AI in games.
MemoryPool.hh
1 #ifndef GRAIL_POOL_ALLOCATOR_H
2 #define GRAIL_POOL_ALLOCATOR_H
3 
4 #include "../GrailSystem/consts.h"
5 
6 #include <type_traits>
7 #include <utility>
8 #include <memory>
9 #include <string>
10 
11 namespace grail
12 {
13  template<typename T>
14  class Emplacer final
15  {
16  public:
17  Emplacer(typename std::enable_if<std::is_trivially_destructible<T>::value>::type* = 0)
18  {
19  }
20 
21  template <typename... Arguments>
22  T& operator()(void* memoryCell, Arguments&&... arguments)
23  {
24  return *(new(memoryCell) T{std::forward<Arguments>(arguments)...});
25  }
26  };
27 
28  template <>
29  class Emplacer<std::string>
30  {
31  public:
32  template <typename... Arguments>
33  std::string& operator()(void* memoryCell, Arguments&&... arguments)
34  {
35  if(StringLength(std::forward<Arguments>(arguments)...) > consts::MAX_STRING_SIZE)
36  {
37  throw std::bad_alloc{};
38  }
39  return *(new(memoryCell) std::string{std::forward<Arguments>(arguments)...});
40  }
41 
42  private:
43  std::size_t StringLength(const std::string& string) const
44  {
45  return string.size();
46  }
47  };
48 
49  template <>
50  class Emplacer<const std::string>
51  {
52  public:
53  template <typename... Arguments>
54  const std::string& operator()(void* memoryCell, Arguments&&... arguments)
55  {
56  if(StringLength(std::forward<Arguments>(arguments)...) > consts::MAX_STRING_SIZE)
57  {
58  throw std::bad_alloc{};
59  }
60  return *(new(memoryCell) const std::string{std::forward<Arguments>(arguments)...});
61  }
62 
63  private:
64  std::size_t StringLength(const std::string& string) const
65  {
66  return string.size();
67  }
68  };
69 
73  class MemoryPool final
74  {
75  public:
76 
81  MemoryPool(const std::size_t BYTES = 5242880u)
82  : blocks{new char[BYTES]}, currentMemoryCell{&blocks[0]}, _size{0},
83  BYTES{BYTES}
84  {
85  }
86 
87  ~MemoryPool()
88  {
89  delete[] blocks;
90  }
91 
92  template<typename T, typename... ConstructorArguments>
93  T& Emplace(ConstructorArguments&&... arguments)
94  {
95  std::size_t memoryRequired = sizeof(T);
96  _size += memoryRequired;
97 
98  if(_size > BYTES)
99  {
100  throw std::bad_alloc{};
101  }
102 
103  Emplacer<T> emplacer;
104  T& result = emplacer(currentMemoryCell, std::forward<ConstructorArguments>(arguments)...);
105  currentMemoryCell = static_cast<char*>(currentMemoryCell) + memoryRequired;
106  return result;
107  }
108 
109  std::size_t Size() const
110  {
111  return _size;
112  }
113 
114  void Reset()
115  {
116  currentMemoryCell = &blocks[0];
117  _size = 0;
118  }
119 
120  private:
121  char* const blocks;
122  void* currentMemoryCell;
123  std::size_t _size;
124  const std::size_t BYTES;
125  };
126 }
127 
128 #endif // GRAIL_POOL_ALLOCATOR_H
Definition: MemoryPool.hh:15
The MemoryPool class - preallocated memory container for optimization issues.
Definition: MemoryPool.hh:74
MemoryPool(const std::size_t BYTES=5242880u)
MemoryPool.
Definition: MemoryPool.hh:81