CppCommon 1.0.5.0
C++ Common Library
Loading...
Searching...
No Matches
allocator.inl
Go to the documentation of this file.
1
9#if defined(_MSC_VER)
10#pragma warning(push)
11#pragma warning(disable: 4127) // C4127: conditional expression is constant
12#endif
13
14namespace CppCommon {
15
16template <typename T, typename U, class TMemoryManager, bool nothrow>
18{
19 return true;
20}
21
22template <typename T, typename U, class TMemoryManager, bool nothrow>
24{
25 return false;
26}
27
28template <typename T, class TMemoryManager, bool nothrow>
29inline T* Allocator<T, TMemoryManager, nothrow>::allocate(size_t num, const void* hint)
30{
31 pointer result = (pointer)_manager.malloc(num * sizeof(T), alignof(T));
32 if (result != nullptr)
33 return result;
34
35 // Not enough memory...
36 if (nothrow)
37 return nullptr;
38 else
39 throw std::bad_alloc();
40}
41
42template <typename T, class TMemoryManager, bool nothrow>
44{
45 _manager.free(ptr, num * sizeof(T));
46}
47
48template <typename T, class TMemoryManager, bool nothrow>
49template <typename U, class... Args>
50inline void Allocator<T, TMemoryManager, nothrow>::construct(U* ptr, Args&&... args)
51{
52 assert((ptr != nullptr) && "Constructed element must be valid!");
53
54 // Construct the element
55 if (ptr != nullptr)
56 new ((void*)ptr) U(std::forward<Args>(args)...);
57}
58
59template <typename T, class TMemoryManager, bool nothrow>
60template <typename U>
62{
63 assert((ptr != nullptr) && "Destroyed element must be valid!");
64
65 // Destroy the element
66 if (ptr != nullptr)
67 ptr->~U();
68}
69
70template <typename T, class TMemoryManager, bool nothrow>
71template <class... Args>
73{
74 // Allocate memory for the element
75 void* ptr = _manager.malloc(sizeof(T));
76
77 // Construct the element
78 if (ptr != nullptr)
79 new (ptr) T(std::forward<Args>(args)...);
80
81 return (T*)ptr;
82}
83
84template <typename T, class TMemoryManager, bool nothrow>
86{
87 assert((ptr != nullptr) && "Released element must be valid!");
88
89 // Release the element
90 if (ptr != nullptr)
91 {
92 // Destroy the element
93 ptr->~T();
94
95 // Free element memory
96 _manager.free(ptr, sizeof(T));
97 }
98}
99
100template <typename T, class TMemoryManager, bool nothrow>
101template <class... Args>
102inline T* Allocator<T, TMemoryManager, nothrow>::CreateArray(size_t length, Args&&... args)
103{
104 assert((length > 0) && "Array length must be greater than zero!");
105
106 size_t header = sizeof(size_t) / sizeof(T);
107 if ((sizeof(size_t) % sizeof(T)) > 0)
108 header += 1;
109
110 // Allocate extra space to store array length in the bytes before the array
111 T* ptr = ((T*)_manager.malloc(sizeof(T) * (length + header), alignof(T))) + header;
112
113 // Store the array length value
114 *(((size_t*)ptr) - 1) = length;
115
116 // Construct array elements
117 for (size_t i = 0; i < length; ++i)
118 new (&ptr[i]) T(std::forward<Args>(args)...);
119
120 return ptr;
121}
122
123template <typename T, class TMemoryManager, bool nothrow>
125{
126 assert((ptr != nullptr) && "Released array must be valid!");
127
128 // Release the array
129 if (ptr != nullptr)
130 {
131 // Get the length of the array
132 size_t length = *(((size_t*)ptr) - 1);
133
134 // Destroy array elements
135 for(size_t i = 0; i < length; ++i)
136 ptr[i].~T();
137
138 // Calculate how much extra memory was allocated to store the length before the array
139 size_t header = sizeof(size_t) / sizeof(T);
140 if ((sizeof(size_t) % sizeof(T)) > 0)
141 header += 1;
142
143 // Free array memory
144 _manager.free(ptr - header, sizeof(T) * (length + header));
145 }
146}
147
148inline void* DefaultMemoryManager::malloc(size_t size, size_t alignment)
149{
150 assert((size > 0) && "Allocated block size must be greater than zero!");
151 assert(Memory::IsValidAlignment(alignment) && "Alignment must be valid!");
152
153 void* result = std::malloc(size);
154 if (result != nullptr)
155 {
156 // Update allocation statistics
157 _allocated += size;
158 ++_allocations;
159 }
160 return result;
161}
162
163inline void DefaultMemoryManager::free(void* ptr, size_t size)
164{
165 assert((ptr != nullptr) && "Deallocated block must be valid!");
166
167 if (ptr != nullptr)
168 {
169 std::free(ptr);
170
171 // Update allocation statistics
172 _allocated -= size;
173 --_allocations;
174 }
175}
176
178{
179 assert((_allocated == 0) && "Memory leak detected! Allocated memory size must be zero!");
180 assert((_allocations == 0) && "Memory leak detected! Count of active memory allocations must be zero!");
181}
182
183} // namespace CppCommon
184
185#if defined(_MSC_VER)
186#pragma warning(pop)
187#endif
Memory allocator class.
Definition allocator.h:25
void construct(U *ptr, Args &&... args)
Constructs an element object on the given location pointer.
Definition allocator.inl:50
void ReleaseArray(T *ptr)
Release an array of element objects.
void Release(T *ptr)
Release a single element object.
Definition allocator.inl:85
T * CreateArray(size_t length, Args &&... args)
Create an array of element objects.
void deallocate(pointer ptr, size_type num)
Release a block of storage previously allocated.
Definition allocator.inl:43
T * Create(Args &&... args)
Create a single element object.
Definition allocator.inl:72
T * pointer
Pointer to element.
Definition allocator.h:33
pointer allocate(size_type num, const void *hint=0)
Allocate a block of storage suitable to contain the given count of elements.
Definition allocator.inl:29
void destroy(U *ptr)
Destroys in-place the object pointed by the given location pointer.
Definition allocator.inl:61
void free(void *ptr, size_t size)
Free the previously allocated memory block.
void reset()
Reset the memory manager.
void * malloc(size_t size, size_t alignment=alignof(std::max_align_t))
Allocate a new memory block of the given size.
static bool IsValidAlignment(size_t alignment) noexcept
Is the given alignment valid?
Definition memory.inl:13
C++ Common project definitions.
bool operator==(const uint128_t &value1, const uint128_t &value2) noexcept
Definition uint128.inl:115
bool operator!=(const uint128_t &value1, const uint128_t &value2) noexcept
Definition uint128.inl:120