From 269f28df980f34895c3c7181140963b4a86a1afc Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Thu, 9 Feb 2017 22:20:56 +0100 Subject: Split the Scope types, and generic ref/unref --- evaluate.cpp | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) (limited to 'evaluate.cpp') diff --git a/evaluate.cpp b/evaluate.cpp index c73d59a..ebfb773 100644 --- a/evaluate.cpp +++ b/evaluate.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include "evaluate.h" @@ -9,37 +9,46 @@ Value::Value(double numval) :type(Type::number),numval(numval){} Value::Value(const string &strval) :type(Type::string),strval(strval){} -Value::Value(const Scope &scope) +Value::Value(ScopeVal *scope) :type(Type::scope),scope(scope){} namespace A { - map collection; - - template - Value* ref_create(Args... args){ - Value *value=new Value(args...); - return ref(value); + struct CollItem{ + int count; + void (*deleter)(void*); + }; + + template + static void generic_deleter(void *p){ + delete (T*)p; } - Value* ref(Value *value){ - auto it=collection.find(value); + unordered_map collection; + + template + T* ref(T *p){ + auto it=collection.find((void*)p); if(it==collection.end()){ - collection.emplace(value,1); + collection.emplace((void*)p,(CollItem){1,generic_deleter}); } else { - it->second++; + it->second.count++; } - return value; + return p; } - void unref(Value *value){ - auto it=collection.find(value); + template + void unref(T *p){ + auto it=collection.find(p); assert(it!=collection.end()); - if(it->second==1){ - delete value; + if(it->second.count==1){ + if(it->second.deleter!=generic_deleter){ + throw runtime_error("Unref'd pointer type not the same as the ref'd version!"); + } + it->second.deleter(p); collection.erase(it); } else { - it->second--; + it->second.count--; } } } -- cgit v1.2.3-54-g00ecf