diff --git a/include/mimalloc.h b/include/mimalloc.h index 59f394a7..65e98d5d 100644 --- a/include/mimalloc.h +++ b/include/mimalloc.h @@ -332,36 +332,25 @@ mi_decl_export void* mi_new_nothrow(size_t n) mi_attr_malloc mi_attr_alloc_size( mi_decl_export void* mi_new_aligned_nothrow(size_t n, size_t alignment) mi_attr_malloc mi_attr_alloc_size(1); #ifdef __cplusplus +void* mi_new_n(size_t count, size_t size) mi_attr_malloc mi_attr_alloc_size2(1,2); + } #endif // --------------------------------------------------------------------------------------------- -// Implement the C++ std::allocator interface for use in STL containers. +// Implement the C++11 std::allocator interface for use in STL containers. // (note: see `mimalloc-new-delete.h` for overriding the new/delete operators globally) // --------------------------------------------------------------------------------------------- -#ifdef __cplusplus - -#if (__cplusplus >= 201103L) || (_MSC_VER > 1900) // C++11 -#include // true_type -#endif - +#if defined(__cplusplus) && (__cplusplus >= 201103L || _MSC_VER > 1900) // C++11 template struct mi_stl_allocator { typedef T value_type; -#if (__cplusplus >= 201103L) || (_MSC_VER > 1900) // C++11 - using propagate_on_container_copy_assignment = std::true_type; - using propagate_on_container_move_assignment = std::true_type; - using propagate_on_container_swap = std::true_type; - using is_always_equal = std::true_type; -#endif - mi_stl_allocator() mi_attr_noexcept {} - mi_stl_allocator(const mi_stl_allocator& other) mi_attr_noexcept { (void)other; } - template mi_stl_allocator(const mi_stl_allocator& other) mi_attr_noexcept { (void)other; } - T* allocate(size_t n, const void* hint = 0) { (void)hint; return (T*)mi_mallocn(n, sizeof(T)); } - void deallocate(T* p, size_t n) { mi_free_size(p,n); } + mi_stl_allocator() = default; + template mi_stl_allocator(const mi_stl_allocator&) mi_attr_noexcept {} + T* allocate(size_t n) { return static_cast(mi_new_n(n, sizeof(T))); } + void deallocate(T* p, size_t n) { mi_free_size(p,n); } }; - -template bool operator==(const mi_stl_allocator& lhs, const mi_stl_allocator& rhs) mi_attr_noexcept { (void)lhs; (void)rhs; return true; } -template bool operator!=(const mi_stl_allocator& lhs, const mi_stl_allocator& rhs) mi_attr_noexcept { (void)lhs; (void)rhs; return false; } -#endif // __cplusplus +template bool operator==(const mi_stl_allocator&, const mi_stl_allocator&) mi_attr_noexcept { return true; } +template bool operator!=(const mi_stl_allocator&, const mi_stl_allocator&) mi_attr_noexcept { return false; } +#endif // C++11 #endif diff --git a/src/alloc.c b/src/alloc.c index d66c629b..25a455f3 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -644,6 +644,11 @@ static bool mi_try_new_handler(bool nothrow) { return true; } } +void* mi_new_n(size_t count, size_t size) { + size_t total; + if (mi_mul_overflow(count, size, &total)) throw std::bad_alloc(); + return mi_new(total); +} #else #include #ifndef ENOMEM