Files
test/intern/memutil/MEM_Allocator.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

79 lines
1.7 KiB
C
Raw Normal View History

/* SPDX-FileCopyrightText: 2006-2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup intern_memutil
2011-02-25 11:47:18 +00:00
*/
#ifndef __MEM_ALLOCATOR_H__
#define __MEM_ALLOCATOR_H__
#include "guardedalloc/MEM_guardedalloc.h"
#include <cstddef>
template<typename _Tp> struct MEM_Allocator {
using size_type = size_t;
using difference_type = ptrdiff_t;
using pointer = _Tp *;
using const_pointer = const _Tp *;
using reference = _Tp &;
using const_reference = const _Tp &;
using value_type = _Tp;
template<typename _Tp1> struct rebind {
using other = MEM_Allocator<_Tp1>;
};
MEM_Allocator() noexcept = default;
MEM_Allocator(const MEM_Allocator & /*other*/) noexcept = default;
template<typename _Tp1> MEM_Allocator(const MEM_Allocator<_Tp1> /*other*/) noexcept {}
~MEM_Allocator() noexcept = default;
pointer address(reference __x) const
{
return &__x;
}
const_pointer address(const_reference __x) const
{
return &__x;
}
/* NOTE: `__n` is permitted to be 0.
* The C++ standard says nothing about what the return value is when `__n == 0`. */
_Tp *allocate(size_type __n, const void * /*unused*/ = nullptr)
{
2013-03-08 06:32:00 +00:00
_Tp *__ret = NULL;
2023-09-24 14:52:38 +10:00
if (__n) {
__ret = static_cast<_Tp *>(MEM_mallocN(__n * sizeof(_Tp), "STL MEM_Allocator"));
2023-09-24 14:52:38 +10:00
}
return __ret;
}
// __p is not permitted to be a null pointer.
void deallocate(pointer __p, size_type /*unused*/)
2012-06-04 20:11:09 +00:00
{
MEM_guardedalloc: Refactor to add more type-safety. The main goal of these changes are to improve static (i.e. build-time) checks on whether a given data can be allocated and freed with `malloc` and `free` (C-style), or requires proper C++-style construction and destruction (`new` and `delete`). * Add new `MEM_malloc_arrayN_aligned` API. * Make `MEM_freeN` a template function in C++, which does static assert on type triviality. * Add `MEM_SAFE_DELETE`, similar to `MEM_SAFE_FREE` but calling `MEM_delete`. The changes to `MEM_freeN` was painful and useful, as it allowed to fix a bunch of invalid calls in existing codebase already. It also highlighted a fair amount of places where it is called to free incomplete type pointers, which is likely a sign of badly designed code (there should rather be an API to destroy and free these data then, if the data type is not fully publicly exposed). For now, these are 'worked around' by explicitly casting the freed pointers to `void *` in these cases - which also makes them easy to search for. Some of these will be addressed separately (see blender/blender!134765). Finally, MSVC seems to consider structs defining new/delete operators (e.g. by using the `MEM_CXX_CLASS_ALLOC_FUNCS` macro) as non-trivial. This does not seem to follow the definition of type triviality, so for now static type checking in `MEM_freeN` has been disabled for Windows. We'll likely have to do the same with type-safe `MEM_[cm]allocN` API being worked on in blender/blender!134771 Based on ideas from Brecht in blender/blender!134452 Pull Request: https://projects.blender.org/blender/blender/pulls/134463
2025-02-20 10:37:10 +01:00
MEM_freeN(static_cast<void *>(__p));
}
size_type max_size() const noexcept
{
return size_t(-1) / sizeof(_Tp);
}
void construct(pointer __p, const _Tp &__val)
{
new (__p) _Tp(__val);
}
void destroy(pointer __p)
{
__p->~_Tp();
}
};
#endif // __MEM_ALLOCATOR_H__