From a463ee5ff2bd8baae7f8f721cf4959afb1299820 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 2 Aug 2010 17:51:30 +0000 Subject: [PATCH] Clean up key used in the thread global object cache, to make sure proper type comparisons are done in the corner cases found in the main boxed_cast<> code a while back --- .../chaiscript/dispatchkit/boxed_value.hpp | 55 ++++++++++++++----- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_value.hpp b/include/chaiscript/dispatchkit/boxed_value.hpp index e9ae280..01d8ef4 100644 --- a/include/chaiscript/dispatchkit/boxed_value.hpp +++ b/include/chaiscript/dispatchkit/boxed_value.hpp @@ -19,8 +19,6 @@ #include #include #include -#include -#include namespace chaiscript { @@ -96,6 +94,38 @@ namespace chaiscript */ struct Object_Cache { + struct Object_Cache_Key + { + Object_Cache_Key(const void *t_obj, bool t_const, const std::type_info *t_objtype) + : m_obj(t_obj), m_const(t_const), m_objtype(t_objtype) + { + } + + bool operator<(const Object_Cache_Key &rhs) const + { + //Take into account the fact that sometimes there are equiv type_info objects + //that have different pointer values, so we have to dereference to use the built in + //comparison operator + return m_obj < rhs.m_obj + || (m_obj == rhs.m_obj && m_const < rhs.m_const) + || (m_obj == rhs.m_obj && m_const == rhs.m_const + && m_objtype < rhs.m_objtype && !((*m_objtype) == (*rhs.m_objtype))); + } + + bool operator==(const Object_Cache_Key &rhs) const + { + return m_obj == rhs.m_obj + && m_const == rhs.m_const + && (m_objtype == rhs.m_objtype || (*m_objtype) == (*rhs.m_objtype) ); + } + + + + const void *m_obj; + bool m_const; + const std::type_info *m_objtype; + }; + Object_Cache() : m_cullcount(0) { @@ -130,14 +160,14 @@ namespace chaiscript &Data::is_null) ); - std::map, Data>::iterator itr - = m_ptrs.find(boost::make_tuple(obj.get(), b_const, ti)); + std::map::iterator itr + = m_ptrs.find(Object_Cache_Key(obj.get(), b_const, ti)); if (itr != m_ptrs.end()) { (*data) = (itr->second); } else { - m_ptrs.insert(std::make_pair(boost::make_tuple(obj.get(), b_const, ti), *data)); + m_ptrs.insert(std::make_pair(Object_Cache_Key(obj.get(), b_const, ti), *data)); } return data; @@ -161,8 +191,8 @@ namespace chaiscript true) ); - std::map, Data >::iterator itr - = m_ptrs.find(boost::make_tuple(obj.get_pointer(), b_const, ti) ); + std::map::iterator itr + = m_ptrs.find(Object_Cache_Key(obj.get_pointer(), b_const, ti) ); // If the ptr is found in the cache and it is the correct type, // return it. It may be the incorrect type when two variables share the @@ -195,9 +225,7 @@ namespace chaiscript boost::shared_ptr *ptr = boost::any_cast >(&data->m_obj); - boost::tuple key(ptr->get(), false, ti); - - m_ptrs.insert(std::make_pair(key, *data)); + m_ptrs.insert(std::make_pair(Object_Cache_Key(ptr->get(), false, ti), *data)); return data; } @@ -223,14 +251,13 @@ namespace chaiscript return; } - - std::map, Data>::iterator itr = m_ptrs.begin(); + std::map::iterator itr = m_ptrs.begin(); while (itr != m_ptrs.end()) { if (itr->second.m_unique(&itr->second.m_obj)) { - std::map, Data >::iterator todel = itr; + std::map::iterator todel = itr; ++itr; m_ptrs.erase(todel); } else { @@ -239,7 +266,7 @@ namespace chaiscript } } - std::map, Data> m_ptrs; + std::map m_ptrs; int m_cullcount; };