Zth (libzth)
Loading...
Searching...
No Matches
allocator.h
Go to the documentation of this file.
1#ifndef ZTH_ALLOCATOR_H
2#define ZTH_ALLOCATOR_H
3/*
4 * SPDX-FileCopyrightText: 2019-2026 Jochem Rutgers
5 *
6 * SPDX-License-Identifier: MPL-2.0
7 */
8
9#include <libzth/macros.h>
10
11#ifdef __cplusplus
12
13# include <libzth/config.h>
14# include <libzth/util.h>
15
16# include <exception>
17# include <list>
18# include <map>
19# include <set>
20# include <string>
21# include <vector>
22
23namespace zth {
24
25# ifdef NDEBUG
26# define ZTH_MALLOC_INLINE inline
27# define ZTH_MALLOC_ATTR(attr)
28# else
29# define ZTH_MALLOC_INLINE __attribute__((noinline))
30# if !defined(__clang_analyzer__) && GCC_VERSION >= 110000L
31# define ZTH_MALLOC_ATTR(attr) __attribute__(attr)
32# else
33# define ZTH_MALLOC_ATTR(attr) __attribute__((malloc))
34# endif
35# endif
36
41template <typename T>
42static ZTH_MALLOC_INLINE void deallocate(T* p, size_t n = 1) noexcept
43{
44 if(!p)
45 return;
46
47 typename Config::Allocator<T>::type allocator;
48 allocator.deallocate(p, n);
49}
50
51template <typename T>
52static ZTH_MALLOC_INLINE void delete_alloc(T* p) noexcept
53{
54 if(unlikely(!p))
55 return;
56
57 p->~T();
58 deallocate(p);
59}
60
65template <typename T>
66__attribute__((warn_unused_result, returns_nonnull)) ZTH_MALLOC_ATTR(
67 (malloc((void (*)(T*, size_t) noexcept)deallocate, 1),
68 alloc_size(1))) static ZTH_MALLOC_INLINE T* allocate(size_t n = 1)
69{
70 typename Config::Allocator<T>::type allocator;
71 return allocator.allocate(n);
72}
73
82template <typename T>
83__attribute__((warn_unused_result)) ZTH_MALLOC_ATTR(
84 (malloc((void (*)(T*, size_t) noexcept)deallocate, 1),
85 alloc_size(1))) static ZTH_MALLOC_INLINE T* allocate_noexcept(size_t n = 1) noexcept
86{
87 try {
88 return allocate<T>(n);
89 } catch(std::bad_alloc const&) {
90 return nullptr;
91 } catch(...) {
93 }
94
95 // Should not get here.
96 return nullptr;
97}
98
99template <typename T>
100__attribute__((warn_unused_result, returns_nonnull)) ZTH_MALLOC_ATTR(
101 (malloc((void (*)(T*) noexcept)delete_alloc))) static ZTH_MALLOC_INLINE T* new_alloc()
102{
103 T* o = allocate<T>();
104 try {
105 new(o) T;
106 return o;
107 } catch(...) {
108 deallocate(o);
109 zth_throw();
110 } // cppcheck-suppress missingReturn
111
112 // Should not get here.
113}
114
115template <typename T, typename Arg>
116__attribute__((warn_unused_result, returns_nonnull)) ZTH_MALLOC_ATTR((malloc(
117 (void (*)(T*) noexcept)delete_alloc))) static ZTH_MALLOC_INLINE T* new_alloc(Arg const& arg)
118{
119 T* o = allocate<T>();
120 try {
121 new(o) T(arg);
122 return o;
123 } catch(...) {
124 deallocate(o);
125 zth_throw();
126 } // cppcheck-suppress missingReturn
127
128 // Should not get here.
129}
130
131# if __cplusplus >= 201103L
132template <typename T, typename... Arg>
133__attribute__((warn_unused_result, returns_nonnull)) ZTH_MALLOC_ATTR((malloc(
134 (void (*)(T*) noexcept)delete_alloc))) static ZTH_MALLOC_INLINE T* new_alloc(Arg&&... arg)
135{
136 T* o = allocate<T>();
137 try {
138 new(o) T{std::forward<Arg>(arg)...};
139 return o;
140 } catch(...) {
141 deallocate(o);
142 zth_throw();
143 } // cppcheck-suppress missingReturn
144
145 // Should not get here.
146}
147# endif
148
159// cppcheck-suppress-macro duplInheritedMember
160# define ZTH_CLASS_NEW_DELETE(T) \
161 public: \
162 static ZTH_MALLOC_INLINE void operator delete(void* ptr) noexcept \
163 { \
164 ::zth::deallocate<T>(static_cast<T*>(ptr)); \
165 } \
166 ZTH_MALLOC_ATTR((malloc, alloc_size(1))) \
167 __attribute__((warn_unused_result, returns_nonnull)) static ZTH_MALLOC_INLINE void* \
168 operator new(std::size_t UNUSED_PAR(n)) \
169 { \
170 zth_assert(n == sizeof(T)); \
171 return ::zth::allocate<T>(); \
172 } \
173 static ZTH_MALLOC_INLINE void operator delete[](void* ptr, size_t sz) noexcept \
174 { \
175 zth_assert(sz % sizeof(T) == 0); \
176 ::zth::deallocate<T>(static_cast<T*>(ptr), sz / sizeof(T)); \
177 } \
178 ZTH_MALLOC_ATTR((malloc, alloc_size(1))) \
179 __attribute__((warn_unused_result, returns_nonnull)) static ZTH_MALLOC_INLINE void* \
180 operator new[](std::size_t sz) \
181 { \
182 zth_assert(sz % sizeof(T) == 0); \
183 return ::zth::allocate<T>(sz / sizeof(T)); \
184 } \
185 typedef typename zth::Config::Allocator<T>::type allocator_type; /* NOLINT */ \
186 \
187 private:
188
193template <typename T>
195 typedef std::vector<T, typename Config::Allocator<T>::type> type;
196};
197
202template <typename Key, typename T, typename Compare = std::less<Key> >
203struct map_type {
204 typedef std::map<
205 Key, T, Compare, typename Config::Allocator<std::pair<const Key, T> >::type>
207};
208
213template <typename Key, typename Compare = std::less<Key> >
214struct set_type {
215 typedef std::set<Key, Compare, typename Config::Allocator<Key>::type> type;
216};
217
222template <typename T>
223struct list_type {
224 typedef std::list<T, typename Config::Allocator<T>::type> type;
225};
226
227template <typename Traits, typename Allocator>
228string to_zth_string(std::basic_string<char, Traits, Allocator> const& s)
229{
230 return string(s.data(), s.size());
231}
232
233inline std::string to_std_string(string const& s)
234{
235 return std::string(s.data(), s.size());
236}
237
238} // namespace zth
239#endif // __cplusplus
240#endif // ZTH_ALLOCATOR_H
#define ZTH_MALLOC_ATTR(attr)
Definition allocator.h:33
#define ZTH_MALLOC_INLINE
Definition allocator.h:29
std::basic_string< char, std::char_traits< char >, Config::Allocator< char >::type > string
std::string type using Config::Allocator::type.
Definition util.h:330
#define zth_throw(...)
Definition macros.h:376
std::string to_std_string(string const &s)
Definition allocator.h:233
string to_zth_string(std::basic_string< char, Traits, Allocator > const &s)
Definition allocator.h:228
std::list type using Config::Allocator::type.
Definition allocator.h:223
std::list< T, typename Config::Allocator< T >::type > type
Definition allocator.h:224
std::map type using Config::Allocator::type.
Definition allocator.h:203
std::map< Key, T, Compare, typename Config::Allocator< std::pair< const Key, T > >::type > type
Definition allocator.h:206
std::map type using Config::Allocator::type.
Definition allocator.h:214
std::set< Key, Compare, typename Config::Allocator< Key >::type > type
Definition allocator.h:215
std::vector type using Config::Allocator::type.
Definition allocator.h:194
std::vector< T, typename Config::Allocator< T >::type > type
Definition allocator.h:195
#define unlikely(expr)
Marks the given expression to likely be evaluated to true.
Definition util.h:60
void zth_terminate()
Terminate immediately.