#ifndef BOOST_SERIALIZATION_EXPORT_HPP | |
#define BOOST_SERIALIZATION_EXPORT_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 | |
// export.hpp: set traits of classes to be serialized | |
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . | |
// 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. | |
// (C) Copyright 2006 David Abrahams - http://www.boost.org. | |
// implementation of class export functionality. This is an alternative to | |
// "forward declaration" method to provoke instantiation of derived classes | |
// that are to be serialized through pointers. | |
#include <utility> | |
#include <cstddef> // NULL | |
#include <boost/config.hpp> | |
#include <boost/static_assert.hpp> | |
#include <boost/preprocessor/stringize.hpp> | |
#include <boost/type_traits/is_polymorphic.hpp> | |
#include <boost/mpl/assert.hpp> | |
#include <boost/mpl/and.hpp> | |
#include <boost/mpl/not.hpp> | |
#include <boost/mpl/bool.hpp> | |
#include <boost/serialization/extended_type_info.hpp> // for guid_defined only | |
#include <boost/serialization/static_warning.hpp> | |
#include <boost/serialization/assume_abstract.hpp> | |
#include <boost/serialization/force_include.hpp> | |
#include <boost/serialization/singleton.hpp> | |
#include <boost/archive/detail/register_archive.hpp> | |
#include <iostream> | |
namespace boost { | |
namespace archive { | |
namespace detail { | |
class basic_pointer_iserializer; | |
class basic_pointer_oserializer; | |
template<class Archive, class T> | |
class pointer_iserializer; | |
template<class Archive, class T> | |
class pointer_oserializer; | |
template <class Archive, class Serializable> | |
struct export_impl | |
{ | |
static const basic_pointer_iserializer & | |
enable_load(mpl::true_){ | |
return boost::serialization::singleton< | |
pointer_iserializer<Archive, Serializable> | |
>::get_const_instance(); | |
} | |
static const basic_pointer_oserializer & | |
enable_save(mpl::true_){ | |
return boost::serialization::singleton< | |
pointer_oserializer<Archive, Serializable> | |
>::get_const_instance(); | |
} | |
inline static void enable_load(mpl::false_) {} | |
inline static void enable_save(mpl::false_) {} | |
}; | |
// On many platforms, naming a specialization of this template is | |
// enough to cause its argument to be instantiated. | |
template <void(*)()> | |
struct instantiate_function {}; | |
template <class Archive, class Serializable> | |
struct ptr_serialization_support | |
{ | |
# if defined(BOOST_MSVC) || defined(__SUNPRO_CC) | |
virtual BOOST_DLLEXPORT void instantiate() BOOST_USED; | |
# elif defined(__BORLANDC__) | |
static BOOST_DLLEXPORT void instantiate() BOOST_USED; | |
enum { x = sizeof(instantiate(),3) }; | |
# else | |
static BOOST_DLLEXPORT void instantiate() BOOST_USED; | |
typedef instantiate_function< | |
&ptr_serialization_support::instantiate | |
> x; | |
# endif | |
}; | |
template <class Archive, class Serializable> | |
BOOST_DLLEXPORT void | |
ptr_serialization_support<Archive,Serializable>::instantiate() | |
{ | |
export_impl<Archive,Serializable>::enable_save( | |
#if ! defined(__BORLANDC__) | |
BOOST_DEDUCED_TYPENAME | |
#endif | |
Archive::is_saving() | |
); | |
export_impl<Archive,Serializable>::enable_load( | |
#if ! defined(__BORLANDC__) | |
BOOST_DEDUCED_TYPENAME | |
#endif | |
Archive::is_loading() | |
); | |
} | |
// Note INTENTIONAL usage of anonymous namespace in header. | |
// This was made this way so that export.hpp could be included | |
// in other headers. This is still under study. | |
namespace extra_detail { | |
template<class T> | |
struct guid_initializer | |
{ | |
void export_guid(mpl::false_) const { | |
// generates the statically-initialized objects whose constructors | |
// register the information allowing serialization of T objects | |
// through pointers to their base classes. | |
instantiate_ptr_serialization((T*)0, 0, adl_tag()); | |
} | |
const void export_guid(mpl::true_) const { | |
} | |
guid_initializer const & export_guid() const { | |
BOOST_STATIC_WARNING(boost::is_polymorphic< T >::value); | |
// note: exporting an abstract base class will have no effect | |
// and cannot be used to instantitiate serialization code | |
// (one might be using this in a DLL to instantiate code) | |
//BOOST_STATIC_WARNING(! boost::serialization::is_abstract< T >::value); | |
export_guid(boost::serialization::is_abstract< T >()); | |
return *this; | |
} | |
}; | |
template<typename T> | |
struct init_guid; | |
} // anonymous | |
} // namespace detail | |
} // namespace archive | |
} // namespace boost | |
#define BOOST_CLASS_EXPORT_IMPLEMENT(T) \ | |
namespace boost { \ | |
namespace archive { \ | |
namespace detail { \ | |
namespace extra_detail { \ | |
template<> \ | |
struct init_guid< T > { \ | |
static guid_initializer< T > const & g; \ | |
}; \ | |
guid_initializer< T > const & init_guid< T >::g = \ | |
::boost::serialization::singleton< \ | |
guid_initializer< T > \ | |
>::get_mutable_instance().export_guid(); \ | |
}}}} \ | |
/**/ | |
#define BOOST_CLASS_EXPORT_KEY2(T, K) \ | |
namespace boost { \ | |
namespace serialization { \ | |
template<> \ | |
struct guid_defined< T > : boost::mpl::true_ {}; \ | |
template<> \ | |
inline const char * guid< T >(){ \ | |
return K; \ | |
} \ | |
} /* serialization */ \ | |
} /* boost */ \ | |
/**/ | |
#define BOOST_CLASS_EXPORT_KEY(T) \ | |
BOOST_CLASS_EXPORT_KEY2(T, BOOST_PP_STRINGIZE(T)) \ | |
/**/ | |
#define BOOST_CLASS_EXPORT_GUID(T, K) \ | |
BOOST_CLASS_EXPORT_KEY2(T, K) \ | |
BOOST_CLASS_EXPORT_IMPLEMENT(T) \ | |
/**/ | |
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) | |
// CodeWarrior fails to construct static members of class templates | |
// when they are instantiated from within templates, so on that | |
// compiler we ask users to specifically register base/derived class | |
// relationships for exported classes. On all other compilers, use of | |
// this macro is entirely optional. | |
# define BOOST_SERIALIZATION_MWERKS_BASE_AND_DERIVED(Base,Derived) \ | |
namespace { \ | |
static int BOOST_PP_CAT(boost_serialization_mwerks_init_, __LINE__) = \ | |
(::boost::archive::detail::instantiate_ptr_serialization((Derived*)0,0), 3); \ | |
static int BOOST_PP_CAT(boost_serialization_mwerks_init2_, __LINE__) = ( \ | |
::boost::serialization::void_cast_register((Derived*)0,(Base*)0) \ | |
, 3); \ | |
} | |
#else | |
# define BOOST_SERIALIZATION_MWERKS_BASE_AND_DERIVED(Base,Derived) | |
#endif | |
// check for unnecessary export. T isn't polymorphic so there is no | |
// need to export it. | |
#define BOOST_CLASS_EXPORT_CHECK(T) \ | |
BOOST_STATIC_WARNING( \ | |
boost::is_polymorphic<U>::value \ | |
); \ | |
/**/ | |
// the default exportable class identifier is the class name | |
// the default list of archives types for which code id generated | |
// are the originally included with this serialization system | |
#define BOOST_CLASS_EXPORT(T) \ | |
BOOST_CLASS_EXPORT_GUID( \ | |
T, \ | |
BOOST_PP_STRINGIZE(T) \ | |
) \ | |
/**/ | |
#endif // BOOST_SERIALIZATION_EXPORT_HPP | |