Fix bug that jon discovered that affects attempting to return a reference to an object that shares a memory location with a containing object but has a different type.

This commit is contained in:
Jason Turner 2009-07-15 23:12:49 +00:00
parent 724ffdcb20
commit ec2f81c674
3 changed files with 28 additions and 8 deletions

View File

@ -135,7 +135,7 @@ namespace dispatchkit
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>()))
); );
std::map<void *, Data >::iterator itr std::map<const void *, Data>::iterator itr
= m_ptrs.find(obj.get()); = m_ptrs.find(obj.get());
if (itr != m_ptrs.end()) if (itr != m_ptrs.end())
@ -157,10 +157,18 @@ namespace dispatchkit
true) true)
); );
std::map<void *, Data >::iterator itr std::map<const void *, Data >::iterator itr
= m_ptrs.find(obj.get_pointer()); = m_ptrs.find(obj.get_pointer());
if (itr != m_ptrs.end()) // 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
// same memory location. Example:
// struct test { int x; };
// test t;
// Both t and t.x share the same memory location, but do not represent
// objects of the same type.
if (itr != m_ptrs.end()
&& itr->second.m_type_info.m_bare_type_info == data->m_type_info.m_bare_type_info)
{ {
(*data) = (itr->second); (*data) = (itr->second);
} }
@ -199,13 +207,13 @@ namespace dispatchkit
*/ */
void cull() void cull()
{ {
std::map<void *, Data >::iterator itr = m_ptrs.begin(); std::map<const void *, Data >::iterator itr = m_ptrs.begin();
while (itr != m_ptrs.end()) while (itr != m_ptrs.end())
{ {
if (itr->second.m_ptr_proxy->unique(&itr->second.m_obj) == 1) if (itr->second.m_ptr_proxy->unique(&itr->second.m_obj) == 1)
{ {
std::map<void *, Data >::iterator todel = itr; std::map<const void *, Data >::iterator todel = itr;
++itr; ++itr;
m_ptrs.erase(todel); m_ptrs.erase(todel);
} else { } else {
@ -214,7 +222,7 @@ namespace dispatchkit
} }
} }
std::map<void *, Data > m_ptrs; std::map<const void *, Data > m_ptrs;
}; };
public: public:

View File

@ -52,6 +52,18 @@ namespace dispatchkit
} }
}; };
/**
* Used internally for handling a return value from a Proxy_Function call
*/
template<typename Ret>
struct Handle_Return<Ret *>
{
Boxed_Value operator()(const boost::function<Ret *()> &f)
{
return Boxed_Value(boost::ref(*f()));
}
};
/** /**
* Used internally for handling a return value from a Proxy_Function call * Used internally for handling a return value from a Proxy_Function call
*/ */

View File

@ -22,7 +22,7 @@ namespace dispatchkit
template<typename T, typename Class> template<typename T, typename Class>
T &get_member(T Class::* m, Class *obj) T &get_member(T Class::* m, Class *obj)
{ {
return obj->*m; return (obj->*m);
} }
/** /**
@ -33,7 +33,7 @@ namespace dispatchkit
template<typename T, typename Class> template<typename T, typename Class>
void register_member(Dispatch_Engine &s, T Class::* m, const std::string &name) void register_member(Dispatch_Engine &s, T Class::* m, const std::string &name)
{ {
s.register_function(boost::function<T (Class *)>(boost::bind(&get_member<T, Class>, m, _1)), name); s.register_function(boost::function<T& (Class *)>(boost::bind(&get_member<T, Class>, m, _1)), name);
} }
} }