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