Yet more work on eng::malloc
This commit is contained in:
@@ -13,27 +13,27 @@
|
||||
// In order to get all engine data structures into the eng::malloc heap, you
|
||||
// need to jump through quite a few hoops:
|
||||
//
|
||||
// * When using STL classes, you need to use the 'eng' variant of those classes:
|
||||
// * When writing a class, always derive from eng::opnew. This adds a
|
||||
// custom operator new to your class, which causes your class to be
|
||||
// allocated using eng::malloc.
|
||||
//
|
||||
// - eng::string instead of std::string (include "wrap-string.hpp")
|
||||
// - eng::vector instead of std::vector (include "wrap-vector.hpp")
|
||||
// - eng::map instead of std::map (include "wrap-map.hpp")
|
||||
// - etc.
|
||||
// * When using STL containers, you need to use the eng variant:
|
||||
// eng::map, eng::set, eng::vector, eng::unordered_map, eng::unordered_set,
|
||||
// and eng::deque. These classes derive from eng::opnew, and they also
|
||||
// use eng::malloc for their internal nodes.
|
||||
//
|
||||
// These eng classes allocate memory using eng::malloc instead of malloc.
|
||||
//
|
||||
// * All your classes must derive from eng::opnew. This adds a custom operator
|
||||
// new and operator delete to your class, which allocate using eng::malloc.
|
||||
//
|
||||
// * Use eng::make_shared and eng::make_unique instead of std::make_shared and
|
||||
// std::make_unique.
|
||||
// * Use eng::string instead of std::string. Use eng::ostringstream
|
||||
// instead of std::ostringstream.
|
||||
//
|
||||
// * Simple classes like std::pair, std::string_view, std::less, std::hash, and
|
||||
// so forth don't allocate memory. Those classes are not wrapped. There is
|
||||
// no eng::pair, eng::less, etc.
|
||||
// so forth are not wrapped. Do not use operator new or delete on
|
||||
// these classes.
|
||||
//
|
||||
// * Instead of std::make_shared, use eng::make_shared. You need this
|
||||
// because std::make_shared doesn't respect your custom operator new.
|
||||
//
|
||||
// * Be aware that most C++ streams use the system malloc heap, and there's no
|
||||
// way to change that. Fortunately, eng::ostringstream uses the dlmalloc
|
||||
// way to change that. Fortunately, eng::ostringstream uses the eng::malloc
|
||||
// heap.
|
||||
//
|
||||
// * Failing to jump through all these hoops won't break your code in any
|
||||
@@ -46,6 +46,7 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
namespace eng {
|
||||
#ifdef __linux__
|
||||
@@ -126,21 +127,60 @@ namespace eng {
|
||||
{
|
||||
return ::eng::free(p);
|
||||
}
|
||||
|
||||
void *operator new[](size_t size)
|
||||
{
|
||||
return ::eng::malloc(size);
|
||||
}
|
||||
|
||||
void operator delete[](void *p, size_t size)
|
||||
{
|
||||
return ::eng::free(p);
|
||||
}
|
||||
};
|
||||
} // namespace eng
|
||||
|
||||
// eng::nevernew. A class containing private operator new and
|
||||
// operator delete, making it impossible to 'new' the class.
|
||||
namespace eng {
|
||||
class nevernew {
|
||||
private:
|
||||
void *operator new(size_t size)
|
||||
{
|
||||
assert(false && "not supposed to 'new' this class");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void operator delete(void *p, size_t size)
|
||||
{
|
||||
assert(false && "not supposed to 'delete' this class");
|
||||
}
|
||||
|
||||
void *operator new[](size_t size)
|
||||
{
|
||||
assert(false && "not supposed to 'new' this class");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void operator delete[](void *p, size_t size)
|
||||
{
|
||||
assert(false && "not supposed to 'delete' this class");
|
||||
}
|
||||
};
|
||||
} // namespace eng
|
||||
|
||||
|
||||
// eng::make_shared allocates shared objects using eng::malloc.
|
||||
namespace eng {
|
||||
template<class T, class... Args>
|
||||
inline ::std::shared_ptr<T> make_shared(Args&&... args) {
|
||||
static eng::allocator<T> alloc;
|
||||
return std::allocate_shared<T>(alloc, args...);
|
||||
return std::allocate_shared<T>(eng::allocator<T>(), args...);
|
||||
}
|
||||
}
|
||||
} // namespace eng
|
||||
|
||||
// eng::make_unique doesn't do anything different than std::make_unique:
|
||||
// they both use operator new and delete. You must
|
||||
// derive from eng::opnew to change operator new and delete.
|
||||
// eng::make_unique doesn't do anything different than std::make_unique: they
|
||||
// both use operator new and delete. You must derive from eng::opnew to change
|
||||
// operator new and delete.
|
||||
namespace eng {
|
||||
template<class T, class... Args>
|
||||
inline ::std::unique_ptr<T> make_unique(Args&&... args) {
|
||||
|
||||
Reference in New Issue
Block a user