diff options
Diffstat (limited to 'evaluate.cpp')
-rw-r--r-- | evaluate.cpp | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/evaluate.cpp b/evaluate.cpp index c73d59a..ebfb773 100644 --- a/evaluate.cpp +++ b/evaluate.cpp @@ -1,4 +1,4 @@ -#include <map> +#include <stdexcept> #include <cassert> #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<Value*,int> collection; - - template <typename ...Args> - Value* ref_create(Args... args){ - Value *value=new Value(args...); - return ref(value); + struct CollItem{ + int count; + void (*deleter)(void*); + }; + + template <typename T> + static void generic_deleter(void *p){ + delete (T*)p; } - Value* ref(Value *value){ - auto it=collection.find(value); + unordered_map<void*,CollItem> collection; + + template <typename T> + 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<T>}); } else { - it->second++; + it->second.count++; } - return value; + return p; } - void unref(Value *value){ - auto it=collection.find(value); + template <typename T> + 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<T>){ + 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--; } } } |