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
7namespace 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.
15struct adl_tag {};
16
17template <class Archive, class Serializable>
18struct 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.
24template <class Archive, class Serializable>
25struct _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
33template<int N>
34struct counter : counter<N-1> {};
35template<>
36struct counter<0> {};
37
38template<class Serializable>
39void instantiate_ptr_serialization(Serializable* s, int, adl_tag) {
40 instantiate_ptr_serialization(s, counter<20>());
41}
42
43template<class Archive>
44struct 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
51char adjust_counter(counter<0>);
52template<class Serializable>
53void instantiate_ptr_serialization(Serializable*, counter<0>) {}
54
55#define BOOST_SERIALIZATION_REGISTER_ARCHIVE(Archive) \
56namespace 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.
72template <class Serializable>
73void 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) \
81namespace boost { namespace archive { namespace detail { \
82 \
83template <class Serializable> \
84typename _ptr_serialization_support<Archive, Serializable>::type \
85instantiate_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