From 1eb0964f4e126175d3fb5c01d7d2d50db32be6b6 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 13 Jun 2009 20:55:47 +0000 Subject: [PATCH] Reduce problems for header only implementation be eliminating static class object --- dispatchkit/bootstrap_stl.hpp | 2 + dispatchkit/boxed_value.hpp | 188 +++++++++++++++++++--------------- 2 files changed, 110 insertions(+), 80 deletions(-) diff --git a/dispatchkit/bootstrap_stl.hpp b/dispatchkit/bootstrap_stl.hpp index f5bd0e9f..2ae51912 100644 --- a/dispatchkit/bootstrap_stl.hpp +++ b/dispatchkit/bootstrap_stl.hpp @@ -15,6 +15,8 @@ void bootstrap_random_access_container(Dispatch_Engine &system, const std::strin 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( boost::function(indexoper(&ContainerType::at)), "[]"); system.register_function( diff --git a/dispatchkit/boxed_value.hpp b/dispatchkit/boxed_value.hpp index 537a4727..2949ebda 100644 --- a/dispatchkit/boxed_value.hpp +++ b/dispatchkit/boxed_value.hpp @@ -10,6 +10,11 @@ class Boxed_Value { + public: + struct Void_Type + { + }; + private: struct Data { @@ -73,75 +78,116 @@ class Boxed_Value boost::shared_ptr m_ptr_proxy; }; - public: - struct Void_Type + struct Object_Cache { - }; - - template - explicit Boxed_Value(boost::shared_ptr obj) - : m_data(new Data( - Get_Type_Info()(), - boost::any(obj), - false, - boost::shared_ptr(new Data::Shared_Ptr_Proxy_Impl())) - ) + boost::shared_ptr get(Boxed_Value::Void_Type) { - boost::shared_ptr *ptr = boost::any_cast >(&m_data->m_obj); - - std::map::iterator itr - = m_ptrs.find(ptr->get()); - - if (itr != m_ptrs.end()) - { - (*m_data) = (itr->second); - } else { - m_ptrs.insert(std::make_pair(ptr->get(), *m_data)); - } + return boost::shared_ptr (new Data( + Get_Type_Info()(), + boost::any(), + false) + ); } - template - explicit Boxed_Value(boost::reference_wrapper obj) - : m_data(new Data( - Get_Type_Info()(), - boost::any(obj), - true) - ) + template + boost::shared_ptr get(boost::shared_ptr obj) + { + boost::shared_ptr data(new Data( + Get_Type_Info()(), + boost::any(obj), + false, + boost::shared_ptr(new Data::Shared_Ptr_Proxy_Impl())) + ); + + std::map::iterator itr + = m_ptrs.find(obj.get()); + + if (itr != m_ptrs.end()) + { + (*data) = (itr->second); + } else { + m_ptrs.insert(std::make_pair(obj.get(), *data)); + } + + return data; + } + + template + boost::shared_ptr get(boost::reference_wrapper obj) { - void *ptr = boost::any_cast >(m_data->m_obj).get_pointer(); + boost::shared_ptr data(new Data( + Get_Type_Info()(), + boost::any(obj), + true) + ); std::map::iterator itr - = m_ptrs.find(ptr); + = m_ptrs.find(obj.get_pointer()); if (itr != m_ptrs.end()) { std::cout << "Reference wrapper ptr found, using it" << std::endl; - (*m_data) = (itr->second); + (*data) = (itr->second); } + + return data; } - template - explicit Boxed_Value(const T& t) - : m_data(new Data( - Get_Type_Info()(), - boost::any(boost::shared_ptr(new T(t))), - false, - boost::shared_ptr(new Data::Shared_Ptr_Proxy_Impl())) - ) + template + boost::shared_ptr get(const T& t) + { + boost::shared_ptr data(new Data( + Get_Type_Info()(), + boost::any(boost::shared_ptr(new T(t))), + false, + boost::shared_ptr(new Data::Shared_Ptr_Proxy_Impl())) + ); + + boost::shared_ptr *ptr = boost::any_cast >(&data->m_obj); + + m_ptrs.insert(std::make_pair(ptr->get(), *data)); + return data; + } + + boost::shared_ptr get() { - boost::shared_ptr *ptr = boost::any_cast >(&m_data->m_obj); - - m_ptrs.insert(std::make_pair(ptr->get(), *m_data)); + return boost::shared_ptr (new Data( + Type_Info(), + boost::any(), + false) + ); } - Boxed_Value(Boxed_Value::Void_Type) - : m_data(new Data( - Get_Type_Info()(), - boost::any(), - false) - ) - { - } + void cull() + { + std::map::iterator itr = m_ptrs.begin(); + + while (itr != m_ptrs.end()) + { + if (itr->second.m_ptr_proxy->unique(&itr->second.m_obj) == 1) + { + std::map::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 m_ptrs; + }; + + public: + template + explicit Boxed_Value(T t) + : m_data(get_object_cache().get(t)) + { + } Boxed_Value(const Boxed_Value &t_so) : m_data(t_so.m_data) @@ -149,19 +195,23 @@ class Boxed_Value } Boxed_Value() - : m_data(new Data( - Type_Info(), - boost::any(), - false) - ) + : m_data(get_object_cache().get()) { } ~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) { (*m_data) = (*rhs.m_data); @@ -196,30 +246,8 @@ class Boxed_Value private: boost::shared_ptr m_data; - static std::map m_ptrs; - - void cleanup_ptrs(std::map &m_ptrs) - { - std::map::iterator itr = m_ptrs.begin(); - - while (itr != m_ptrs.end()) - { - if (itr->second.m_ptr_proxy->unique(&itr->second.m_obj) == 1) - { - std::map::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 Boxed_Value::m_ptrs; //cast_help specializations template