Support serialization in DLLS

Make thread-safe
fix portable binary archives

[SVN r43691]
This commit is contained in:
Robert Ramey
2008-03-18 05:01:57 +00:00
parent cfb16a8a9d
commit 66b1028d4c
288 changed files with 94786 additions and 95244 deletions

View File

@@ -16,13 +16,15 @@
#include <cassert>
// STL
#include <set>
#include <vector>
#include <functional>
#include <algorithm>
#include <cassert>
// BOOST
#include <boost/shared_ptr.hpp>
#define BOOST_SERIALIZATION_SOURCE
#include <boost/serialization/singleton.hpp>
#define BOOST_SERIALIZATION_SOURCE
#include <boost/serialization/extended_type_info.hpp>
#include <boost/serialization/void_cast.hpp>
@@ -31,300 +33,242 @@ namespace boost {
namespace serialization {
namespace void_cast_detail {
#if 0
// registry of casting objects
struct void_caster_compare
{
bool
operator()(
shared_ptr<const void_caster> lhs,
shared_ptr<const void_caster> rhs ) const
{
if( lhs.get()->m_derived_type < rhs.get()->m_derived_type )
const void_caster * lhs,
const void_caster * rhs
) const {
if( lhs->m_derived < rhs->m_derived )
return true;
if( rhs.get()->m_derived_type < lhs.get()->m_derived_type)
return false;
if( lhs.get()->m_base_type < rhs.get()->m_base_type )
if( lhs->m_base < rhs->m_base )
return true;
return false;
}
};
struct null_deleter
{
void operator()(void const *) const
{}
};
typedef std::set<const void_caster *, void_caster_compare> set_type;
#endif
// it turns out that at least one compiler (msvc 6.0) doesn't guarentee
// to destroy static objects in exactly the reverse sequence that they
// are constructed. To guarentee this, use a singleton pattern
class void_caster_registry
{
typedef shared_ptr<const void_caster> value_type;
typedef std::set<value_type, void_caster_compare> set_type;
set_type m_set;
static void_caster_registry * m_self;
static void_caster_registry *
self(){
if(NULL == m_self){
static void_caster_registry instance;
m_self = & instance;
}
return m_self;
}
void_caster_registry(){}
public:
~void_caster_registry(){
m_self = 0;
}
typedef set_type::iterator iterator;
typedef set_type::const_iterator const_iterator;
static iterator
begin() {
return self()->m_set.begin();
}
static iterator
end() {
return self()->m_set.end();
}
static const_iterator
find(void_caster * vcp){
return self()->m_set.find(value_type(vcp, null_deleter()));
}
static std::pair<iterator, bool>
insert(const value_type & vcp){
return self()->m_set.insert(vcp);
}
static bool
empty(){
if(NULL == m_self)
return true;
return m_self->m_set.empty();
}
static void
purge(const extended_type_info * eti);
};
typedef std::vector<const void_caster *> set_type;
void_caster_registry * void_caster_registry::m_self = NULL;
typedef boost::serialization::singleton<set_type> void_caster_registry;
void
void_caster_registry::purge(const extended_type_info * eti){
if(NULL == m_self)
return;
if(! empty()){
iterator i = m_self->m_set.begin();
while(i != m_self->m_set.end()){
// note that the erase might invalidate i so save it here
iterator j = i++;
if((*j)->includes(eti))
m_self->m_set.erase(j);
}
}
inline bool
void_caster::operator==(void_caster const & rhs) const{
if(m_derived != rhs.m_derived)
return false;
if(m_base != rhs.m_base)
return false;
return true;
}
// implementation of void caster base class
BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY())
void_caster::void_caster(
extended_type_info const & derived_type_,
extended_type_info const & base_type_
extended_type_info const & derived,
extended_type_info const & base
) :
m_derived_type( derived_type_),
m_base_type(base_type_)
m_derived(derived),
m_base(base)
{}
BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY())
void_caster::~void_caster(){}
bool
void_caster::includes(const extended_type_info * eti) const {
return & m_derived_type == eti || & m_base_type == eti;
BOOST_SERIALIZATION_DECL(void)
void_caster::static_register() const {
void_caster_registry::get_mutable_instance().push_back(this);
// to do - add new void_caster_derived entries
// which can be generated by adding this new primitive
/*
while(){
if(!extend_down(this)
&& !extend_up(this))
break;
}
*/
}
void BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY())
void_caster::static_register(const void_caster * vcp)
{
void_caster_registry::insert(shared_ptr<const void_caster>(vcp, null_deleter()));
BOOST_SERIALIZATION_DECL(void)
void_caster::static_unregister() const {
void_cast_detail::set_type & st
= void_caster_registry::get_mutable_instance();
void_cast_detail::set_type::iterator it;
it = std::find(st.begin(), st.end(), this);
assert(st.end() != it);
st.erase(it);
// to do - remove all void_caster_derived entries
// which depend upon this primitive
/*
while(){
if(!truncate_down(this)
&& !truncate_up(this))
break;
}
*/
}
#if 0
// implementation of shortcut void caster
class void_caster_derived : public void_caster
{
std::ptrdiff_t difference;
virtual void const*
upcast( void const* t ) const{
return static_cast<const char*> ( t ) + difference;
virtual void const *
upcast(void const * const t) const{
return static_cast<const char *> ( t ) + difference;
}
virtual void const*
downcast( void const* t ) const{
return static_cast<const char*> ( t ) - difference;
virtual void const *
downcast(void const * const t) const{
return static_cast<const char *> ( t ) - difference;
}
public:
void_caster_derived(
extended_type_info const& derived_type_,
extended_type_info const& base_type_,
std::ptrdiff_t difference_
extended_type_info const & derived,
extended_type_info const & base,
std::ptrdiff_t difference
) :
void_caster(derived_type_, base_type_),
difference( difference_ )
{}
void_caster(derived, base),
difference( difference )
{
this->static_register();
}
~void_caster_derived(){
this->static_unregister();
}
};
#endif
// just used as a search key
class void_caster_argument : public void_caster
{
virtual void const*
upcast( void const* t ) const {
virtual void const *
upcast(void const * const t) const {
assert(false);
return NULL;
}
virtual void const*
downcast( void const* t ) const {
virtual void const *
downcast( void const * const t) const {
assert(false);
return NULL;
}
public:
void_caster_argument(
extended_type_info const& derived_type_,
extended_type_info const& base_type_
extended_type_info const & derived,
extended_type_info const & base
) :
void_caster(derived_type_, base_type_)
void_caster(derived, base)
{}
~void_caster_argument(){};
};
struct match {
void_cast_detail::void_caster_argument const * const m_ca;
match(void_cast_detail::void_caster_argument const * const ca) :
m_ca(ca)
{}
bool operator()(const void_cast_detail::void_caster * vc){
return * vc == * m_ca;
};
};
} // namespace void_cast_detail
void BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY())
unregister_void_casts(extended_type_info *eti)
{
void_cast_detail::void_caster_registry::purge(eti);
}
// Given a void *, assume that it really points to an instance of one type
// and alter it so that it would point to an instance of a related type.
// Return the altered pointer. If there exists no sequence of casts that
// can transform from_type to to_type, return a NULL.
BOOST_SERIALIZATION_DECL(void const *)
BOOST_SERIALIZATION_DECL(void const *)
void_upcast(
extended_type_info const & derived_type,
extended_type_info const & base_type,
void const * const t,
bool top
extended_type_info const & derived,
extended_type_info const & base,
void const * const t
){
// same types - trivial case
if (derived_type == base_type)
if (derived == base)
return t;
// check to see if base/derived pair is found in the registry
void_cast_detail::void_caster_argument ca(derived_type, base_type );
void_cast_detail::void_caster_registry::const_iterator it;
it = void_cast_detail::void_caster_registry::find( &ca );
const void * t_new = NULL;
// check to see if base/derived pair is found in the registry
const void_cast_detail::set_type & s
= void_cast_detail::void_caster_registry::get_const_instance();
void_cast_detail::set_type::const_iterator it;
void_cast_detail::void_caster_argument ca(derived, base);
it = std::find_if(
s.begin(),
s.end(),
void_cast_detail::match(& ca)
);
// if so
if (it != void_cast_detail::void_caster_registry::end())
if (s.end() != it)
// we're done
return (*it)->upcast(t);
// try to find a chain that gives us what we want
for(
it = void_cast_detail::void_caster_registry::begin();
it != void_cast_detail::void_caster_registry::end();
++it
){
for(it = s.begin(); it != s.end(); ++it){
// if the current candidate doesn't cast to the desired target type
if ((*it)->m_base_type == base_type){
if((*it)->m_base == base){
// if the current candidate casts from the desired source type
if ((*it)->m_derived_type == derived_type){
if ((*it)->m_derived == derived){
// we have a base/derived match - we're done
// cast to the intermediate type
t_new = (*it)->upcast(t);
break;
}
t_new = void_upcast(derived_type, (*it)->m_derived_type, t, false);
if (NULL != t_new){
t_new = (*it)->upcast(t_new);
assert(NULL != t_new);
if(top){
// register the this pair so we will have to go through
// keep this expensive search process more than once.
void_cast_detail::void_caster * vcp =
new void_cast_detail::void_caster_derived(
derived_type,
base_type,
static_cast<const char*>(t_new) - static_cast<const char*>(t)
);
void_cast_detail::void_caster_registry::insert(
shared_ptr<const void_cast_detail::void_caster>(vcp)
);
}
break;
return (*it)->upcast(t);
}
const void * t_new;
t_new = void_upcast(derived, (*it)->m_derived, t);
if(NULL != t_new)
return (*it)->upcast(t_new);
}
}
return t_new;
return NULL;
}
BOOST_SERIALIZATION_DECL(void const *)
BOOST_SERIALIZATION_DECL(void const *)
void_downcast(
const extended_type_info & derived_type,
const extended_type_info & base_type,
const void * const t,
bool top
extended_type_info const & derived,
extended_type_info const & base,
void const * const t
){
// same types - trivial case
if (derived_type == base_type)
if (derived == base)
return t;
// check to see if base/derived pair is found in the registry
void_cast_detail::void_caster_argument ca(derived_type, base_type );
void_cast_detail::void_caster_registry::const_iterator it;
it = void_cast_detail::void_caster_registry::find( &ca );
// if so
if (it != void_cast_detail::void_caster_registry::end())
// we're done
return (*it)->downcast(t);
const void * t_new = NULL;
// check to see if base/derived pair is found in the registry
const void_cast_detail::set_type & s
= void_cast_detail::void_caster_registry::get_const_instance();
void_cast_detail::set_type::const_iterator it;
void_cast_detail::void_caster_argument ca(derived, base);
it = std::find_if(
s.begin(),
s.end(),
void_cast_detail::match(& ca)
);
// if so
if (s.end() != it)
// we're done
return(*it)->downcast(t);
// try to find a chain that gives us what we want
for(
it = void_cast_detail::void_caster_registry::begin();
it != void_cast_detail::void_caster_registry::end();
++it
){
// if the current candidate doesn't casts from the desired target type
if ((*it)->m_derived_type == derived_type){
// if the current candidate casts to the desired source type
if ((*it)->m_base_type == base_type){
for(it = s.begin(); it != s.end(); ++it){
// if the current candidate doesn't cast to the desired target type
if ((*it)->m_derived == derived){
// if the current candidate casts from the desired source type
if ((*it)->m_base == base){
// we have a base/derived match - we're done
// cast to the intermediate type
t_new = (*it)->downcast(t);
break;
}
t_new = void_downcast((*it)->m_base_type, base_type, t, false);
if (NULL != t_new){
t_new = (*it)->downcast(t_new);
assert(NULL != t_new);
if(top){
// register the this pair so we will have to go through
// keep this expensive search process more than once.
void_cast_detail::void_caster * vcp =
new void_cast_detail::void_caster_derived(
derived_type,
base_type,
static_cast<const char*>(t) - static_cast<const char*>(t_new)
);
void_cast_detail::void_caster_registry::insert(
shared_ptr<const void_cast_detail::void_caster>(vcp)
);
}
break;
return (*it)->downcast(t);
}
const void * t_new;
t_new = void_downcast((*it)->m_base, base, t);
if(NULL != t_new)
return (*it)->downcast(t_new);
}
}
return t_new;
return NULL;
}
} // namespace serialization