Memory management with freeing when applicable

This commit is contained in:
Jason Turner
2009-06-12 00:01:54 +00:00
parent 9838e34a96
commit b96059cba8
2 changed files with 47 additions and 11 deletions

View File

@@ -4,8 +4,9 @@
#include "type_info.hpp" #include "type_info.hpp"
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/any.hpp> #include <boost/any.hpp>
#include <boost/function.hpp>
#include <boost/ref.hpp> #include <boost/ref.hpp>
#include <boost/bind.hpp>
class Boxed_Value class Boxed_Value
{ {
@@ -14,8 +15,10 @@ class Boxed_Value
{ {
Data(const Type_Info &ti, Data(const Type_Info &ti,
const boost::any &to, const boost::any &to,
bool tr) bool tr,
: m_type_info(ti), m_obj(to), m_is_ref(tr) const boost::function<bool ()> &t_unique = &Boxed_Value::Data::get_false)
: m_type_info(ti), m_obj(to),
m_is_ref(tr)
{ {
} }
@@ -28,6 +31,11 @@ class Boxed_Value
return *this; return *this;
} }
static bool get_false()
{
return false;
}
Type_Info m_type_info; Type_Info m_type_info;
boost::any m_obj; boost::any m_obj;
bool m_is_ref; bool m_is_ref;
@@ -46,16 +54,16 @@ class Boxed_Value
false) false)
) )
{ {
void *ptr = boost::any_cast<boost::shared_ptr<T> >(m_data->m_obj).get(); boost::shared_ptr<T> *ptr = boost::any_cast<boost::shared_ptr<T> >(&m_data->m_obj);
std::map<void *, boost::shared_ptr<Data> >::iterator itr std::map<void *, boost::shared_ptr<Data> >::iterator itr
= m_ptrs.find(ptr); = m_ptrs.find(ptr->get());
if (itr != m_ptrs.end()) if (itr != m_ptrs.end())
{ {
m_data = (itr->second); m_data = (itr->second);
} else { } else {
m_ptrs[ptr] = m_data; m_ptrs[ptr->get()] = m_data;
} }
} }
@@ -74,11 +82,9 @@ class Boxed_Value
if (itr != m_ptrs.end()) if (itr != m_ptrs.end())
{ {
std::cout << "Reference wrapper ptr found, using it" << std::endl; // std::cout << "Reference wrapper ptr found, using it" << std::endl;
m_data = (itr->second); m_data = (itr->second);
} else { }
m_ptrs[ptr] = m_data;
}
} }
template<typename T> template<typename T>
@@ -89,7 +95,9 @@ class Boxed_Value
false) false)
) )
{ {
m_ptrs[boost::any_cast<boost::shared_ptr<T> >(m_data->m_obj).get()] boost::shared_ptr<T> *ptr = boost::any_cast<boost::shared_ptr<T> >(&m_data->m_obj);
m_ptrs[ptr->get()]
= m_data; = m_data;
} }
@@ -116,6 +124,11 @@ class Boxed_Value
{ {
} }
~Boxed_Value()
{
cleanup_ptrs(m_ptrs);
}
Boxed_Value assign(const Boxed_Value &rhs) Boxed_Value assign(const Boxed_Value &rhs)
{ {
(*m_data) = (*rhs.m_data); (*m_data) = (*rhs.m_data);
@@ -151,6 +164,26 @@ class Boxed_Value
private: private:
boost::shared_ptr<Data> m_data; boost::shared_ptr<Data> m_data;
static std::map<void *, boost::shared_ptr<Data> > m_ptrs; static std::map<void *, boost::shared_ptr<Data> > m_ptrs;
void cleanup_ptrs(std::map<void *, boost::shared_ptr<Data> > &m_ptrs)
{
std::map<void *, boost::shared_ptr<Data> >::iterator itr = m_ptrs.begin();
while (itr != m_ptrs.end())
{
if (itr->second.unique())
{
std::map<void *, boost::shared_ptr<Data> >::iterator todel = itr;
// std::cout << "Releasing unique ptr " << std::endl;
++itr;
m_ptrs.erase(todel);
} else {
++itr;
}
}
// std::cout << "References held: " << m_ptrs.size() << std::endl;
}
}; };
std::map<void *, boost::shared_ptr<Boxed_Value::Data> > Boxed_Value::m_ptrs; std::map<void *, boost::shared_ptr<Boxed_Value::Data> > Boxed_Value::m_ptrs;

View File

@@ -1,2 +1,5 @@
var add2 = function(x, y) { x + y } var add2 = function(x, y) { x + y }
var add1 = function(x, f) { f(3,x) }
print(add2(3, 4)) print(add2(3, 4))
print(add1(2, add2))