register_archive.hpp 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // Copyright David Abrahams 2006. Distributed under the Boost
  2. // Software License, Version 1.0. (See accompanying
  3. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  4. #ifndef BOOST_ARCHIVE_DETAIL_REGISTER_ARCHIVE_DWA2006521_HPP
  5. # define BOOST_ARCHIVE_DETAIL_REGISTER_ARCHIVE_DWA2006521_HPP
  6. namespace boost { namespace archive { namespace detail {
  7. // No instantiate_ptr_serialization overloads generated by
  8. // BOOST_SERIALIZATION_REGISTER_ARCHIVE that lexically follow the call
  9. // will be seen *unless* they are in an associated namespace of one of
  10. // the arguments, so we pass one of these along to make sure this
  11. // namespace is considered. See temp.dep.candidate (14.6.4.2) in the
  12. // standard.
  13. struct adl_tag {};
  14. template <class Archive, class Serializable>
  15. struct ptr_serialization_support;
  16. // We could've just used ptr_serialization_support, above, but using
  17. // it with only a forward declaration causes vc6/7 to complain about a
  18. // missing instantiate member, even if it has one. This is just a
  19. // friendly layer of indirection.
  20. template <class Archive, class Serializable>
  21. struct _ptr_serialization_support
  22. : ptr_serialization_support<Archive,Serializable>
  23. {
  24. typedef int type;
  25. };
  26. #if defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x5130)
  27. template<int N>
  28. struct counter : counter<N-1> {};
  29. template<>
  30. struct counter<0> {};
  31. template<class Serializable>
  32. void instantiate_ptr_serialization(Serializable* s, int, adl_tag) {
  33. instantiate_ptr_serialization(s, counter<20>());
  34. }
  35. template<class Archive>
  36. struct get_counter {
  37. static const int value = sizeof(adjust_counter(counter<20>()));
  38. typedef counter<value> type;
  39. typedef counter<value - 1> prior;
  40. typedef char (&next)[value+1];
  41. };
  42. char adjust_counter(counter<0>);
  43. template<class Serializable>
  44. void instantiate_ptr_serialization(Serializable*, counter<0>) {}
  45. #define BOOST_SERIALIZATION_REGISTER_ARCHIVE(Archive) \
  46. namespace boost { namespace archive { namespace detail { \
  47. get_counter<Archive >::next adjust_counter(get_counter<Archive >::type);\
  48. template<class Serializable> \
  49. void instantiate_ptr_serialization(Serializable* s, \
  50. get_counter<Archive >::type) { \
  51. ptr_serialization_support<Archive, Serializable> x; \
  52. instantiate_ptr_serialization(s, get_counter<Archive >::prior()); \
  53. }\
  54. }}}
  55. #else
  56. // This function gets called, but its only purpose is to participate
  57. // in overload resolution with the functions declared by
  58. // BOOST_SERIALIZATION_REGISTER_ARCHIVE, below.
  59. template <class Serializable>
  60. void instantiate_ptr_serialization(Serializable*, int, adl_tag ) {}
  61. // The function declaration generated by this macro never actually
  62. // gets called, but its return type gets instantiated, and that's
  63. // enough to cause registration of serialization functions between
  64. // Archive and any exported Serializable type. See also:
  65. // boost/serialization/export.hpp
  66. # define BOOST_SERIALIZATION_REGISTER_ARCHIVE(Archive) \
  67. namespace boost { namespace archive { namespace detail { \
  68. \
  69. template <class Serializable> \
  70. typename _ptr_serialization_support<Archive, Serializable>::type \
  71. instantiate_ptr_serialization( Serializable*, Archive*, adl_tag ); \
  72. \
  73. }}}
  74. #endif
  75. }}} // namespace boost::archive::detail
  76. #endif // BOOST_ARCHIVE_DETAIL_INSTANTIATE_SERIALIZE_DWA2006521_HPP