export.hpp 8.3 KB

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