export.hpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. #ifndef BOOST_SERIALIZATION_EXPORT_HPP
  2. #define BOOST_SERIALIZATION_EXPORT_HPP
  3. // MS compatible compilers support #pragma once
  4. #if defined(_MSC_VER)
  5. # pragma once
  6. #endif
  7. /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
  8. // export.hpp: set traits of classes to be serialized
  9. // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
  10. // Use, modification and distribution is subject to the Boost Software
  11. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  12. // http://www.boost.org/LICENSE_1_0.txt)
  13. // See http://www.boost.org for updates, documentation, and revision history.
  14. // (C) Copyright 2006 David Abrahams - http://www.boost.org.
  15. // implementation of class export functionality. This is an alternative to
  16. // "forward declaration" method to provoke instantiation of derived classes
  17. // that are to be serialized through pointers.
  18. #include <utility>
  19. #include <cstddef> // NULL
  20. #include <boost/config.hpp>
  21. #include <boost/static_assert.hpp>
  22. #include <boost/preprocessor/stringize.hpp>
  23. #include <boost/type_traits/is_polymorphic.hpp>
  24. #include <boost/mpl/assert.hpp>
  25. #include <boost/mpl/and.hpp>
  26. #include <boost/mpl/not.hpp>
  27. #include <boost/mpl/bool_fwd.hpp>
  28. #include <boost/serialization/extended_type_info.hpp> // for guid_defined only
  29. #include <boost/serialization/static_warning.hpp>
  30. #include <boost/serialization/assume_abstract.hpp>
  31. #include <boost/serialization/force_include.hpp>
  32. #include <boost/serialization/singleton.hpp>
  33. #include <boost/archive/detail/register_archive.hpp>
  34. namespace boost {
  35. namespace archive {
  36. namespace detail {
  37. class basic_pointer_iserializer;
  38. class basic_pointer_oserializer;
  39. template<class Archive, class T>
  40. class pointer_iserializer;
  41. template<class Archive, class T>
  42. class pointer_oserializer;
  43. template <class Archive, class Serializable>
  44. struct export_impl
  45. {
  46. static const basic_pointer_iserializer &
  47. enable_load(mpl::true_){
  48. return boost::serialization::singleton<
  49. pointer_iserializer<Archive, Serializable>
  50. >::get_const_instance();
  51. }
  52. static const basic_pointer_oserializer &
  53. enable_save(mpl::true_){
  54. return boost::serialization::singleton<
  55. pointer_oserializer<Archive, Serializable>
  56. >::get_const_instance();
  57. }
  58. inline static void enable_load(mpl::false_) {}
  59. inline static void enable_save(mpl::false_) {}
  60. };
  61. // On many platforms, naming a specialization of this template is
  62. // enough to cause its argument to be instantiated.
  63. template <void(*)()>
  64. struct instantiate_function {};
  65. template <class Archive, class Serializable>
  66. struct ptr_serialization_support
  67. {
  68. # if defined(BOOST_MSVC) || defined(__SUNPRO_CC)
  69. virtual BOOST_DLLEXPORT void instantiate() BOOST_USED;
  70. # else
  71. static BOOST_DLLEXPORT void instantiate() BOOST_USED;
  72. typedef instantiate_function<
  73. &ptr_serialization_support::instantiate
  74. > x;
  75. # endif
  76. };
  77. template <class Archive, class Serializable>
  78. BOOST_DLLEXPORT void
  79. ptr_serialization_support<Archive,Serializable>::instantiate()
  80. {
  81. export_impl<Archive,Serializable>::enable_save(
  82. typename Archive::is_saving()
  83. );
  84. export_impl<Archive,Serializable>::enable_load(
  85. typename Archive::is_loading()
  86. );
  87. }
  88. // Note INTENTIONAL usage of anonymous namespace in header.
  89. // This was made this way so that export.hpp could be included
  90. // in other headers. This is still under study.
  91. namespace extra_detail {
  92. template<class T>
  93. struct guid_initializer
  94. {
  95. void export_guid(mpl::false_) const {
  96. // generates the statically-initialized objects whose constructors
  97. // register the information allowing serialization of T objects
  98. // through pointers to their base classes.
  99. instantiate_ptr_serialization((T*)0, 0, adl_tag());
  100. }
  101. void export_guid(mpl::true_) const {
  102. }
  103. guid_initializer const & export_guid() const {
  104. BOOST_STATIC_WARNING(boost::is_polymorphic< T >::value);
  105. // note: exporting an abstract base class will have no effect
  106. // and cannot be used to instantitiate serialization code
  107. // (one might be using this in a DLL to instantiate code)
  108. //BOOST_STATIC_WARNING(! boost::serialization::is_abstract< T >::value);
  109. export_guid(boost::serialization::is_abstract< T >());
  110. return *this;
  111. }
  112. };
  113. template<typename T>
  114. struct init_guid;
  115. } // anonymous
  116. } // namespace detail
  117. } // namespace archive
  118. } // namespace boost
  119. #define BOOST_CLASS_EXPORT_IMPLEMENT(T) \
  120. namespace boost { \
  121. namespace archive { \
  122. namespace detail { \
  123. namespace extra_detail { \
  124. template<> \
  125. struct init_guid< T > { \
  126. static guid_initializer< T > const & g; \
  127. }; \
  128. guid_initializer< T > const & init_guid< T >::g = \
  129. ::boost::serialization::singleton< \
  130. guid_initializer< T > \
  131. >::get_mutable_instance().export_guid(); \
  132. }}}} \
  133. /**/
  134. #define BOOST_CLASS_EXPORT_KEY2(T, K) \
  135. namespace boost { \
  136. namespace serialization { \
  137. template<> \
  138. struct guid_defined< T > : boost::mpl::true_ {}; \
  139. template<> \
  140. inline const char * guid< T >(){ \
  141. return K; \
  142. } \
  143. } /* serialization */ \
  144. } /* boost */ \
  145. /**/
  146. #define BOOST_CLASS_EXPORT_KEY(T) \
  147. BOOST_CLASS_EXPORT_KEY2(T, BOOST_PP_STRINGIZE(T)) \
  148. /**/
  149. #define BOOST_CLASS_EXPORT_GUID(T, K) \
  150. BOOST_CLASS_EXPORT_KEY2(T, K) \
  151. BOOST_CLASS_EXPORT_IMPLEMENT(T) \
  152. /**/
  153. #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
  154. // CodeWarrior fails to construct static members of class templates
  155. // when they are instantiated from within templates, so on that
  156. // compiler we ask users to specifically register base/derived class
  157. // relationships for exported classes. On all other compilers, use of
  158. // this macro is entirely optional.
  159. # define BOOST_SERIALIZATION_MWERKS_BASE_AND_DERIVED(Base,Derived) \
  160. namespace { \
  161. static int BOOST_PP_CAT(boost_serialization_mwerks_init_, __LINE__) = \
  162. (::boost::archive::detail::instantiate_ptr_serialization((Derived*)0,0), 3); \
  163. static int BOOST_PP_CAT(boost_serialization_mwerks_init2_, __LINE__) = ( \
  164. ::boost::serialization::void_cast_register((Derived*)0,(Base*)0) \
  165. , 3); \
  166. }
  167. #else
  168. # define BOOST_SERIALIZATION_MWERKS_BASE_AND_DERIVED(Base,Derived)
  169. #endif
  170. // check for unnecessary export. T isn't polymorphic so there is no
  171. // need to export it.
  172. #define BOOST_CLASS_EXPORT_CHECK(T) \
  173. BOOST_STATIC_WARNING( \
  174. boost::is_polymorphic<U>::value \
  175. ); \
  176. /**/
  177. // the default exportable class identifier is the class name
  178. // the default list of archives types for which code id generated
  179. // are the originally included with this serialization system
  180. #define BOOST_CLASS_EXPORT(T) \
  181. BOOST_CLASS_EXPORT_GUID( \
  182. T, \
  183. BOOST_PP_STRINGIZE(T) \
  184. ) \
  185. /**/
  186. #endif // BOOST_SERIALIZATION_EXPORT_HPP