25#define MOCHI_HAS_MEMORY_RESOURCE 1
26#define MOCHI_HAS_EXPERIMENTAL_MEMORY_RESOURCE 0
27#define MOCHI_HAS_PMR_NEW_DELETE_RESOURCE 1
30#if defined(__APPLE__) && defined(__clang_major__) && !defined(__cpp_lib_memory_resource)
31#if __clang_major__ < 15
32#undef MOCHI_HAS_MEMORY_RESOURCE
33#define MOCHI_HAS_MEMORY_RESOURCE 0
34#undef MOCHI_HAS_PMR_NEW_DELETE_RESOURCE
35#define MOCHI_HAS_PMR_NEW_DELETE_RESOURCE 0
36#undef MOCHI_HAS_EXPERIMENTAL_MEMORY_RESOURCE
37#define MOCHI_HAS_EXPERIMENTAL_MEMORY_RESOURCE 1
44#undef MOCHI_HAS_MEMORY_RESOURCE
45#define MOCHI_HAS_MEMORY_RESOURCE 0
46#undef MOCHI_HAS_PMR_NEW_DELETE_RESOURCE
47#define MOCHI_HAS_PMR_NEW_DELETE_RESOURCE 0
48#undef MOCHI_HAS_EXPERIMENTAL_MEMORY_RESOURCE
49#define MOCHI_HAS_EXPERIMENTAL_MEMORY_RESOURCE 0
55#if MOCHI_PLATFORM_ANDROID
56#undef MOCHI_HAS_MEMORY_RESOURCE
57#define MOCHI_HAS_MEMORY_RESOURCE 0
58#undef MOCHI_HAS_PMR_NEW_DELETE_RESOURCE
59#define MOCHI_HAS_PMR_NEW_DELETE_RESOURCE 0
60#undef MOCHI_HAS_EXPERIMENTAL_MEMORY_RESOURCE
61#define MOCHI_HAS_EXPERIMENTAL_MEMORY_RESOURCE 0
64#if MOCHI_HAS_MEMORY_RESOURCE
65#include <memory_resource>
66#elif MOCHI_HAS_EXPERIMENTAL_MEMORY_RESOURCE
67#include <experimental/memory_resource>
76#if MOCHI_ALLOCATOR_DEBUG
78#define MOCHI_ALLOCATOR_ASSERT(condition_without_side_effects, ...) \
79 MOCHI_ASSERT(condition_without_side_effects __VA_OPT__(, )##__VA_ARGS__)
84#define MOCHI_ALLOCATOR_ASSERT(condition_without_side_effects, ...) \
85 MOCHI_ASSERT(condition_without_side_effects, ##__VA_ARGS__)
88#define MOCHI_ALLOCATOR_ASSERT(...)
99 ptr !=
nullptr || sizeInBytes == 0,
"Allocation failed without throwing an exception");
101 !(
reinterpret_cast<intptr_t
>(ptr) & (alignment - 1)),
102 "Address does not have the requested alignment of %zu bytes",
110 !(
reinterpret_cast<intptr_t
>(ptr) & (alignment - 1)),
111 "Address does not have the stated alignment");
123inline void* DefaultAllocator::do_allocate(
size_t sizeInBytes,
size_t alignment) {
124#if MOCHI_PMR_USES_JEMALLOC
136 sizeInBytes =
Max(sizeInBytes,
size_t(16));
139#if MOCHI_HAS_MEMORY_RESOURCE && MOCHI_HAS_PMR_NEW_DELETE_RESOURCE
140 return std::pmr::new_delete_resource()->allocate(sizeInBytes, alignment);
141#elif MOCHI_HAS_EXPERIMENTAL_MEMORY_RESOURCE && MOCHI_HAS_PMR_NEW_DELETE_RESOURCE
142 return std::experimental::pmr::new_delete_resource()->allocate(sizeInBytes, alignment);
143#elif defined(__cpp_lib_aligned_alloc)
145 if (alignment <= 16) {
146 return std::malloc(sizeInBytes);
148 return std::aligned_alloc(alignment, sizeInBytes);
152 if (alignment <= 8) {
153 return malloc(sizeInBytes);
156 posix_memalign(&ptr, alignment, sizeInBytes);
162inline void DefaultAllocator::do_deallocate(
164 [[maybe_unused]]
size_t sizeInBytes,
165 [[maybe_unused]]
size_t alignment) {
166#if MOCHI_PMR_USES_JEMALLOC
168 sizeInBytes =
Max(sizeInBytes,
size_t(16));
171#if MOCHI_HAS_MEMORY_RESOURCE && MOCHI_HAS_PMR_NEW_DELETE_RESOURCE
172 return std::pmr::new_delete_resource()->deallocate(ptr, sizeInBytes, alignment);
173#elif MOCHI_HAS_EXPERIMENTAL_MEMORY_RESOURCE && MOCHI_HAS_PMR_NEW_DELETE_RESOURCE
174 return std::experimental::pmr::new_delete_resource()->deallocate(ptr, sizeInBytes, alignment);
175#elif defined(__cpp_lib_aligned_alloc)
182inline bool DefaultAllocator::do_is_equal(
Allocator const& other)
const noexcept {
189 return (&other ==
this);
#define MOCHI_ALLOCATOR_ASSERT(condition_without_side_effects,...)
Virtual interface class for memory allocation and deallocation.
virtual void do_deallocate(void *ptr, std::size_t sizeInBytes, std::size_t alignment)=0
void * allocate(std::size_t sizeInBytes, std::size_t alignment=alignof(std::max_align_t))
Allocate memory of the specified size and alignment.
void deallocate(void *ptr, std::size_t sizeInBytes, std::size_t alignment=alignof(std::max_align_t))
Deallocate a block of memory that was previously allocated by this Allocator instance or by a compati...
virtual void * do_allocate(std::size_t sizeInBytes, std::size_t alignment)=0
virtual bool do_is_equal(Allocator const &other) const noexcept=0
bool is_equal(Allocator const &other) const noexcept
Return true if memory allocated by this Allocator instance can be deallocated by the other Allocator ...
Mochi's default implementation of the Allocator interface.
constexpr bool IsPowerOfTwo(T a)
Allocator * GetDefaultAllocator()
Get an instance of the DefaultAllocator class.
constexpr T const & Max(T const &a, T const &b)