Grail (C++)  1.1.1
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 "../GrailCore/consts.h"
5 
6 #include <memory>
7 #include <string>
8 #include <type_traits>
9 #include <utility>
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:
80  MemoryPool(const std::size_t BYTES = 5242880u)
81  : blocks{new char[BYTES]},
82  currentMemoryCell{&blocks[0]},
83  _size{0},
84  BYTES{BYTES}
85  {
86  }
87 
88  ~MemoryPool()
89  {
90  delete[] blocks;
91  }
92 
93  template <typename T, typename... ConstructorArguments>
94  T& Emplace(ConstructorArguments&&... arguments)
95  {
96  std::size_t memoryRequired = sizeof(T);
97  _size += memoryRequired;
98 
99  if(_size > BYTES)
100  {
101  throw std::bad_alloc{};
102  }
103 
104  Emplacer<T> emplacer;
105  T& result = emplacer(currentMemoryCell, std::forward<ConstructorArguments>(arguments)...);
106  currentMemoryCell = static_cast<char*>(currentMemoryCell) + memoryRequired;
107  return result;
108  }
109 
110  std::size_t Size() const
111  {
112  return _size;
113  }
114 
115  void Reset()
116  {
117  currentMemoryCell = &blocks[0];
118  _size = 0;
119  }
120 
121  private:
122  char* const blocks;
123  void* currentMemoryCell;
124  std::size_t _size;
125  const std::size_t BYTES;
126  };
127 }
128 
129 #endif // GRAIL_POOL_ALLOCATOR_H
grail::MemoryPool::MemoryPool
MemoryPool(const std::size_t BYTES=5242880u)
MemoryPool.
Definition: MemoryPool.hh:80
grail::MemoryPool
The MemoryPool class - preallocated memory container for optimization issues.
Definition: MemoryPool.hh:73
grail::Emplacer
Definition: MemoryPool.hh:14