]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | #ifndef BOOST_SERIALIZATION_EXPORT_HPP |
2 | #define BOOST_SERIALIZATION_EXPORT_HPP | |
3 | ||
4 | // MS compatible compilers support #pragma once | |
5 | #if defined(_MSC_VER) | |
6 | # pragma once | |
7 | #endif | |
8 | ||
9 | /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 | |
10 | // export.hpp: set traits of classes to be serialized | |
11 | ||
12 | // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . | |
13 | // Use, modification and distribution is subject to the Boost Software | |
14 | // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
15 | // http://www.boost.org/LICENSE_1_0.txt) | |
16 | ||
17 | // See http://www.boost.org for updates, documentation, and revision history. | |
18 | ||
19 | // (C) Copyright 2006 David Abrahams - http://www.boost.org. | |
20 | // implementation of class export functionality. This is an alternative to | |
21 | // "forward declaration" method to provoke instantiation of derived classes | |
22 | // that are to be serialized through pointers. | |
23 | ||
24 | #include <utility> | |
25 | #include <cstddef> // NULL | |
26 | ||
27 | #include <boost/config.hpp> | |
28 | #include <boost/static_assert.hpp> | |
29 | #include <boost/preprocessor/stringize.hpp> | |
30 | #include <boost/type_traits/is_polymorphic.hpp> | |
31 | ||
32 | #include <boost/mpl/assert.hpp> | |
33 | #include <boost/mpl/and.hpp> | |
34 | #include <boost/mpl/not.hpp> | |
35 | #include <boost/mpl/bool_fwd.hpp> | |
36 | ||
37 | #include <boost/serialization/extended_type_info.hpp> // for guid_defined only | |
38 | #include <boost/serialization/static_warning.hpp> | |
39 | #include <boost/serialization/assume_abstract.hpp> | |
40 | #include <boost/serialization/force_include.hpp> | |
41 | #include <boost/serialization/singleton.hpp> | |
42 | ||
43 | #include <boost/archive/detail/register_archive.hpp> | |
44 | ||
7c673cae FG |
45 | namespace boost { |
46 | namespace archive { | |
47 | namespace detail { | |
48 | ||
49 | class basic_pointer_iserializer; | |
50 | class basic_pointer_oserializer; | |
51 | ||
52 | template<class Archive, class T> | |
53 | class pointer_iserializer; | |
54 | template<class Archive, class T> | |
55 | class pointer_oserializer; | |
56 | ||
57 | template <class Archive, class Serializable> | |
58 | struct export_impl | |
59 | { | |
60 | static const basic_pointer_iserializer & | |
61 | enable_load(mpl::true_){ | |
62 | return boost::serialization::singleton< | |
f67539c2 | 63 | pointer_iserializer<Archive, Serializable> |
7c673cae FG |
64 | >::get_const_instance(); |
65 | } | |
66 | ||
67 | static const basic_pointer_oserializer & | |
68 | enable_save(mpl::true_){ | |
69 | return boost::serialization::singleton< | |
f67539c2 | 70 | pointer_oserializer<Archive, Serializable> |
7c673cae FG |
71 | >::get_const_instance(); |
72 | } | |
73 | inline static void enable_load(mpl::false_) {} | |
74 | inline static void enable_save(mpl::false_) {} | |
75 | }; | |
76 | ||
77 | // On many platforms, naming a specialization of this template is | |
78 | // enough to cause its argument to be instantiated. | |
79 | template <void(*)()> | |
80 | struct instantiate_function {}; | |
81 | ||
82 | template <class Archive, class Serializable> | |
83 | struct ptr_serialization_support | |
84 | { | |
85 | # if defined(BOOST_MSVC) || defined(__SUNPRO_CC) | |
86 | virtual BOOST_DLLEXPORT void instantiate() BOOST_USED; | |
87 | # else | |
88 | static BOOST_DLLEXPORT void instantiate() BOOST_USED; | |
89 | typedef instantiate_function< | |
90 | &ptr_serialization_support::instantiate | |
91 | > x; | |
92 | # endif | |
93 | }; | |
94 | ||
95 | template <class Archive, class Serializable> | |
f67539c2 | 96 | BOOST_DLLEXPORT void |
7c673cae FG |
97 | ptr_serialization_support<Archive,Serializable>::instantiate() |
98 | { | |
99 | export_impl<Archive,Serializable>::enable_save( | |
100 | typename Archive::is_saving() | |
101 | ); | |
102 | ||
103 | export_impl<Archive,Serializable>::enable_load( | |
104 | typename Archive::is_loading() | |
105 | ); | |
106 | } | |
107 | ||
108 | // Note INTENTIONAL usage of anonymous namespace in header. | |
109 | // This was made this way so that export.hpp could be included | |
110 | // in other headers. This is still under study. | |
111 | ||
112 | namespace extra_detail { | |
113 | ||
114 | template<class T> | |
115 | struct guid_initializer | |
116 | { | |
117 | void export_guid(mpl::false_) const { | |
118 | // generates the statically-initialized objects whose constructors | |
119 | // register the information allowing serialization of T objects | |
120 | // through pointers to their base classes. | |
121 | instantiate_ptr_serialization((T*)0, 0, adl_tag()); | |
122 | } | |
123 | void export_guid(mpl::true_) const { | |
124 | } | |
125 | guid_initializer const & export_guid() const { | |
126 | BOOST_STATIC_WARNING(boost::is_polymorphic< T >::value); | |
127 | // note: exporting an abstract base class will have no effect | |
128 | // and cannot be used to instantitiate serialization code | |
129 | // (one might be using this in a DLL to instantiate code) | |
130 | //BOOST_STATIC_WARNING(! boost::serialization::is_abstract< T >::value); | |
131 | export_guid(boost::serialization::is_abstract< T >()); | |
132 | return *this; | |
133 | } | |
134 | }; | |
135 | ||
136 | template<typename T> | |
137 | struct init_guid; | |
138 | ||
139 | } // anonymous | |
140 | } // namespace detail | |
141 | } // namespace archive | |
142 | } // namespace boost | |
143 | ||
144 | #define BOOST_CLASS_EXPORT_IMPLEMENT(T) \ | |
145 | namespace boost { \ | |
146 | namespace archive { \ | |
147 | namespace detail { \ | |
148 | namespace extra_detail { \ | |
149 | template<> \ | |
150 | struct init_guid< T > { \ | |
151 | static guid_initializer< T > const & g; \ | |
152 | }; \ | |
153 | guid_initializer< T > const & init_guid< T >::g = \ | |
154 | ::boost::serialization::singleton< \ | |
155 | guid_initializer< T > \ | |
156 | >::get_mutable_instance().export_guid(); \ | |
157 | }}}} \ | |
158 | /**/ | |
159 | ||
160 | #define BOOST_CLASS_EXPORT_KEY2(T, K) \ | |
161 | namespace boost { \ | |
162 | namespace serialization { \ | |
163 | template<> \ | |
164 | struct guid_defined< T > : boost::mpl::true_ {}; \ | |
165 | template<> \ | |
166 | inline const char * guid< T >(){ \ | |
167 | return K; \ | |
168 | } \ | |
169 | } /* serialization */ \ | |
170 | } /* boost */ \ | |
171 | /**/ | |
172 | ||
173 | #define BOOST_CLASS_EXPORT_KEY(T) \ | |
174 | BOOST_CLASS_EXPORT_KEY2(T, BOOST_PP_STRINGIZE(T)) \ | |
175 | /**/ | |
176 | ||
177 | #define BOOST_CLASS_EXPORT_GUID(T, K) \ | |
178 | BOOST_CLASS_EXPORT_KEY2(T, K) \ | |
179 | BOOST_CLASS_EXPORT_IMPLEMENT(T) \ | |
180 | /**/ | |
181 | ||
182 | #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) | |
183 | ||
184 | // CodeWarrior fails to construct static members of class templates | |
185 | // when they are instantiated from within templates, so on that | |
186 | // compiler we ask users to specifically register base/derived class | |
187 | // relationships for exported classes. On all other compilers, use of | |
188 | // this macro is entirely optional. | |
189 | # define BOOST_SERIALIZATION_MWERKS_BASE_AND_DERIVED(Base,Derived) \ | |
190 | namespace { \ | |
191 | static int BOOST_PP_CAT(boost_serialization_mwerks_init_, __LINE__) = \ | |
192 | (::boost::archive::detail::instantiate_ptr_serialization((Derived*)0,0), 3); \ | |
193 | static int BOOST_PP_CAT(boost_serialization_mwerks_init2_, __LINE__) = ( \ | |
194 | ::boost::serialization::void_cast_register((Derived*)0,(Base*)0) \ | |
195 | , 3); \ | |
196 | } | |
197 | ||
198 | #else | |
199 | ||
200 | # define BOOST_SERIALIZATION_MWERKS_BASE_AND_DERIVED(Base,Derived) | |
201 | ||
f67539c2 | 202 | #endif |
7c673cae FG |
203 | |
204 | // check for unnecessary export. T isn't polymorphic so there is no | |
205 | // need to export it. | |
206 | #define BOOST_CLASS_EXPORT_CHECK(T) \ | |
207 | BOOST_STATIC_WARNING( \ | |
208 | boost::is_polymorphic<U>::value \ | |
209 | ); \ | |
210 | /**/ | |
211 | ||
212 | // the default exportable class identifier is the class name | |
213 | // the default list of archives types for which code id generated | |
214 | // are the originally included with this serialization system | |
215 | #define BOOST_CLASS_EXPORT(T) \ | |
216 | BOOST_CLASS_EXPORT_GUID( \ | |
217 | T, \ | |
218 | BOOST_PP_STRINGIZE(T) \ | |
219 | ) \ | |
220 | /**/ | |
221 | ||
222 | #endif // BOOST_SERIALIZATION_EXPORT_HPP | |
223 |