You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
219 lines
7.1 KiB
219 lines
7.1 KiB
#ifndef BOOST_ARCHIVE_SHARED_PTR_HELPER_HPP |
|
#define BOOST_ARCHIVE_SHARED_PTR_HELPER_HPP |
|
|
|
// MS compatible compilers support #pragma once |
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020) |
|
# pragma once |
|
#endif |
|
|
|
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 |
|
// shared_ptr_helper.hpp: serialization for boost shared pointern |
|
|
|
// (C) Copyright 2004-2009 Robert Ramey, Martin Ecker and Takatoshi Kondo |
|
// Use, modification and distribution is subject to the Boost Software |
|
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
|
// http://www.boost.org/LICENSE_1_0.txt) |
|
|
|
// See http://www.boost.org for updates, documentation, and revision history. |
|
|
|
#include <set> |
|
#include <list> |
|
#include <utility> |
|
#include <cstddef> // NULL |
|
|
|
#include <boost/config.hpp> |
|
#include <boost/shared_ptr.hpp> |
|
|
|
#include <boost/type_traits/is_polymorphic.hpp> |
|
#include <boost/serialization/type_info_implementation.hpp> |
|
#include <boost/serialization/shared_ptr_132.hpp> |
|
#include <boost/serialization/throw_exception.hpp> |
|
|
|
#include <boost/archive/archive_exception.hpp> |
|
#include <boost/archive/detail/decl.hpp> |
|
|
|
#include <boost/archive/detail/abi_prefix.hpp> // must be the last headern |
|
|
|
namespace boost_132 { |
|
template<class T> class shared_ptr; |
|
} |
|
namespace boost { |
|
template<class T> class shared_ptr; |
|
namespace serialization { |
|
class extended_type_info; |
|
template<class Archive, class T> |
|
inline void load( |
|
Archive & ar, |
|
boost::shared_ptr< T > &t, |
|
const unsigned int file_version |
|
); |
|
} |
|
namespace archive{ |
|
namespace detail { |
|
|
|
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 |
|
// a common class for holding various types of shared pointers |
|
|
|
class shared_ptr_helper { |
|
struct collection_type_compare { |
|
bool operator()( |
|
const shared_ptr<const void> &lhs, |
|
const shared_ptr<const void> &rhs |
|
)const{ |
|
return lhs.get() < rhs.get(); |
|
} |
|
}; |
|
typedef std::set< |
|
boost::shared_ptr<const void>, |
|
collection_type_compare |
|
> collection_type; |
|
typedef collection_type::const_iterator iterator_type; |
|
// list of shared_pointers create accessable by raw pointer. This |
|
// is used to "match up" shared pointers loaded at different |
|
// points in the archive. Note, we delay construction until |
|
// it is actually used since this is by default included as |
|
// a "mix-in" even if shared_ptr isn't used. |
|
collection_type * m_pointers; |
|
|
|
struct null_deleter { |
|
void operator()(void const *) const {} |
|
}; |
|
|
|
struct void_deleter { |
|
const boost::serialization::extended_type_info * m_eti; |
|
void_deleter(const boost::serialization::extended_type_info *eti) : |
|
m_eti(eti) |
|
{} |
|
void operator()(void *vp) const { |
|
m_eti->destroy(vp); |
|
} |
|
}; |
|
|
|
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS |
|
public: |
|
#else |
|
template<class Archive, class T> |
|
friend inline void boost::serialization::load( |
|
Archive & ar, |
|
boost::shared_ptr< T > &t, |
|
const unsigned int file_version |
|
); |
|
#endif |
|
|
|
// #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP |
|
// list of loaded pointers. This is used to be sure that the pointers |
|
// stay around long enough to be "matched" with other pointers loaded |
|
// by the same archive. These are created with a "null_deleter" so that |
|
// when this list is destroyed - the underlaying raw pointers are not |
|
// destroyed. This has to be done because the pointers are also held by |
|
// new system which is disjoint from this set. This is implemented |
|
// by a change in load_construct_data below. It makes this file suitable |
|
// only for loading pointers into a 1.33 or later boost system. |
|
std::list<boost_132::shared_ptr<const void> > * m_pointers_132; |
|
// #endif |
|
|
|
// returns pointer to object and an indicator whether this is a |
|
// new entry (true) or a previous one (false) |
|
BOOST_ARCHIVE_DECL(shared_ptr<void>) |
|
get_od( |
|
const void * od, |
|
const boost::serialization::extended_type_info * true_type, |
|
const boost::serialization::extended_type_info * this_type |
|
); |
|
|
|
BOOST_ARCHIVE_DECL(void) |
|
append(const boost::shared_ptr<const void> &); |
|
|
|
template<class T> |
|
struct non_polymorphic { |
|
static const boost::serialization::extended_type_info * |
|
get_object_identifier(T & t){ |
|
return & boost::serialization::singleton< |
|
BOOST_DEDUCED_TYPENAME |
|
boost::serialization::type_info_implementation< T >::type |
|
>::get_const_instance(); |
|
} |
|
}; |
|
template<class T> |
|
struct polymorphic { |
|
static const boost::serialization::extended_type_info * |
|
get_object_identifier(T & t){ |
|
return boost::serialization::singleton< |
|
BOOST_DEDUCED_TYPENAME |
|
boost::serialization::type_info_implementation< T >::type |
|
>::get_const_instance().get_derived_extended_type_info(t); |
|
} |
|
}; |
|
public: |
|
template<class T> |
|
void reset(shared_ptr< T > & s, T * t){ |
|
if(NULL == t){ |
|
s.reset(); |
|
return; |
|
} |
|
const boost::serialization::extended_type_info * this_type |
|
= & boost::serialization::type_info_implementation< T >::type |
|
::get_const_instance(); |
|
|
|
// get pointer to the most derived object. This is effectively |
|
// the object identifern |
|
typedef BOOST_DEDUCED_TYPENAME mpl::eval_if< |
|
is_polymorphic< T >, |
|
mpl::identity<polymorphic< T > >, |
|
mpl::identity<non_polymorphic< T > > |
|
>::type type; |
|
|
|
const boost::serialization::extended_type_info * true_type |
|
= type::get_object_identifier(*t); |
|
|
|
// note:if this exception is thrown, be sure that derived pointern |
|
// is either registered or exported. |
|
if(NULL == true_type) |
|
boost::serialization::throw_exception( |
|
archive_exception( |
|
archive_exception::unregistered_class, |
|
this_type->get_debug_info() |
|
) |
|
); |
|
shared_ptr<void> r = |
|
get_od( |
|
static_cast<const void *>(t), |
|
true_type, |
|
this_type |
|
); |
|
if(!r){ |
|
s.reset(t); |
|
const void * od = void_downcast( |
|
*true_type, |
|
*this_type, |
|
static_cast<const void *>(t) |
|
); |
|
shared_ptr<const void> sp(s, od); |
|
append(sp); |
|
} |
|
else{ |
|
s = shared_ptr< T >( |
|
r, |
|
static_cast<T *>(r.get()) |
|
); |
|
} |
|
} |
|
|
|
// #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP |
|
BOOST_ARCHIVE_DECL(void) |
|
append(const boost_132::shared_ptr<const void> & t); |
|
// #endif |
|
public: |
|
BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) |
|
shared_ptr_helper(); |
|
BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) |
|
~shared_ptr_helper(); |
|
}; |
|
|
|
} // namespace detail |
|
} // namespace archive |
|
} // namespace boost |
|
|
|
#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas |
|
|
|
#endif // BOOST_ARCHIVE_SHARED_PTR_HELPER_HPP
|
|
|