Lugdunum  0.1.0
Memory.inl
Go to the documentation of this file.
1 template <typename T, class Arena, class ...Args>
2 inline T* new_one(size_t alignment, const char* file, size_t line, Arena& arena, Args&&... args) {
3  void* ptr = arena.allocate(sizeof(T), alignment, 0, file, line);
4 
5  if (!ptr) {
6  return nullptr;
7  }
8 
9  return new (ptr) T{std::forward<Args>(args)...};
10 }
11 
12 template <typename T, class Arena>
13 inline void delete_one(T* object, Arena& arena) {
14  if (object) {
15  object->~T();
16  }
17 
18  arena.free(object);
19 }
20 
21 template <typename T, class Arena, class ...Args, typename std::enable_if<!std::is_pod<T>::value, int>::type>
22 inline T* new_array(size_t alignment, size_t nb, const char* file, size_t line, Arena& arena, Args&&... args) {
23  if (nb == 0) {
24  return nullptr;
25  }
26 
27  void* const ptr = arena.allocate(sizeof(T) * nb + sizeof(size_t), alignment, sizeof(size_t), file, line);
28 
29  if (!ptr) {
30  return nullptr;
31  }
32 
33  // Store the size of the array
34  size_t* size_ptr = static_cast<size_t*>(ptr);
35  *size_ptr = nb;
36 
37  // Call the constructors
38  T* const user_ptr = reinterpret_cast<T*>(size_ptr + 1);
39  for (size_t i = 0; i < nb; ++i) {
40  new (&user_ptr[i]) T{std::forward<Args>(args)...};
41  }
42 
43  return user_ptr;
44 }
45 
46 template <typename T, class Arena, typename std::enable_if<!std::is_pod<T>::value, int>::type>
47 inline void delete_array(T* ptr, Arena& arena) {
48  if (!ptr) {
49  arena.free(ptr);
50  return;
51  }
52 
53  // Get back the size of the array
54  size_t* size_ptr = reinterpret_cast<size_t*>(ptr);
55  const size_t nb = size_ptr[-1];
56 
57  // Call the destructors in reverse order
58  for (size_t i = nb; i > 0; --i) {
59  ptr[i - 1].~T();
60  }
61 
62  arena.free(&(size_ptr[-1]));
63 }
64 
65 template <typename T, class Arena, typename std::enable_if<std::is_pod<T>::value, int>::type>
66 inline T* new_array(size_t alignment, size_t nb, const char* file, size_t line, Arena& arena) {
67  void* ptr = arena.allocate(sizeof(T) * nb, alignment, 0, file, line);
68 
69  if (!ptr) {
70  return nullptr;
71  }
72 
73  return new(ptr) T{};
74 }
75 
76 template <typename T, class Arena, typename std::enable_if<std::is_pod<T>::value, int>::type>
77 inline void delete_array(T* ptr, Arena& arena) {
78  arena.free(ptr);
79 }
80 
81 
82 // make_unique of single object
83 template <typename T, class Arena, typename ...Args>
84 inline typename priv::make_unique_if<T>::SingleObject make_unique(Arena& arena, Args&&... args) {
85  return make_unique_align<T>(arena, alignof(T), std::forward<Args>(args)...);
86 }
87 
88 template <typename T, class Arena, typename ...Args>
89 typename priv::make_unique_if<T>::SingleObject make_unique_align(Arena& arena, size_t alignment, Args&&... args) {
90  auto deleter = [&arena](T* ptr) {
91  LUG_DELETE(ptr, arena);
92  };
93 
94  return typename priv::make_unique_if<T>::SingleObject(
95  LUG_NEW_ALIGN(T, alignment, arena, std::forward<Args>(args)...),
96  deleter
97  );
98 }
99 
100 // make_unique of dynamic array (args only for non POD types)
101 template <typename T, class Arena, typename ...Args, typename std::enable_if<!std::is_pod<T>::value, int>::type>
102 inline typename priv::make_unique_if<T>::UnknownBound make_unique(Arena& arena, size_t size, Args&&... args) {
103  return make_unique_align<T>(arena, alignof(T), size, std::forward<Args>(args)...);
104 }
105 
106 template <typename T, class Arena, typename ...Args, typename std::enable_if<!std::is_pod<T>::value, int>::type>
107 typename priv::make_unique_if<T>::UnknownBound make_unique_align(Arena& arena, size_t alignment, size_t size, Args&&... args) {
108  using U = typename std::remove_all_extents<T>::type;
109 
110  auto deleter = [&arena](U* ptr) {
111  LUG_DELETE_ARRAY(ptr, arena);
112  };
113 
114  return typename priv::make_unique_if<T>::UnknownBound(
115  LUG_NEW_ARRAY_ALIGN_SIZE(T, alignment, size, arena, std::forward<Args>(args)...),
116  deleter
117  );
118 }
119 
120 template <typename T, class Arena, typename std::enable_if<std::is_pod<T>::value, int>::type>
121 inline typename priv::make_unique_if<T>::UnknownBound make_unique(Arena& arena, size_t size) {
122  return make_unique_align<T>(arena, alignof(T), size);
123 }
124 
125 template <typename T, class Arena, typename std::enable_if<std::is_pod<T>::value, int>::type>
126 typename priv::make_unique_if<T>::UnknownBound make_unique_align(Arena& arena, size_t alignment, size_t size) {
127  using U = typename std::remove_all_extents<T>::type;
128 
129  auto deleter = [&arena](U* ptr) {
130  LUG_DELETE_ARRAY(ptr, arena);
131  };
132 
133  return typename priv::make_unique_if<T>::UnknownBound(
134  LUG_NEW_ARRAY_ALIGN_SIZE(T, alignment, size, arena),
135  deleter
136  );
137 }
138 
139 // make_unique of static array (args only for non POD types)
140 template <typename T, class Arena, typename ...Args, typename std::enable_if<!std::is_pod<T>::value, int>::type>
141 inline typename priv::make_unique_if<T>::KnownBound make_unique(Arena& arena, Args&&... args) {
142  return make_unique_align<T>(arena, alignof(T), std::forward<Args>(args)...);
143 }
144 
145 template <typename T, class Arena, typename ...Args, typename std::enable_if<!std::is_pod<T>::value, int>::type>
146 typename priv::make_unique_if<T>::KnownBound make_unique_align(Arena& arena, size_t alignment, Args&&... args) {
147  using U = typename std::remove_all_extents<T>::type;
148 
149  auto deleter = [&arena](U* ptr) {
150  LUG_DELETE_ARRAY(ptr, arena);
151  };
152 
153  return typename priv::make_unique_if<T>::KnownBound(
154  LUG_NEW_ARRAY_ALIGN(T, alignment, arena, std::forward<Args>(args)...),
155  deleter
156  );
157 }
158 
159 template <typename T, class Arena, typename std::enable_if<std::is_pod<T>::value, int>::type>
160 typename priv::make_unique_if<T>::KnownBound make_unique(Arena& arena) {
161  return make_unique_align<T>(arena, alignof(T));
162 }
163 
164 template <typename T, class Arena, typename std::enable_if<std::is_pod<T>::value, int>::type>
165 typename priv::make_unique_if<T>::KnownBound make_unique_align(Arena& arena, size_t alignment) {
166  using U = typename std::remove_all_extents<T>::type;
167 
168  auto deleter = [&arena](U* ptr) {
169  LUG_DELETE_ARRAY(ptr, arena);
170  };
171 
172  return typename priv::make_unique_if<T>::KnownBound(
173  LUG_NEW_ARRAY_ALIGN(T, alignment, arena),
174  deleter
175  );
176 }
void delete_one(T *object, Arena &arena)
Definition: Memory.inl:13
#define LUG_NEW_ARRAY_ALIGN(T, alignment,...)
Definition: Memory.hpp:17
#define LUG_NEW_ARRAY_ALIGN_SIZE(T, alignment, size,...)
Definition: Memory.hpp:18
T * new_array(size_t alignment, size_t nb, const char *file, size_t line, Arena &arena, Args &&... args)
Definition: Memory.inl:22
#define LUG_DELETE(object, arena)
Definition: Memory.hpp:21
#define LUG_DELETE_ARRAY(object, arena)
Definition: Memory.hpp:25
T * new_one(size_t alignment, const char *file, size_t line, Arena &arena, Args &&... args)
Definition: Memory.inl:2
#define LUG_NEW_ALIGN(T, alignment,...)
Definition: Memory.hpp:16
priv::make_unique_if< T >::SingleObject make_unique_align(Arena &arena, size_t alignment, Args &&... args)
Definition: Memory.inl:89
priv::make_unique_if< T >::SingleObject make_unique(Arena &arena, Args &&... args)
Definition: Memory.inl:84
void delete_array(T *ptr, Arena &arena)
Definition: Memory.inl:47