Reduce problems for header only implementation be eliminating static class object

This commit is contained in:
Jason Turner 2009-06-13 20:55:47 +00:00
parent dc0f74fd36
commit 1eb0964f4e
2 changed files with 110 additions and 80 deletions

View File

@ -15,6 +15,8 @@ void bootstrap_random_access_container(Dispatch_Engine &system, const std::strin
typedef typename ContainerType::reference(ContainerType::*indexoper)(size_t); typedef typename ContainerType::reference(ContainerType::*indexoper)(size_t);
//In the interest of runtime safety for the system, we prefer the at() method for [] access,
//to throw an exception in an out of bounds condition.
system.register_function( system.register_function(
boost::function<typename ContainerType::reference (ContainerType *, int)>(indexoper(&ContainerType::at)), "[]"); boost::function<typename ContainerType::reference (ContainerType *, int)>(indexoper(&ContainerType::at)), "[]");
system.register_function( system.register_function(

View File

@ -10,6 +10,11 @@
class Boxed_Value class Boxed_Value
{ {
public:
struct Void_Type
{
};
private: private:
struct Data struct Data
{ {
@ -73,73 +78,114 @@ class Boxed_Value
boost::shared_ptr<Shared_Ptr_Proxy> m_ptr_proxy; boost::shared_ptr<Shared_Ptr_Proxy> m_ptr_proxy;
}; };
public: struct Object_Cache
struct Void_Type
{ {
}; boost::shared_ptr<Data> get(Boxed_Value::Void_Type)
{
return boost::shared_ptr<Data> (new Data(
Get_Type_Info<void>()(),
boost::any(),
false)
);
}
template<typename T> template<typename T>
explicit Boxed_Value(boost::shared_ptr<T> obj) boost::shared_ptr<Data> get(boost::shared_ptr<T> obj)
: m_data(new Data( {
boost::shared_ptr<Data> data(new Data(
Get_Type_Info<T>()(), Get_Type_Info<T>()(),
boost::any(obj), boost::any(obj),
false, false,
boost::shared_ptr<Data::Shared_Ptr_Proxy>(new Data::Shared_Ptr_Proxy_Impl<T>())) boost::shared_ptr<Data::Shared_Ptr_Proxy>(new Data::Shared_Ptr_Proxy_Impl<T>()))
) );
{
boost::shared_ptr<T> *ptr = boost::any_cast<boost::shared_ptr<T> >(&m_data->m_obj);
std::map<void *, Data >::iterator itr std::map<void *, Data >::iterator itr
= m_ptrs.find(ptr->get()); = m_ptrs.find(obj.get());
if (itr != m_ptrs.end()) if (itr != m_ptrs.end())
{ {
(*m_data) = (itr->second); (*data) = (itr->second);
} else { } else {
m_ptrs.insert(std::make_pair(ptr->get(), *m_data)); m_ptrs.insert(std::make_pair(obj.get(), *data));
} }
return data;
} }
template<typename T> template<typename T>
explicit Boxed_Value(boost::reference_wrapper<T> obj) boost::shared_ptr<Data> get(boost::reference_wrapper<T> obj)
: m_data(new Data( {
boost::shared_ptr<Data> data(new Data(
Get_Type_Info<T>()(), Get_Type_Info<T>()(),
boost::any(obj), boost::any(obj),
true) true)
) );
{
void *ptr = boost::any_cast<boost::reference_wrapper<T> >(m_data->m_obj).get_pointer();
std::map<void *, Data >::iterator itr std::map<void *, Data >::iterator itr
= m_ptrs.find(ptr); = m_ptrs.find(obj.get_pointer());
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); (*data) = (itr->second);
} }
return data;
} }
template<typename T> template<typename T>
explicit Boxed_Value(const T& t) boost::shared_ptr<Data> get(const T& t)
: m_data(new Data( {
boost::shared_ptr<Data> data(new Data(
Get_Type_Info<T>()(), Get_Type_Info<T>()(),
boost::any(boost::shared_ptr<T>(new T(t))), boost::any(boost::shared_ptr<T>(new T(t))),
false, false,
boost::shared_ptr<Data::Shared_Ptr_Proxy>(new Data::Shared_Ptr_Proxy_Impl<T>())) boost::shared_ptr<Data::Shared_Ptr_Proxy>(new Data::Shared_Ptr_Proxy_Impl<T>()))
) );
{
boost::shared_ptr<T> *ptr = boost::any_cast<boost::shared_ptr<T> >(&m_data->m_obj);
m_ptrs.insert(std::make_pair(ptr->get(), *m_data)); boost::shared_ptr<T> *ptr = boost::any_cast<boost::shared_ptr<T> >(&data->m_obj);
m_ptrs.insert(std::make_pair(ptr->get(), *data));
return data;
} }
Boxed_Value(Boxed_Value::Void_Type) boost::shared_ptr<Data> get()
: m_data(new Data( {
Get_Type_Info<void>()(), return boost::shared_ptr<Data> (new Data(
Type_Info(),
boost::any(), boost::any(),
false) false)
) );
}
void cull()
{
std::map<void *, Data >::iterator itr = m_ptrs.begin();
while (itr != m_ptrs.end())
{
if (itr->second.m_ptr_proxy->unique(&itr->second.m_obj) == 1)
{
std::map<void *, 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 *, Data > m_ptrs;
};
public:
template<typename T>
explicit Boxed_Value(T t)
: m_data(get_object_cache().get(t))
{ {
} }
@ -149,19 +195,23 @@ class Boxed_Value
} }
Boxed_Value() Boxed_Value()
: m_data(new Data( : m_data(get_object_cache().get())
Type_Info(),
boost::any(),
false)
)
{ {
} }
~Boxed_Value() ~Boxed_Value()
{ {
cleanup_ptrs(m_ptrs); get_object_cache().cull();
} }
Object_Cache &get_object_cache()
{
static Object_Cache oc;
return oc;
}
Boxed_Value assign(const Boxed_Value &rhs) Boxed_Value assign(const Boxed_Value &rhs)
{ {
(*m_data) = (*rhs.m_data); (*m_data) = (*rhs.m_data);
@ -196,30 +246,8 @@ class Boxed_Value
private: private:
boost::shared_ptr<Data> m_data; boost::shared_ptr<Data> m_data;
static std::map<void *, Data > m_ptrs;
void cleanup_ptrs(std::map<void *, Data > &m_ptrs)
{
std::map<void *, Data >::iterator itr = m_ptrs.begin();
while (itr != m_ptrs.end())
{
if (itr->second.m_ptr_proxy->unique(&itr->second.m_obj) == 1)
{
std::map<void *, 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 *, Boxed_Value::Data > Boxed_Value::m_ptrs;
//cast_help specializations //cast_help specializations
template<typename Result> template<typename Result>