Lugdunum  0.1.0
Memory.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <cstddef>
4 #include <type_traits>
5 #include <new>
6 #include <memory>
7 #include <functional>
8 
13 
14 
15 // The variadic arguments are always "arena, args..." (args only work for non array allocation and array of non pod)
16 #define LUG_NEW_ALIGN(T, alignment, ...) ::lug::System::Memory::new_one<T>(alignment, __FILE__, __LINE__, __VA_ARGS__)
17 #define LUG_NEW_ARRAY_ALIGN(T, alignment, ...) LUG_NEW_ARRAY_ALIGN_SIZE(typename std::remove_all_extents<T>::type, alignment, std::extent<T>::value, __VA_ARGS__)
18 #define LUG_NEW_ARRAY_ALIGN_SIZE(T, alignment, size, ...) ::lug::System::Memory::new_array<typename std::remove_all_extents<T>::type>(alignment, size, __FILE__, __LINE__, __VA_ARGS__)
19 
20 #define LUG_NEW(T, ...) LUG_NEW_ALIGN(T, alignof(T), __VA_ARGS__)
21 #define LUG_DELETE(object, arena) ::lug::System::Memory::delete_one(object, arena)
22 
23 #define LUG_NEW_ARRAY(T, ...) LUG_NEW_ARRAY_ALIGN(T, alignof(typename std::remove_all_extents<T>::type), __VA_ARGS__)
24 #define LUG_NEW_ARRAY_SIZE(T, size, ...) LUG_NEW_ARRAY_ALIGN_SIZE(T, alignof(typename std::remove_all_extents<T>::type), size, __VA_ARGS__)
25 #define LUG_DELETE_ARRAY(object, arena) ::lug::System::Memory::delete_array(object, arena)
26 
27 
28 namespace lug {
29 namespace System {
30 namespace Memory {
31 
32 template <typename T, class Arena, class ...Args>
33 T* new_one(size_t alignment, const char* file, size_t line, Arena& arena, Args&&... args);
34 
35 template <typename T, class Arena>
36 void delete_one(T* object, Arena& arena);
37 
38 template <typename T, class Arena, class ...Args, typename std::enable_if<!std::is_pod<T>::value, int>::type = 0>
39 T* new_array(size_t alignment, size_t nb, const char* file, size_t line, Arena& arena, Args&&... args);
40 
41 template <typename T, class Arena, typename std::enable_if<!std::is_pod<T>::value, int>::type = 0>
42 void delete_array(T* ptr, Arena& arena);
43 
44 template <typename T, class Arena, typename std::enable_if<std::is_pod<T>::value, int>::type = 0>
45 T* new_array(size_t alignment, size_t nb, const char* file, size_t line, Arena& arena);
46 
47 template <typename T, class Arena, class ...Args, typename std::enable_if<std::is_pod<T>::value, int>::type = 0>
48 T* new_array(size_t alignment, size_t nb, const char* file, size_t line, Arena& arena, Args&&... args) = delete;
49 
50 template <typename T, class Arena, typename std::enable_if<std::is_pod<T>::value, int>::type = 0>
51 void delete_array(T* ptr, Arena& arena);
52 
56 // unique_ptr
57 namespace priv {
58 
59 template <typename T>
60 struct make_unique_deleter {
61  using Deleter = std::function<void (T*)>;
62 };
63 
64 template <typename T>
65 struct make_unique_deleter<T[]> {
66  using Deleter = std::function<void (T*)>;
67 };
68 
69 template <typename T, size_t Count>
70 struct make_unique_deleter<T[Count]> {
71  using Deleter = std::function<void (T*)>;
72 };
73 
74 } // namespace priv
79 template<typename T, typename Deleter = typename priv::make_unique_deleter<T>::Deleter>
80 using unique_ptr = std::unique_ptr<T, Deleter>;
81 
85 namespace priv {
86 
87 template <typename T>
88 struct make_unique_if {
89  using SingleObject = lug::System::Memory::unique_ptr<T>;
90 };
91 
92 template <typename T>
93 struct make_unique_if<T[]> {
94  using UnknownBound = lug::System::Memory::unique_ptr<T[]>;
95 };
96 
97 template <typename T, size_t Count>
98 struct make_unique_if<T[Count]> {
99  using KnownBound = lug::System::Memory::unique_ptr<T[]>;
100 };
101 
102 } // namespace priv
107 // Single object
108 template <typename T, class Arena, typename ...Args>
109 typename priv::make_unique_if<T>::SingleObject make_unique(Arena& arena, Args&&... args);
110 
111 template <typename T, class Arena, typename ...Args>
112 typename priv::make_unique_if<T>::SingleObject make_unique_align(Arena& arena, size_t alignment, Args&&... args);
113 
114 // Dynamic array
115 template <typename T, class Arena, typename ...Args, typename std::enable_if<!std::is_pod<T>::value, int>::type = 0>
116 typename priv::make_unique_if<T>::UnknownBound make_unique(Arena& arena, size_t size, Args&&... args);
117 
118 template <typename T, class Arena, typename ...Args, typename std::enable_if<!std::is_pod<T>::value, int>::type = 0>
119 typename priv::make_unique_if<T>::UnknownBound make_unique_align(Arena& arena, size_t alignment, size_t size, Args&&... args);
120 
121 template <typename T, class Arena, typename std::enable_if<std::is_pod<T>::value, int>::type = 0>
122 typename priv::make_unique_if<T>::UnknownBound make_unique(Arena& arena, size_t size);
123 
124 template <typename T, class Arena, typename std::enable_if<std::is_pod<T>::value, int>::type = 0>
125 typename priv::make_unique_if<T>::UnknownBound make_unique_align(Arena& arena, size_t alignment, size_t size);
126 
127 template <typename T, class Arena, typename ...Args, typename std::enable_if<std::is_pod<T>::value, int>::type = 0>
128 typename priv::make_unique_if<T>::UnknownBound make_unique(Arena& arena, size_t size, Args&&... args) = delete;
129 
130 template <typename T, class Arena, typename ...Args, typename std::enable_if<std::is_pod<T>::value, int>::type = 0>
131 typename priv::make_unique_if<T>::UnknownBound make_unique_align(Arena& arena, size_t alignment, size_t size, Args&&... args) = delete;
132 
133 // Static array
134 template <typename T, class Arena, typename ...Args, typename std::enable_if<!std::is_pod<T>::value, int>::type = 0>
135 typename priv::make_unique_if<T>::KnownBound make_unique(Arena& arena, Args&&... args);
136 
137 template <typename T, class Arena, typename ...Args, typename std::enable_if<!std::is_pod<T>::value, int>::type = 0>
138 typename priv::make_unique_if<T>::KnownBound make_unique_align(Arena& arena, size_t alignment, Args&&... args);
139 
140 template <typename T, class Arena, typename std::enable_if<std::is_pod<T>::value, int>::type = 0>
141 typename priv::make_unique_if<T>::KnownBound make_unique(Arena& arena);
142 
143 template <typename T, class Arena, typename std::enable_if<std::is_pod<T>::value, int>::type = 0>
144 typename priv::make_unique_if<T>::KnownBound make_unique_align(Arena& arena, size_t alignment);
145 
146 template <typename T, class Arena, typename ...Args, typename std::enable_if<std::is_pod<T>::value, int>::type = 0>
147 typename priv::make_unique_if<T>::KnownBound make_unique(Arena& arena, Args&&... args) = delete;
148 
149 template <typename T, class Arena, typename ...Args, typename std::enable_if<std::is_pod<T>::value, int>::type = 0>
150 typename priv::make_unique_if<T>::KnownBound make_unique_align(Arena& arena, size_t alignment, Args&&... args) = delete;
151 
152 // TODO: Develop shared_ptr too
153 
154 #include <lug/System/Memory.inl>
155 
156 } // Memory
157 } // System
158 } // lug
void delete_array(T *ptr, Arena &arena)
priv::make_unique_if< T >::SingleObject make_unique_align(Arena &arena, size_t alignment, Args &&... args)
T * new_one(size_t alignment, const char *file, size_t line, Arena &arena, Args &&... args)
void delete_one(T *object, Arena &arena)
std::unique_ptr< T, Deleter > unique_ptr
Definition: Memory.hpp:80
priv::make_unique_if< T >::SingleObject make_unique(Arena &arena, Args &&... args)
T * new_array(size_t alignment, size_t nb, const char *file, size_t line, Arena &arena, Args &&... args)