sl@0: #ifndef BOOST_SERIALIZATION_EXPORT_HPP sl@0: #define BOOST_SERIALIZATION_EXPORT_HPP sl@0: sl@0: // MS compatible compilers support #pragma once sl@0: #if defined(_MSC_VER) && (_MSC_VER >= 1020) sl@0: # pragma once sl@0: #endif sl@0: sl@0: /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 sl@0: // export.hpp: set traits of classes to be serialized sl@0: sl@0: // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . sl@0: // Use, modification and distribution is subject to the Boost Software sl@0: // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at sl@0: // http://www.boost.org/LICENSE_1_0.txt) sl@0: sl@0: // See http://www.boost.org for updates, documentation, and revision history. sl@0: sl@0: // implementation of class export functionality. This is an alternative to sl@0: // "forward declaration" method to provoke instantiation of derived classes sl@0: // that are to be serialized through pointers. sl@0: sl@0: #include sl@0: sl@0: #include sl@0: sl@0: // if no archive headers have been included this is a no op sl@0: // this is to permit BOOST_EXPORT etc to be included in a sl@0: // file declaration header sl@0: #if ! defined(BOOST_ARCHIVE_BASIC_ARCHIVE_HPP) sl@0: #define BOOST_CLASS_EXPORT_GUID_ARCHIVE_LIST(T, K, ASEQ) sl@0: sl@0: #else sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: namespace boost { sl@0: namespace archive { sl@0: namespace detail { sl@0: sl@0: // forward template declarations sl@0: class basic_pointer_iserializer; sl@0: template sl@0: BOOST_DLLEXPORT const basic_pointer_iserializer & sl@0: instantiate_pointer_iserializer(Archive * ar, T *) BOOST_USED; sl@0: sl@0: class basic_pointer_oserializer; sl@0: template sl@0: BOOST_DLLEXPORT const basic_pointer_oserializer & sl@0: instantiate_pointer_oserializer(Archive * ar, T *) BOOST_USED; sl@0: sl@0: namespace export_impl sl@0: { sl@0: struct nothing{ sl@0: static void instantiate(){} sl@0: }; sl@0: sl@0: template sl@0: struct archive { sl@0: struct i { sl@0: static void invoke(){ sl@0: instantiate_pointer_iserializer( sl@0: static_cast(NULL), sl@0: static_cast(NULL) sl@0: ); sl@0: } sl@0: }; sl@0: struct o { sl@0: static void invoke(){ sl@0: instantiate_pointer_oserializer( sl@0: static_cast(NULL), sl@0: static_cast(NULL) sl@0: ); sl@0: } sl@0: }; sl@0: static void instantiate(){ sl@0: #if defined(__GNUC__) && (__GNUC__ >= 3) sl@0: BOOST_STATIC_ASSERT( sl@0: Archive::is_loading::value || Archive::is_saving::value sl@0: ); sl@0: #endif sl@0: typedef BOOST_DEDUCED_TYPENAME mpl::eval_if< sl@0: BOOST_DEDUCED_TYPENAME Archive::is_saving, sl@0: mpl::identity, sl@0: // else sl@0: BOOST_DEDUCED_TYPENAME mpl::eval_if< sl@0: BOOST_DEDUCED_TYPENAME Archive::is_loading, sl@0: mpl::identity, sl@0: // else sl@0: mpl::identity sl@0: > >::type typex; sl@0: typex::invoke(); sl@0: } sl@0: }; sl@0: sl@0: template sl@0: struct for_each_archive { sl@0: private: sl@0: typedef BOOST_DEDUCED_TYPENAME mpl::pop_front::type tail; sl@0: typedef BOOST_DEDUCED_TYPENAME mpl::front::type head; sl@0: public: sl@0: static void instantiate(){ sl@0: archive::instantiate(); sl@0: typedef BOOST_DEDUCED_TYPENAME mpl::eval_if< sl@0: mpl::empty, sl@0: mpl::identity, sl@0: mpl::identity > sl@0: >::type typex; sl@0: typex::instantiate(); sl@0: } sl@0: }; sl@0: sl@0: } // namespace export_impl sl@0: sl@0: // strictly conforming sl@0: template sl@0: struct export_generator { sl@0: export_generator(){ sl@0: export_impl::for_each_archive::instantiate(); sl@0: } sl@0: static const export_generator instance; sl@0: }; sl@0: sl@0: template sl@0: const export_generator sl@0: export_generator::instance; sl@0: sl@0: // instantiation of this template creates a static object. sl@0: template sl@0: struct guid_initializer { sl@0: typedef BOOST_DEDUCED_TYPENAME boost::serialization::type_info_implementation::type eti_type; sl@0: static void export_register(const char *key){ sl@0: eti_type::export_register(key); sl@0: } sl@0: static const guid_initializer instance; sl@0: guid_initializer(const char *key = 0) BOOST_USED ; sl@0: }; sl@0: sl@0: template sl@0: guid_initializer::guid_initializer(const char *key){ sl@0: if(0 != key) sl@0: export_register(key); sl@0: } sl@0: sl@0: template sl@0: const guid_initializer guid_initializer::instance; sl@0: sl@0: // only gcc seems to be able to explicitly instantiate a static instance. sl@0: // but all can instantiate a function that refers to a static instance sl@0: sl@0: // the following optimization - inhibiting explicit instantiation for abstract sl@0: // classes breaks msvc compliles sl@0: template sl@0: struct export_instance { sl@0: struct abstract { sl@0: static const export_generator * sl@0: invoke(){ sl@0: return 0; sl@0: } sl@0: }; sl@0: struct not_abstract { sl@0: static const export_generator * sl@0: invoke(){ sl@0: return & export_generator::instance; sl@0: } sl@0: }; sl@0: }; sl@0: sl@0: template sl@0: BOOST_DLLEXPORT sl@0: std::pair *, const guid_initializer *> sl@0: export_instance_invoke() { sl@0: typedef BOOST_DEDUCED_TYPENAME mpl::eval_if< sl@0: serialization::is_abstract, sl@0: mpl::identity::abstract>, sl@0: mpl::identity::not_abstract> sl@0: >::type typex; sl@0: return std::pair *, const guid_initializer *>( sl@0: typex::invoke(), sl@0: & guid_initializer::instance sl@0: ); sl@0: } sl@0: sl@0: template sl@0: struct export_archives { sl@0: struct empty_archive_list { sl@0: static BOOST_DLLEXPORT sl@0: std::pair *, const guid_initializer *> sl@0: invoke(){ sl@0: return std::pair *, sl@0: const guid_initializer *>(0, 0); sl@0: } sl@0: }; sl@0: struct non_empty_archive_list { sl@0: static BOOST_DLLEXPORT sl@0: std::pair *, const guid_initializer *> sl@0: invoke(){ sl@0: return export_instance_invoke(); sl@0: } sl@0: }; sl@0: }; sl@0: sl@0: template sl@0: BOOST_DLLEXPORT sl@0: std::pair *, const guid_initializer *> sl@0: export_archives_invoke(T &, ASeq &){ sl@0: typedef BOOST_DEDUCED_TYPENAME mpl::eval_if< sl@0: mpl::empty, sl@0: mpl::identity::empty_archive_list>, sl@0: mpl::identity::non_empty_archive_list> sl@0: >::type typex; sl@0: return typex::invoke(); sl@0: } sl@0: sl@0: } // namespace detail sl@0: } // namespace archive sl@0: } // namespace boost sl@0: sl@0: #define BOOST_CLASS_EXPORT_GUID_ARCHIVE_LIST(T, K, ASEQ) \ sl@0: namespace boost { \ sl@0: namespace archive { \ sl@0: namespace detail { \ sl@0: template<> \ sl@0: const guid_initializer< T > \ sl@0: guid_initializer< T >::instance(K); \ sl@0: template \ sl@0: BOOST_DLLEXPORT \ sl@0: std::pair *, const guid_initializer< T > *> \ sl@0: export_archives_invoke(T &, ASEQ &); \ sl@0: } } } \ sl@0: /**/ sl@0: sl@0: #endif sl@0: sl@0: // check for unnecessary export. T isn't polymorphic so there is no sl@0: // need to export it. sl@0: #define BOOST_CLASS_EXPORT_CHECK(T) \ sl@0: BOOST_STATIC_WARNING( \ sl@0: boost::serialization::type_info_implementation< T > \ sl@0: ::type::is_polymorphic::value \ sl@0: ); \ sl@0: /**/ sl@0: sl@0: // the default list of archives types for which code id generated sl@0: #define BOOST_CLASS_EXPORT_GUID(T, K) \ sl@0: BOOST_CLASS_EXPORT_GUID_ARCHIVE_LIST( \ sl@0: T, \ sl@0: K, \ sl@0: boost::archive::detail::known_archive_types::type \ sl@0: ) \ sl@0: /**/ sl@0: sl@0: // the default exportable class identifier is the class name sl@0: #define BOOST_CLASS_EXPORT_ARCHIVE_LIST(T, ASEQ) \ sl@0: BOOST_CLASS_EXPORT_GUID_ARCHIVE_LIST(T, BOOST_PP_STRINGIZE(T), A) sl@0: sl@0: // the default exportable class identifier is the class name sl@0: // the default list of archives types for which code id generated sl@0: // are the originally included with this serialization system sl@0: #define BOOST_CLASS_EXPORT(T) \ sl@0: BOOST_CLASS_EXPORT_GUID_ARCHIVE_LIST( \ sl@0: T, \ sl@0: BOOST_PP_STRINGIZE(T), \ sl@0: boost::archive::detail::known_archive_types::type \ sl@0: ) \ sl@0: /**/ sl@0: sl@0: #endif // BOOST_SERIALIZATION_EXPORT_HPP