export.hpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. #ifndef BOOST_SERIALIZATION_EXPORT_HPP
  2. #define BOOST_SERIALIZATION_EXPORT_HPP
  3. // MS compatible compilers support #pragma once
  4. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  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. #ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO
  25. #include <boost/serialization/extended_type_info_typeid.hpp>
  26. #endif
  27. #include <boost/serialization/static_warning.hpp>
  28. #include <boost/serialization/type_info_implementation.hpp>
  29. #include <boost/serialization/assume_abstract.hpp>
  30. #include <boost/serialization/force_include.hpp>
  31. #include <boost/serialization/singleton.hpp>
  32. #include <boost/archive/detail/register_archive.hpp>
  33. #include <boost/mpl/assert.hpp>
  34. #include <boost/mpl/and.hpp>
  35. #include <boost/mpl/not.hpp>
  36. #include <boost/mpl/bool.hpp>
  37. #include <iostream>
  38. namespace boost {
  39. namespace archive {
  40. namespace detail {
  41. class basic_pointer_iserializer;
  42. class basic_pointer_oserializer;
  43. template<class Archive, class T>
  44. class pointer_iserializer;
  45. template<class Archive, class T>
  46. class pointer_oserializer;
  47. template <class Archive, class Serializable>
  48. struct export_impl
  49. {
  50. static const basic_pointer_iserializer &
  51. enable_load(mpl::true_){
  52. return boost::serialization::singleton<
  53. pointer_iserializer<Archive, Serializable>
  54. >::get_const_instance();
  55. }
  56. static const basic_pointer_oserializer &
  57. enable_save(mpl::true_){
  58. return boost::serialization::singleton<
  59. pointer_oserializer<Archive, Serializable>
  60. >::get_const_instance();
  61. }
  62. inline static void enable_load(mpl::false_) {}
  63. inline static void enable_save(mpl::false_) {}
  64. };
  65. // On many platforms, naming a specialization of this template is
  66. // enough to cause its argument to be instantiated.
  67. template <void(*)()>
  68. struct instantiate_function {};
  69. template <class Archive, class Serializable>
  70. struct ptr_serialization_support
  71. {
  72. # if defined(BOOST_MSVC) || defined(__SUNPRO_CC)
  73. virtual BOOST_DLLEXPORT void instantiate() BOOST_USED;
  74. # elif defined(__BORLANDC__)
  75. static BOOST_DLLEXPORT void instantiate() BOOST_USED;
  76. enum { x = sizeof(instantiate(),3) };
  77. # else
  78. static BOOST_DLLEXPORT void instantiate() BOOST_USED;
  79. typedef instantiate_function<
  80. &ptr_serialization_support::instantiate
  81. > x;
  82. # endif
  83. };
  84. template <class Archive, class Serializable>
  85. BOOST_DLLEXPORT void
  86. ptr_serialization_support<Archive,Serializable>::instantiate()
  87. {
  88. export_impl<Archive,Serializable>::enable_save(
  89. #if ! defined(__BORLANDC__)
  90. BOOST_DEDUCED_TYPENAME
  91. #endif
  92. Archive::is_saving()
  93. );
  94. export_impl<Archive,Serializable>::enable_load(
  95. #if ! defined(__BORLANDC__)
  96. BOOST_DEDUCED_TYPENAME
  97. #endif
  98. Archive::is_loading()
  99. );
  100. }
  101. namespace {
  102. template<class T>
  103. struct guid_initializer
  104. {
  105. const guid_initializer & export_guid(char const* /* key */, mpl::false_){
  106. // generates the statically-initialized objects whose constructors
  107. // register the information allowing serialization of T objects
  108. // through pointers to their base classes.
  109. instantiate_ptr_serialization((T*)0, 0, adl_tag());
  110. return *this;
  111. }
  112. const guid_initializer & export_guid(char const* /*key*/, mpl::true_){
  113. return *this;
  114. }
  115. const guid_initializer & export_guid(char const* key){
  116. BOOST_STATIC_WARNING(boost::is_polymorphic<T>::value);
  117. assert(NULL != key);
  118. boost::serialization::singleton<
  119. BOOST_DEDUCED_TYPENAME
  120. boost::serialization::type_info_implementation<T>::type
  121. >::get_mutable_instance().key_register(key);
  122. // note: exporting an abstract base class will have no effect
  123. // and cannot be used to instantitiate serialization code
  124. // (one might be using this in a DLL to instantiate code)
  125. //BOOST_STATIC_WARNING(! boost::serialization::is_abstract<T>::value);
  126. return export_guid(key, boost::serialization::is_abstract<T>());
  127. }
  128. };
  129. template<typename T>
  130. struct init_guid;
  131. } // anonymous
  132. } // namespace detail
  133. } // namespace archive
  134. } // namespace boost
  135. #define BOOST_CLASS_EXPORT_GUID(T, K) \
  136. namespace boost { \
  137. namespace archive { \
  138. namespace detail { \
  139. namespace { \
  140. template<> \
  141. struct init_guid< T > { \
  142. static ::boost::archive::detail::guid_initializer< T > const \
  143. & guid_initializer; \
  144. }; \
  145. ::boost::archive::detail::guid_initializer< T > const & \
  146. ::boost::archive::detail::init_guid< T >::guid_initializer = \
  147. ::boost::serialization::singleton< \
  148. ::boost::archive::detail::guid_initializer< T > \
  149. >::get_mutable_instance().export_guid(K); \
  150. }}}} \
  151. /**/
  152. #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
  153. // CodeWarrior fails to construct static members of class templates
  154. // when they are instantiated from within templates, so on that
  155. // compiler we ask users to specifically register base/derived class
  156. // relationships for exported classes. On all other compilers, use of
  157. // this macro is entirely optional.
  158. # define BOOST_SERIALIZATION_MWERKS_BASE_AND_DERIVED(Base,Derived) \
  159. namespace { \
  160. static int BOOST_PP_CAT(boost_serialization_mwerks_init_, __LINE__) = \
  161. (::boost::archive::detail::instantiate_ptr_serialization((Derived*)0,0), 3); \
  162. static int BOOST_PP_CAT(boost_serialization_mwerks_init2_, __LINE__) = ( \
  163. ::boost::serialization::void_cast_register((Derived*)0,(Base*)0) \
  164. , 3); \
  165. }
  166. #else
  167. # define BOOST_SERIALIZATION_MWERKS_BASE_AND_DERIVED(Base,Derived)
  168. #endif
  169. // check for unnecessary export. T isn't polymorphic so there is no
  170. // need to export it.
  171. #define BOOST_CLASS_EXPORT_CHECK(T) \
  172. BOOST_STATIC_WARNING( \
  173. boost::is_polymorphic<U>::value \
  174. ); \
  175. /**/
  176. // the default exportable class identifier is the class name
  177. // the default list of archives types for which code id generated
  178. // are the originally included with this serialization system
  179. #define BOOST_CLASS_EXPORT(T) \
  180. BOOST_CLASS_EXPORT_GUID( \
  181. T, \
  182. BOOST_PP_STRINGIZE(T) \
  183. ) \
  184. /**/
  185. #endif // BOOST_SERIALIZATION_EXPORT_HPP