#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 |