1 #ifndef BOOST_SERIALIZATION_EXPORT_HPP
2 #define BOOST_SERIALIZATION_EXPORT_HPP
4 // MS compatible compilers support #pragma once
5 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
9 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
10 // export.hpp: set traits of classes to be serialized
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)
17 // See http://www.boost.org for updates, documentation, and revision history.
19 // implementation of class export functionality. This is an alternative to
20 // "forward declaration" method to provoke instantiation of derived classes
21 // that are to be serialized through pointers.
25 #include <boost/config.hpp>
27 // if no archive headers have been included this is a no op
28 // this is to permit BOOST_EXPORT etc to be included in a
29 // file declaration header
30 #if ! defined(BOOST_ARCHIVE_BASIC_ARCHIVE_HPP)
31 #define BOOST_CLASS_EXPORT_GUID_ARCHIVE_LIST(T, K, ASEQ)
34 #include <boost/static_assert.hpp>
35 #include <boost/preprocessor/stringize.hpp>
36 #include <boost/mpl/eval_if.hpp>
37 #include <boost/mpl/or.hpp>
38 #include <boost/mpl/empty.hpp>
39 #include <boost/mpl/front.hpp>
40 #include <boost/mpl/pop_front.hpp>
41 #include <boost/mpl/void.hpp>
42 #include <boost/mpl/identity.hpp>
44 #include <boost/archive/detail/known_archive_types.hpp>
45 #include <boost/serialization/force_include.hpp>
46 #include <boost/serialization/type_info_implementation.hpp>
47 #include <boost/serialization/is_abstract.hpp>
53 // forward template declarations
54 class basic_pointer_iserializer;
55 template<class Archive, class T>
56 BOOST_DLLEXPORT const basic_pointer_iserializer &
57 instantiate_pointer_iserializer(Archive * ar, T *) BOOST_USED;
59 class basic_pointer_oserializer;
60 template<class Archive, class T>
61 BOOST_DLLEXPORT const basic_pointer_oserializer &
62 instantiate_pointer_oserializer(Archive * ar, T *) BOOST_USED;
67 static void instantiate(){}
70 template<class Archive, class T>
74 instantiate_pointer_iserializer(
75 static_cast<Archive *>(NULL),
76 static_cast<T *>(NULL)
82 instantiate_pointer_oserializer(
83 static_cast<Archive *>(NULL),
84 static_cast<T *>(NULL)
88 static void instantiate(){
89 #if defined(__GNUC__) && (__GNUC__ >= 3)
91 Archive::is_loading::value || Archive::is_saving::value
94 typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
95 BOOST_DEDUCED_TYPENAME Archive::is_saving,
98 BOOST_DEDUCED_TYPENAME mpl::eval_if<
99 BOOST_DEDUCED_TYPENAME Archive::is_loading,
102 mpl::identity<nothing>
108 template<class ASeq, class T>
109 struct for_each_archive {
111 typedef BOOST_DEDUCED_TYPENAME mpl::pop_front<ASeq>::type tail;
112 typedef BOOST_DEDUCED_TYPENAME mpl::front<ASeq>::type head;
114 static void instantiate(){
115 archive<head, T>::instantiate();
116 typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
118 mpl::identity<nothing>,
119 mpl::identity<for_each_archive<tail, T> >
121 typex::instantiate();
125 } // namespace export_impl
127 // strictly conforming
128 template<class T, class ASeq>
129 struct export_generator {
131 export_impl::for_each_archive<ASeq, T>::instantiate();
133 static const export_generator instance;
136 template<class T, class ASeq>
137 const export_generator<T, ASeq>
138 export_generator<T, ASeq>::instance;
140 // instantiation of this template creates a static object.
142 struct guid_initializer {
143 typedef BOOST_DEDUCED_TYPENAME boost::serialization::type_info_implementation<T>::type eti_type;
144 static void export_register(const char *key){
145 eti_type::export_register(key);
147 static const guid_initializer instance;
148 guid_initializer(const char *key = 0) BOOST_USED ;
152 guid_initializer<T>::guid_initializer(const char *key){
154 export_register(key);
158 const guid_initializer<T> guid_initializer<T>::instance;
160 // only gcc seems to be able to explicitly instantiate a static instance.
161 // but all can instantiate a function that refers to a static instance
163 // the following optimization - inhibiting explicit instantiation for abstract
164 // classes breaks msvc compliles
165 template<class T, class ASeq>
166 struct export_instance {
168 static const export_generator<T, ASeq> *
173 struct not_abstract {
174 static const export_generator<T, ASeq> *
176 return & export_generator<T, ASeq>::instance;
181 template<class T, class ASeq>
183 std::pair<const export_generator<T, ASeq> *, const guid_initializer<T> *>
184 export_instance_invoke() {
185 typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
186 serialization::is_abstract<T>,
187 mpl::identity<BOOST_DEDUCED_TYPENAME export_instance<T, ASeq>::abstract>,
188 mpl::identity<BOOST_DEDUCED_TYPENAME export_instance<T, ASeq>::not_abstract>
190 return std::pair<const export_generator<T, ASeq> *, const guid_initializer<T> *>(
192 & guid_initializer<T>::instance
196 template<class T, class ASeq>
197 struct export_archives {
198 struct empty_archive_list {
199 static BOOST_DLLEXPORT
200 std::pair<const export_generator<T, ASeq> *, const guid_initializer<T> *>
202 return std::pair<const export_generator<T, ASeq> *,
203 const guid_initializer<T> *>(0, 0);
206 struct non_empty_archive_list {
207 static BOOST_DLLEXPORT
208 std::pair<const export_generator<T, ASeq> *, const guid_initializer<T> *>
210 return export_instance_invoke<T, ASeq>();
215 template<class T, class ASeq>
217 std::pair<const export_generator<T, ASeq> *, const guid_initializer<T> *>
218 export_archives_invoke(T &, ASeq &){
219 typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
221 mpl::identity<BOOST_DEDUCED_TYPENAME export_archives<T, ASeq>::empty_archive_list>,
222 mpl::identity<BOOST_DEDUCED_TYPENAME export_archives<T, ASeq>::non_empty_archive_list>
224 return typex::invoke();
227 } // namespace detail
228 } // namespace archive
231 #define BOOST_CLASS_EXPORT_GUID_ARCHIVE_LIST(T, K, ASEQ) \
233 namespace archive { \
236 const guid_initializer< T > \
237 guid_initializer< T >::instance(K); \
240 std::pair<const export_generator<T, ASEQ> *, const guid_initializer< T > *> \
241 export_archives_invoke<T, ASEQ>(T &, ASEQ &); \
247 // check for unnecessary export. T isn't polymorphic so there is no
248 // need to export it.
249 #define BOOST_CLASS_EXPORT_CHECK(T) \
250 BOOST_STATIC_WARNING( \
251 boost::serialization::type_info_implementation< T > \
252 ::type::is_polymorphic::value \
256 // the default list of archives types for which code id generated
257 #define BOOST_CLASS_EXPORT_GUID(T, K) \
258 BOOST_CLASS_EXPORT_GUID_ARCHIVE_LIST( \
261 boost::archive::detail::known_archive_types::type \
265 // the default exportable class identifier is the class name
266 #define BOOST_CLASS_EXPORT_ARCHIVE_LIST(T, ASEQ) \
267 BOOST_CLASS_EXPORT_GUID_ARCHIVE_LIST(T, BOOST_PP_STRINGIZE(T), A)
269 // the default exportable class identifier is the class name
270 // the default list of archives types for which code id generated
271 // are the originally included with this serialization system
272 #define BOOST_CLASS_EXPORT(T) \
273 BOOST_CLASS_EXPORT_GUID_ARCHIVE_LIST( \
275 BOOST_PP_STRINGIZE(T), \
276 boost::archive::detail::known_archive_types::type \
280 #endif // BOOST_SERIALIZATION_EXPORT_HPP