Refactor library GC to its own namespace

This commit is contained in:
Ilari Liusvaara 2014-11-10 16:06:04 +02:00
parent 9a69dc3511
commit b5ed0f73b1
10 changed files with 77 additions and 72 deletions

View file

@ -32,8 +32,8 @@ struct memwatch_printer
/**
* Get a printer object corresponding to this object.
*/
gcroot_pointer<memorywatch::item_printer> get_printer_obj(
std::function<gcroot_pointer<mathexpr::mathexpr>(const std::string& n)> vars);
GC::pointer<memorywatch::item_printer> get_printer_obj(
std::function<GC::pointer<mathexpr::mathexpr>(const std::string& n)> vars);
//Fields.
enum position_category {
PC_DISABLED,

View file

@ -3,11 +3,13 @@
#include <cstdlib>
class garbage_collectable
namespace GC
{
class item
{
public:
garbage_collectable();
virtual ~garbage_collectable();
item();
virtual ~item();
void mark_root();
void unmark_root();
static void do_gc();
@ -19,28 +21,28 @@ private:
bool reachable;
};
struct gcroot_pointer_object_tag {};
template<class T> class gcroot_pointer
struct obj_tag {};
template<class T> class pointer
{
public:
gcroot_pointer()
pointer()
{
ptr = NULL;
}
gcroot_pointer(T* obj)
pointer(T* obj)
{
ptr = obj;
}
template<typename... U> gcroot_pointer(gcroot_pointer_object_tag tag, U... args)
template<typename... U> pointer(obj_tag tag, U... args)
{
ptr = new T(args...);
}
gcroot_pointer(const gcroot_pointer& p)
pointer(const pointer& p)
{
if(p.ptr) p.ptr->mark_root();
ptr = p.ptr;
}
gcroot_pointer& operator=(const gcroot_pointer& p)
pointer& operator=(const pointer& p)
{
if(ptr == p.ptr) return *this;
if(ptr) ptr->unmark_root();
@ -48,7 +50,7 @@ public:
ptr = p.ptr;
return *this;
}
~gcroot_pointer()
~pointer()
{
if(ptr) ptr->unmark_root();
}
@ -62,5 +64,6 @@ public:
private:
T* ptr;
};
}
#endif

View file

@ -216,7 +216,7 @@ template<class T> struct typeinfo_wrapper : public typeinfo
}
};
class mathexpr : public garbage_collectable
class mathexpr : public GC::item
{
public:
enum eval_state
@ -234,13 +234,13 @@ public:
//Undefined value of specified type.
mathexpr(typeinfo* _type);
//Forward evaluation.
mathexpr(typeinfo* _type, gcroot_pointer<mathexpr> fwd);
mathexpr(typeinfo* _type, GC::pointer<mathexpr> fwd);
//Value of specified type.
mathexpr(value value);
//Value of specified type.
mathexpr(typeinfo* _type, const std::string& value, bool string);
//Specified Operator.
mathexpr(typeinfo* _type, operinfo* fn, std::vector<gcroot_pointer<mathexpr>> _args,
mathexpr(typeinfo* _type, operinfo* fn, std::vector<GC::pointer<mathexpr>> _args,
bool _owns_operator = false);
//Dtor.
~mathexpr();
@ -254,8 +254,8 @@ public:
//Reset.
void reset();
//Parse an expression.
static gcroot_pointer<mathexpr> parse(typeinfo& _type, const std::string& expr,
std::function<gcroot_pointer<mathexpr>(const std::string&)> vars);
static GC::pointer<mathexpr> parse(typeinfo& _type, const std::string& expr,
std::function<GC::pointer<mathexpr>(const std::string&)> vars);
protected:
void trace();
private:

View file

@ -21,9 +21,9 @@ struct output_fb : public item_printer
void show(const std::string& iname, const std::string& val);
void reset();
bool cond_enable;
gcroot_pointer<mathexpr::mathexpr> enabled;
gcroot_pointer<mathexpr::mathexpr> pos_x;
gcroot_pointer<mathexpr::mathexpr> pos_y;
GC::pointer<mathexpr::mathexpr> enabled;
GC::pointer<mathexpr::mathexpr> pos_x;
GC::pointer<mathexpr::mathexpr> pos_y;
bool alt_origin_x;
bool alt_origin_y;
bool cliprange_x;

View file

@ -16,7 +16,7 @@ struct output_list : public item_printer
void show(const std::string& iname, const std::string& val);
void reset();
bool cond_enable;
gcroot_pointer<mathexpr::mathexpr> enabled;
GC::pointer<mathexpr::mathexpr> enabled;
//State variables.
std::function<void(const std::string& n, const std::string& v)> fn;
};

View file

@ -43,7 +43,7 @@ struct memread_oper : public mathexpr::operinfo
/**
* Memory watch item printer.
*/
struct item_printer : public garbage_collectable
struct item_printer : public GC::item
{
/**
* Dtor.
@ -72,7 +72,7 @@ struct item
* Parameter t: The type of the result.
*/
item(mathexpr::typeinfo& t)
: expr(gcroot_pointer_object_tag(), &t)
: expr(GC::obj_tag(), &t)
{
}
/**
@ -86,8 +86,8 @@ struct item
*/
void show(const std::string& iname);
//Fields.
gcroot_pointer<item_printer> printer; //Printer to use.
gcroot_pointer<mathexpr::mathexpr> expr; //Expression to watch.
GC::pointer<item_printer> printer; //Printer to use.
GC::pointer<mathexpr::mathexpr> expr; //Expression to watch.
std::string format; //Formatting to use.
};

View file

@ -156,10 +156,10 @@ void memwatch_printer::unserialize(const JSON::node& node)
onscreen_halo_color = json_signed_default(node, "onscreen_halo_color", false);
}
gcroot_pointer<memorywatch::item_printer> memwatch_printer::get_printer_obj(
std::function<gcroot_pointer<mathexpr::mathexpr>(const std::string& n)> vars)
GC::pointer<memorywatch::item_printer> memwatch_printer::get_printer_obj(
std::function<GC::pointer<mathexpr::mathexpr>(const std::string& n)> vars)
{
gcroot_pointer<memorywatch::item_printer> ptr;
GC::pointer<memorywatch::item_printer> ptr;
memorywatch::output_list* l;
memorywatch::output_fb* f;
@ -167,10 +167,10 @@ gcroot_pointer<memorywatch::item_printer> memwatch_printer::get_printer_obj(
switch(position) {
case PC_DISABLED:
ptr = gcroot_pointer<memorywatch::item_printer>(new memorywatch::output_null);
ptr = GC::pointer<memorywatch::item_printer>(new memorywatch::output_null);
break;
case PC_MEMORYWATCH:
ptr = gcroot_pointer<memorywatch::item_printer>(new memorywatch::output_list);
ptr = GC::pointer<memorywatch::item_printer>(new memorywatch::output_list);
l = dynamic_cast<memorywatch::output_list*>(ptr.as_pointer());
l->cond_enable = cond_enable;
try {
@ -184,7 +184,7 @@ gcroot_pointer<memorywatch::item_printer> memwatch_printer::get_printer_obj(
l->set_output(dummy_target_fn);
break;
case PC_ONSCREEN:
ptr = gcroot_pointer<memorywatch::item_printer>(new memorywatch::output_fb);
ptr = GC::pointer<memorywatch::item_printer>(new memorywatch::output_fb);
f = dynamic_cast<memorywatch::output_fb*>(ptr.as_pointer());
f->font = NULL;
f->set_dtor_cb([](memorywatch::output_fb& obj) { put_font(obj.font); });
@ -497,19 +497,19 @@ void memwatch_set::rebuild(std::map<std::string, memwatch_item>& nitems)
{
{
memorywatch::set new_set;
std::map<std::string, gcroot_pointer<mathexpr::mathexpr>> vars;
auto vars_fn = [&vars](const std::string& n) -> gcroot_pointer<mathexpr::mathexpr> {
std::map<std::string, GC::pointer<mathexpr::mathexpr>> vars;
auto vars_fn = [&vars](const std::string& n) -> GC::pointer<mathexpr::mathexpr> {
if(!vars.count(n))
vars[n] = gcroot_pointer<mathexpr::mathexpr>(gcroot_pointer_object_tag(),
vars[n] = GC::pointer<mathexpr::mathexpr>(GC::obj_tag(),
mathexpr::expression_value());
return vars[n];
};
for(auto& i : nitems) {
mathexpr::operinfo* memread_oper = i.second.get_memread_oper();
try {
gcroot_pointer<mathexpr::mathexpr> rt_expr;
gcroot_pointer<memorywatch::item_printer> rt_printer;
std::vector<gcroot_pointer<mathexpr::mathexpr>> v;
GC::pointer<mathexpr::mathexpr> rt_expr;
GC::pointer<memorywatch::item_printer> rt_printer;
std::vector<GC::pointer<mathexpr::mathexpr>> v;
try {
rt_expr = mathexpr::mathexpr::parse(*mathexpr::expression_value(),
i.second.expr, vars_fn);
@ -519,7 +519,7 @@ void memwatch_set::rebuild(std::map<std::string, memwatch_item>& nitems)
}
v.push_back(rt_expr);
if(memread_oper) {
rt_expr = gcroot_pointer<mathexpr::mathexpr>(gcroot_pointer_object_tag(),
rt_expr = GC::pointer<mathexpr::mathexpr>(GC::obj_tag(),
mathexpr::expression_value(), memread_oper, v, true);
memread_oper = NULL;
}
@ -545,7 +545,7 @@ void memwatch_set::rebuild(std::map<std::string, memwatch_item>& nitems)
}
watch_set.swap(new_set);
}
garbage_collectable::do_gc();
GC::item::do_gc();
}
void memwatch_set::watch_output(const std::string& name, const std::string& value)

View file

@ -3,34 +3,36 @@
#include <iostream>
#include <set>
namespace GC
{
namespace
{
std::set<garbage_collectable*>* gc_items;
std::set<item*>* gc_items;
}
garbage_collectable::garbage_collectable()
item::item()
{
if(!gc_items) gc_items = new std::set<garbage_collectable*>;
if(!gc_items) gc_items = new std::set<item*>;
gc_items->insert(this);
root_count = 1;
}
garbage_collectable::~garbage_collectable()
item::~item()
{
gc_items->erase(this);
}
void garbage_collectable::mark_root()
void item::mark_root()
{
root_count++;
}
void garbage_collectable::unmark_root()
void item::unmark_root()
{
if(root_count) root_count--;
}
void garbage_collectable::do_gc()
void item::do_gc()
{
if(!gc_items) return;
for(auto i : *gc_items)
@ -50,7 +52,7 @@ void garbage_collectable::do_gc()
}
}
void garbage_collectable::mark()
void item::mark()
{
bool was_reachable = reachable;
reachable = true;
@ -58,3 +60,4 @@ void garbage_collectable::mark()
trace();
}
}
}

View file

@ -30,7 +30,7 @@ mathexpr::mathexpr(typeinfo* _type)
fn = (operinfo*)0xDEADBEEF;
}
mathexpr::mathexpr(typeinfo* _type, gcroot_pointer<mathexpr> fwd)
mathexpr::mathexpr(typeinfo* _type, GC::pointer<mathexpr> fwd)
: type(*_type)
{
owns_operator = false;
@ -58,8 +58,7 @@ mathexpr::mathexpr(typeinfo* _type, const std::string& _val, bool string)
fn = NULL;
}
mathexpr::mathexpr(typeinfo* _type, operinfo* _fn, std::vector<gcroot_pointer<mathexpr>> _args,
bool _owns_operator)
mathexpr::mathexpr(typeinfo* _type, operinfo* _fn, std::vector<GC::pointer<mathexpr>> _args, bool _owns_operator)
: type(*_type), fn(_fn), owns_operator(_owns_operator)
{
try {
@ -354,18 +353,18 @@ namespace
struct expr_or_op
{
expr_or_op(gcroot_pointer<mathexpr> e) : expr(e), typei(NULL) {}
expr_or_op(GC::pointer<mathexpr> e) : expr(e), typei(NULL) {}
expr_or_op(std::string o) : op(o), typei(NULL) {}
gcroot_pointer<mathexpr> expr;
GC::pointer<mathexpr> expr;
std::string op;
operinfo* typei;
};
gcroot_pointer<mathexpr> parse_rec(typeinfo& _type, std::vector<expr_or_op>& operands,
GC::pointer<mathexpr> parse_rec(typeinfo& _type, std::vector<expr_or_op>& operands,
size_t first, size_t last)
{
if(operands.empty())
return gcroot_pointer<mathexpr>(gcroot_pointer_object_tag(), &_type);
return GC::pointer<mathexpr>(GC::obj_tag(), &_type);
if(last - first > 1) {
//Find the highest percedence operator.
size_t best = last;
@ -387,29 +386,29 @@ namespace
size_t j = first;
while(operands[j].typei)
j++;
std::vector<gcroot_pointer<mathexpr>> args;
std::vector<GC::pointer<mathexpr>> args;
args.push_back(parse_rec(_type, operands, first + 1, j + 1));
return gcroot_pointer<mathexpr>(gcroot_pointer_object_tag(), &_type,
return GC::pointer<mathexpr>(GC::obj_tag(), &_type,
operands[best].typei, args);
} else {
//Binary operator.
std::vector<gcroot_pointer<mathexpr>> args;
std::vector<GC::pointer<mathexpr>> args;
args.push_back(parse_rec(_type, operands, first, best));
args.push_back(parse_rec(_type, operands, best + 1, last));
return gcroot_pointer<mathexpr>(gcroot_pointer_object_tag(), &_type,
return GC::pointer<mathexpr>(GC::obj_tag(), &_type,
operands[best].typei, args);
}
}
return operands[first].expr;
}
gcroot_pointer<mathexpr> parse_rec(typeinfo& _type, std::vector<subexpression>& ss,
GC::pointer<mathexpr> parse_rec(typeinfo& _type, std::vector<subexpression>& ss,
std::set<operinfo*>& operations,
std::function<gcroot_pointer<mathexpr>(const std::string&)> vars, size_t first, size_t last)
std::function<GC::pointer<mathexpr>(const std::string&)> vars, size_t first, size_t last)
{
operations_set opset(operations);
std::vector<expr_or_op> operands;
std::vector<gcroot_pointer<mathexpr>> args;
std::vector<GC::pointer<mathexpr>> args;
operinfo* fn;
for(size_t i = first; i < last; i++) {
size_t l = find_last_in_sub(ss, i);
@ -419,16 +418,16 @@ namespace
operands.push_back(parse_rec(_type, ss, operations, vars, i + 1, l));
break;
case TT_VALUE:
operands.push_back(gcroot_pointer<mathexpr>(gcroot_pointer_object_tag(), &_type,
operands.push_back(GC::pointer<mathexpr>(GC::obj_tag(), &_type,
ss[i].string, false));
break;
case TT_STRING:
operands.push_back(gcroot_pointer<mathexpr>(gcroot_pointer_object_tag(), &_type,
operands.push_back(GC::pointer<mathexpr>(GC::obj_tag(), &_type,
ss[i].string, true));
break;
case TT_VARIABLE:
//We have to warp this is identify transform to make the evaluation lazy.
operands.push_back(gcroot_pointer<mathexpr>(gcroot_pointer_object_tag(), &_type,
operands.push_back(GC::pointer<mathexpr>(GC::obj_tag(), &_type,
vars(ss[i].string)));
break;
case TT_FUNCTION:
@ -442,7 +441,7 @@ namespace
else
i = k;
}
operands.push_back(gcroot_pointer<mathexpr>(gcroot_pointer_object_tag(), &_type, fn,
operands.push_back(GC::pointer<mathexpr>(GC::obj_tag(), &_type, fn,
args));
args.clear();
break;
@ -462,8 +461,8 @@ namespace
if(!(bool)i.expr) {
auto fn = opset.find_operator(i.op, 0);
if(fn)
i.expr = gcroot_pointer<mathexpr>(gcroot_pointer_object_tag(), &_type, fn,
std::vector<gcroot_pointer<mathexpr>>());
i.expr = GC::pointer<mathexpr>(GC::obj_tag(), &_type, fn,
std::vector<GC::pointer<mathexpr>>());
}
}
//Check that there aren't two consequtive subexpressions and mark operators.
@ -615,8 +614,8 @@ namespace
}
}
gcroot_pointer<mathexpr> mathexpr::parse(typeinfo& _type, const std::string& expr,
std::function<gcroot_pointer<mathexpr>(const std::string&)> vars)
GC::pointer<mathexpr> mathexpr::parse(typeinfo& _type, const std::string& expr,
std::function<GC::pointer<mathexpr>(const std::string&)> vars)
{
if(expr == "")
throw std::runtime_error("Empty expression");

View file

@ -230,7 +230,7 @@ void item::show(const std::string& n)
set::~set()
{
roots.clear();
garbage_collectable::do_gc();
GC::item::do_gc();
}
void set::reset()
@ -284,7 +284,7 @@ void set::destroy(const std::string& name)
if(!roots.count(name))
return;
roots.erase(name);
garbage_collectable::do_gc();
GC::item::do_gc();
}
const std::string& set::get_longest_name(std::function<size_t(const std::string& n)> rate)