Yet more work on eng::malloc
This commit is contained in:
@@ -9,8 +9,6 @@ grep std::unordered_set cpp/*
|
||||
grep std::deque cpp/*
|
||||
grep std::ostringstream cpp/*
|
||||
grep std::ostream cpp/*
|
||||
grep std::unique_ptr cpp/*
|
||||
grep std::shared_ptr cpp/*
|
||||
|
||||
grep std::cerr cpp/*
|
||||
grep std::cout cpp/*
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
#include <cassert>
|
||||
#include <ostream>
|
||||
|
||||
class AnimStep {
|
||||
class AnimStep : public eng::nevernew {
|
||||
friend class AnimQueue;
|
||||
public:
|
||||
enum {
|
||||
@@ -166,7 +166,7 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class AnimQueue {
|
||||
class AnimQueue : public eng::nevernew {
|
||||
public:
|
||||
// World type determines whether versions increment or autozero
|
||||
AnimQueue(util::WorldType wt);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <ostream>
|
||||
#include <memory>
|
||||
|
||||
class DebugCollector {
|
||||
class DebugCollector : public eng::nevernew {
|
||||
private:
|
||||
// At any given time, the stringstream may contain one
|
||||
// extra line that hasn't yet been appended to the list of lines.
|
||||
@@ -33,7 +33,7 @@ public:
|
||||
friend class DebugBlock;
|
||||
};
|
||||
|
||||
class DebugBlock {
|
||||
class DebugBlock : public eng::nevernew {
|
||||
private:
|
||||
DebugCollector *dbc_;
|
||||
int n_regular_;
|
||||
|
||||
@@ -106,7 +106,7 @@ class DrivenEngine;
|
||||
using UniqueDrivenEngine = std::unique_ptr<DrivenEngine>;
|
||||
using DrivenEngineMaker = UniqueDrivenEngine (*)();
|
||||
|
||||
class Channel {
|
||||
class Channel : public eng::opnew {
|
||||
public:
|
||||
// Get the buffers associated with this channel.
|
||||
//
|
||||
@@ -190,7 +190,7 @@ private:
|
||||
|
||||
using SharedChannel = std::shared_ptr<Channel>;
|
||||
|
||||
class DrivenEngine {
|
||||
class DrivenEngine : public eng::opnew {
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "luastack.hpp"
|
||||
#include "streambuffer.hpp"
|
||||
|
||||
class GuiElt {
|
||||
class GuiElt : public eng::nevernew {
|
||||
friend class Gui;
|
||||
public:
|
||||
enum Type {
|
||||
@@ -27,7 +27,7 @@ public:
|
||||
const eng::string &label() const { return label_; }
|
||||
};
|
||||
|
||||
class Gui {
|
||||
class Gui : public eng::nevernew {
|
||||
public:
|
||||
using EltVec = eng::vector<GuiElt>;
|
||||
private:
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
#include <cstdint>
|
||||
#include <ostream>
|
||||
|
||||
class IdGlobalPool {
|
||||
class IdGlobalPool : public eng::nevernew {
|
||||
public:
|
||||
// Construct and destroy global pools. Note that after constructing
|
||||
// a global pool, it is generally also necessary to initialize it
|
||||
@@ -119,7 +119,7 @@ private:
|
||||
friend int unittests_idalloc(lua_State *L);
|
||||
};
|
||||
|
||||
class IdPlayerPool {
|
||||
class IdPlayerPool : public eng::nevernew {
|
||||
public:
|
||||
// Construct a player pool.
|
||||
//
|
||||
|
||||
@@ -16,7 +16,7 @@ public:
|
||||
void deserialize(StreamBuffer *sb);
|
||||
};
|
||||
|
||||
class Invocation {
|
||||
class Invocation : public eng::nevernew {
|
||||
public:
|
||||
enum Kind {
|
||||
KIND_INVALID,
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
#include "luastack.hpp"
|
||||
|
||||
class LuaConsole {
|
||||
class LuaConsole : public eng::nevernew {
|
||||
public:
|
||||
using StringVec = eng::vector<eng::string>;
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "streambuffer.hpp"
|
||||
#include "luastack.hpp"
|
||||
|
||||
class LuaSnap {
|
||||
class LuaSnap : public eng::nevernew {
|
||||
private:
|
||||
lua_State *state_;
|
||||
|
||||
|
||||
@@ -163,7 +163,7 @@ extern "C" {
|
||||
#include "eris.h"
|
||||
}
|
||||
|
||||
class LuaSlot {
|
||||
class LuaSlot : public eng::nevernew {
|
||||
protected:
|
||||
int index_;
|
||||
private:
|
||||
@@ -226,7 +226,7 @@ int LuaTypeTagValue(lua_State *L) { return 0; }
|
||||
#define LUA_TT_GLOBALDB 22
|
||||
#define LUA_TT_CLASS 23
|
||||
|
||||
class LuaStack {
|
||||
class LuaStack : public eng::nevernew {
|
||||
private:
|
||||
int narg_;
|
||||
int ngap_;
|
||||
@@ -470,7 +470,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class LuaFunctionReg {
|
||||
class LuaFunctionReg : public eng::nevernew {
|
||||
private:
|
||||
const char *name_;
|
||||
const char *args_;
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
|
||||
class PlaneMap;
|
||||
|
||||
class PlaneItem {
|
||||
class PlaneItem : public eng::nevernew {
|
||||
friend class PlaneMap;
|
||||
|
||||
private:
|
||||
@@ -112,7 +112,7 @@ public:
|
||||
void set_xyz(float x, float y, float z) { set_pos(plane_, x, y, z); }
|
||||
};
|
||||
|
||||
class PlaneMap {
|
||||
class PlaneMap : public eng::nevernew {
|
||||
friend class PlaneItem;
|
||||
private:
|
||||
using EltVec = eng::vector<PlaneItem *>;
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
|
||||
struct PrintBufferCore;
|
||||
|
||||
class PrintBuffer : public eng::opnew {
|
||||
class PrintBuffer : public eng::nevernew {
|
||||
private:
|
||||
PrintBufferCore *core_;
|
||||
|
||||
@@ -138,7 +138,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class PrintChanneler : public eng::opnew {
|
||||
class PrintChanneler : public eng::nevernew {
|
||||
private:
|
||||
int64_t line_;
|
||||
public:
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class SchedEntry {
|
||||
class SchedEntry : public eng::nevernew {
|
||||
private:
|
||||
friend class Schedule;
|
||||
int64_t clock_;
|
||||
@@ -30,7 +30,7 @@ public:
|
||||
eng::string debug_string() const;
|
||||
};
|
||||
|
||||
class Schedule {
|
||||
class Schedule : public eng::nevernew {
|
||||
private:
|
||||
eng::set<SchedEntry> schedule_;
|
||||
public:
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
#include "streambuffer.hpp"
|
||||
#include "debugcollector.hpp"
|
||||
|
||||
class SourceDB {
|
||||
class SourceDB : public eng::nevernew {
|
||||
private:
|
||||
lua_State *lua_state_;
|
||||
|
||||
|
||||
@@ -490,7 +490,7 @@ void *StreamBuffer::lua_reader_ud(int64_t size) {
|
||||
return this;
|
||||
}
|
||||
|
||||
class StreamBufferWriter : public std::streambuf {
|
||||
class StreamBufferWriter : public std::streambuf, public eng::opnew {
|
||||
private:
|
||||
StreamBuffer *target_;
|
||||
public:
|
||||
@@ -504,7 +504,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class StreamBufferOStream : public std::ostream {
|
||||
class StreamBufferOStream : public std::ostream, public eng::opnew {
|
||||
private:
|
||||
StreamBufferWriter writer_;
|
||||
public:
|
||||
|
||||
@@ -222,7 +222,7 @@
|
||||
#include "luastack.hpp"
|
||||
#include "util.hpp"
|
||||
|
||||
class StreamException
|
||||
class StreamException : public eng::nevernew
|
||||
{
|
||||
public:
|
||||
virtual char const *what() const { return "General stream exception"; }
|
||||
@@ -240,7 +240,7 @@ public:
|
||||
virtual char const *what() const { return "Stream contained invalid data"; }
|
||||
};
|
||||
|
||||
class StreamBuffer {
|
||||
class StreamBuffer : public eng::nevernew {
|
||||
public:
|
||||
// Construct an empty buffer.
|
||||
StreamBuffer();
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
class World;
|
||||
|
||||
class Tangible {
|
||||
class Tangible : public eng::opnew {
|
||||
private:
|
||||
friend class World;
|
||||
|
||||
@@ -90,7 +90,7 @@ public:
|
||||
|
||||
using UniqueTangible = std::unique_ptr<Tangible>;
|
||||
|
||||
class World {
|
||||
class World : public eng::opnew {
|
||||
public:
|
||||
using IdVector = util::IdVector;
|
||||
using TanVector = eng::vector<const Tangible*>;
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
|
||||
namespace eng {
|
||||
template<class T>
|
||||
using deque = std::deque<T, eng::allocator<T>>;
|
||||
class deque : public std::deque<T, eng::allocator<T>>, public eng::opnew {
|
||||
using std::deque<T, eng::allocator<T>>::deque;
|
||||
};
|
||||
} // namespace eng
|
||||
|
||||
#endif // WRAP_DEQUE_HPP
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
|
||||
namespace eng {
|
||||
template<class K, class V, class C=std::less<K>>
|
||||
using map = std::map<K, V, C, eng::allocator<std::pair<const K, V>>>;
|
||||
class map : public std::map<K, V, C, eng::allocator<std::pair<const K, V>>>, eng::opnew {
|
||||
using std::map<K, V, C, eng::allocator<std::pair<const K, V>>>::map;
|
||||
};
|
||||
} // namespace eng
|
||||
|
||||
#endif // WRAP_MAP_HPP
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
|
||||
namespace eng {
|
||||
template<class K, class C=std::less<K>>
|
||||
using set = std::set<K, C, eng::allocator<K>>;
|
||||
class set : public std::set<K, C, eng::allocator<K>>, public eng::opnew {
|
||||
using std::set<K, C, eng::allocator<K>>::set;
|
||||
};
|
||||
} // namespace eng
|
||||
|
||||
#endif // WRAP_SET_HPP
|
||||
|
||||
@@ -2,11 +2,16 @@
|
||||
#define WRAP_SSTREAM_HPP
|
||||
|
||||
#include "eng-malloc.hpp"
|
||||
#include "wrap-string.hpp"
|
||||
#include <sstream>
|
||||
#include <string_view>
|
||||
|
||||
namespace eng {
|
||||
template<class C, class T=std::char_traits<C>>
|
||||
using basic_ostringstream = std::basic_ostringstream<C, T, eng::allocator<C>>;
|
||||
class basic_ostringstream : public std::basic_ostringstream<C, T, eng::allocator<C>>, public eng::opnew {
|
||||
using underlying = std::basic_ostringstream<C, T, eng::allocator<C>>;
|
||||
using underlying::basic_ostringstream;
|
||||
};
|
||||
using ostringstream = basic_ostringstream<char>;
|
||||
} // namespace eng
|
||||
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
|
||||
namespace eng {
|
||||
template<class K, class V, class H=std::hash<K>, class E=std::equal_to<K>>
|
||||
using unordered_map = std::unordered_map<K, V, H, E, eng::allocator<std::pair<const K, V>>>;
|
||||
class unordered_map : public std::unordered_map<K, V, H, E, eng::allocator<std::pair<const K, V>>>, public eng::opnew {
|
||||
using std::unordered_map<K, V, H, E, eng::allocator<std::pair<const K, V>>>::unordered_map;
|
||||
};
|
||||
} // namespace eng
|
||||
|
||||
#endif // WRAP_UNORDERED_MAP_HPP
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
|
||||
namespace eng {
|
||||
template<class K, class H=std::hash<K>, class E=std::equal_to<K>>
|
||||
using unordered_set = std::unordered_set<K, H, E, eng::allocator<K>>;
|
||||
class unordered_set : public std::unordered_set<K, H, E, eng::allocator<K>>, public eng::opnew {
|
||||
using std::unordered_set<K, H, E, eng::allocator<K>>::unordered_set;
|
||||
};
|
||||
} // namespace eng
|
||||
|
||||
#endif // WRAP_UNORDERED_SET_HPP
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
|
||||
namespace eng {
|
||||
template<class T>
|
||||
using vector = std::vector<T, eng::allocator<T>>;
|
||||
class vector : public std::vector<T, eng::allocator<T>>, public eng::opnew {
|
||||
using std::vector<T, eng::allocator<T>>::vector;
|
||||
};
|
||||
} // namespace eng
|
||||
|
||||
#endif // WRAP_VECTOR_HPP
|
||||
|
||||
Reference in New Issue
Block a user