memory_manager_internal.h (3312B)
1 // Copyright (c) the JPEG XL Project Authors. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 #ifndef LIB_JXL_MEMORY_MANAGER_INTERNAL_H_ 7 #define LIB_JXL_MEMORY_MANAGER_INTERNAL_H_ 8 9 // Memory allocator with support for alignment + misalignment. 10 11 #include <jxl/memory_manager.h> 12 #include <stddef.h> 13 #include <stdlib.h> 14 #include <string.h> // memcpy 15 16 #include <memory> 17 18 #include "lib/jxl/base/compiler_specific.h" 19 #include "lib/jxl/base/status.h" 20 21 namespace jxl { 22 23 // Default alloc and free functions. 24 void* MemoryManagerDefaultAlloc(void* opaque, size_t size); 25 void MemoryManagerDefaultFree(void* opaque, void* address); 26 27 // Initializes the memory manager instance with the passed one. The 28 // MemoryManager passed in |memory_manager| may be NULL or contain NULL 29 // functions which will be initialized with the default ones. If either alloc 30 // or free are NULL, then both must be NULL, otherwise this function returns an 31 // error. 32 static JXL_INLINE Status MemoryManagerInit( 33 JxlMemoryManager* self, const JxlMemoryManager* memory_manager) { 34 if (memory_manager) { 35 *self = *memory_manager; 36 } else { 37 memset(self, 0, sizeof(*self)); 38 } 39 bool is_default_alloc = (self->alloc == nullptr); 40 bool is_default_free = (self->free == nullptr); 41 if (is_default_alloc != is_default_free) { 42 return false; 43 } 44 if (is_default_alloc) self->alloc = jxl::MemoryManagerDefaultAlloc; 45 if (is_default_free) self->free = jxl::MemoryManagerDefaultFree; 46 47 return true; 48 } 49 50 static JXL_INLINE void* MemoryManagerAlloc( 51 const JxlMemoryManager* memory_manager, size_t size) { 52 return memory_manager->alloc(memory_manager->opaque, size); 53 } 54 55 static JXL_INLINE void MemoryManagerFree(const JxlMemoryManager* memory_manager, 56 void* address) { 57 memory_manager->free(memory_manager->opaque, address); 58 } 59 60 // Helper class to be used as a deleter in a unique_ptr<T> call. 61 class MemoryManagerDeleteHelper { 62 public: 63 explicit MemoryManagerDeleteHelper(const JxlMemoryManager* memory_manager) 64 : memory_manager_(memory_manager) {} 65 66 // Delete and free the passed pointer using the memory_manager. 67 template <typename T> 68 void operator()(T* address) const { 69 if (!address) { 70 return; 71 } 72 address->~T(); 73 return memory_manager_->free(memory_manager_->opaque, address); 74 } 75 76 private: 77 const JxlMemoryManager* memory_manager_; 78 }; 79 80 template <typename T> 81 using MemoryManagerUniquePtr = std::unique_ptr<T, MemoryManagerDeleteHelper>; 82 83 // Creates a new object T allocating it with the memory allocator into a 84 // unique_ptr. 85 template <typename T, typename... Args> 86 JXL_INLINE MemoryManagerUniquePtr<T> MemoryManagerMakeUnique( 87 const JxlMemoryManager* memory_manager, Args&&... args) { 88 T* mem = 89 static_cast<T*>(memory_manager->alloc(memory_manager->opaque, sizeof(T))); 90 if (!mem) { 91 // Allocation error case. 92 return MemoryManagerUniquePtr<T>(nullptr, 93 MemoryManagerDeleteHelper(memory_manager)); 94 } 95 return MemoryManagerUniquePtr<T>(new (mem) T(std::forward<Args>(args)...), 96 MemoryManagerDeleteHelper(memory_manager)); 97 } 98 99 } // namespace jxl 100 101 #endif // LIB_JXL_MEMORY_MANAGER_INTERNAL_H_