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