Chaste  Release::3.4
SerializationExportWrapper.hpp
Go to the documentation of this file.
1 /*
2 
3 Copyright (c) 2005-2016, University of Oxford.
4 All rights reserved.
5 
6 University of Oxford means the Chancellor, Masters and Scholars of the
7 University of Oxford, having an administrative office at Wellington
8 Square, Oxford OX1 2JD, UK.
9 
10 This file is part of Chaste.
11 
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are met:
14  * Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16  * Redistributions in binary form must reproduce the above copyright notice,
17  this list of conditions and the following disclaimer in the documentation
18  and/or other materials provided with the distribution.
19  * Neither the name of the University of Oxford nor the names of its
20  contributors may be used to endorse or promote products derived from this
21  software without specific prior written permission.
22 
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 
34 */
35 
37 #define COVERAGE_IGNORE
38 
79 #include <boost/version.hpp>
80 
82 // Make sure includes happen in the correct place. This has to go before
83 // the SERIALIZATIONEXPORTWRAPPER_HPP_ guard, since we need it to be seen
84 // by both .hpp and .cpp files.
85 
86 #if BOOST_VERSION < 103600
87 // Boost 1.34 and older - export goes in headers
88 #ifndef CHASTE_SERIALIZATION_CPP
89 #include <boost/serialization/export.hpp>
90 #endif // CHASTE_SERIALIZATION_CPP
91 
92 #elif BOOST_VERSION < 104100
93 // Boost 1.36-1.40 - export goes in .cpp, along with archive includes
94 #ifdef CHASTE_SERIALIZATION_CPP
96 #include <boost/serialization/export.hpp>
97 #endif // CHASTE_SERIALIZATION_CPP
98 
99 #else
100 // Boost 1.41 and newer - export goes in both, with archive includes in .cpp
101 #include <boost/serialization/extended_type_info.hpp> // We get compile errors without this...
102 #include <boost/serialization/export.hpp>
103 #ifdef CHASTE_SERIALIZATION_CPP
105 #endif // CHASTE_SERIALIZATION_CPP
106 
107 #endif
108 // Done includes
109 
111 #if BOOST_VERSION >= 104100 && defined(CHASTE_SERIALIZATION_CPP)
112 // .cpp file needs to use BOOST_CLASS_EXPORT_IMPLEMENT, so we need
113 // to redefine the macros from the .hpp file. Hence this can't go
114 // in the include guard.
115 
116 #undef CHASTE_CLASS_EXPORT_TEMPLATED
117 
122 #define CHASTE_CLASS_EXPORT_TEMPLATED(T, S) \
123  BOOST_CLASS_EXPORT_IMPLEMENT(T)
124 
125 #undef CHASTE_CLASS_EXPORT_INTERNAL
126 
130 #define CHASTE_CLASS_EXPORT_INTERNAL(T) \
131  BOOST_CLASS_EXPORT_IMPLEMENT(T)
132 
133 #endif // BOOST_VERSION >= 104100 && defined(CHASTE_SERIALIZATION_CPP)
134 
136 
137 #ifndef SERIALIZATIONEXPORTWRAPPER_HPP_
138 
139 #define SERIALIZATIONEXPORTWRAPPER_HPP_
140 
141 // Code in the next block is only compiled when the .hpp is first seen
142 
144 
145 #include <boost/preprocessor/cat.hpp>
146 #include <boost/preprocessor/stringize.hpp>
147 
148 // Handle broken BOOST_CLASS_EXPORT in Boost 1.36 & 1.37
149 #if BOOST_VERSION >= 103600 && BOOST_VERSION < 103800
150 
158 #define CHASTE_CLASS_EXPORT_GUID(T, K, S) \
159 namespace \
160 { \
161  ::boost::archive::detail::guid_initializer< T > const & \
162  BOOST_PP_CAT(BOOST_PP_CAT(boost_serialization_guid_initializer_, __LINE__), S) \
163  = ::boost::serialization::singleton< \
164  ::boost::archive::detail::guid_initializer< T > \
165  >::get_mutable_instance().export_guid(K); \
166 }
167 
173 #define CHASTE_CLASS_EXPORT_TEMPLATED(T, S) \
174  CHASTE_CLASS_EXPORT_GUID( \
175  T, \
176  BOOST_PP_STRINGIZE(T), S \
177  ) \
178 
179 
183 #define CHASTE_CLASS_EXPORT_INTERNAL(T) \
184  CHASTE_CLASS_EXPORT_TEMPLATED(T, T)
185 
186 
187 // The interface changes yet again in Boost 1.41, and we need something in both .hpp and .cpp...
188 #elif BOOST_VERSION >= 104100
189 // .hpp file needs to use BOOST_CLASS_EXPORT_KEY
190 
196 #define CHASTE_CLASS_EXPORT_TEMPLATED(T, S) \
197  BOOST_CLASS_EXPORT_KEY(T)
198 
203 #define CHASTE_CLASS_EXPORT_INTERNAL(T) \
204  BOOST_CLASS_EXPORT_KEY(T)
205 
206 #else // BOOST_VERSION < 103600 || (BOOST_VERSION >= 103800 && BOOST_VERSION < 104100)
207 //Do exactly as we did before (so that archives created with 1.33 don't have to be re-generated)
208 
214 #define CHASTE_CLASS_EXPORT_TEMPLATED(T, S) \
215  BOOST_CLASS_EXPORT(T)
216 
221 #define CHASTE_CLASS_EXPORT_INTERNAL(T) \
222  BOOST_CLASS_EXPORT(T)
223 
224 #endif // BOOST_VERSION >= 103600 && BOOST_VERSION < 103800
225 
226 template<class> struct pack;
233 template<class T> struct pack<void (T)> {
234  typedef T type;
235 };
236 
242 #define CHASTE_EXPORT_KEY_1(CLASS, P1) \
243  BOOST_PP_CAT(CLASS, P1)
244 
251 #define CHASTE_EXPORT_KEY_2(CLASS, P1, P2) \
252  BOOST_PP_CAT(BOOST_PP_CAT(CLASS, P1), P2)
253 
261 #define CHASTE_EXPORT_KEY_3(CLASS, P1, P2, P3) \
262  BOOST_PP_CAT(BOOST_PP_CAT(BOOST_PP_CAT(CLASS, P1), P2), P3)
263 
269 #define CHASTE_PACK_1(CLASS, P1) pack<void (CLASS< P1 >)>::type
270 
277 #define CHASTE_PACK_2(CLASS, P1, P2) pack<void (CLASS< P1,P2 >)>::type
278 
286 #define CHASTE_PACK_3(CLASS, P1, P2, P3) pack<void (CLASS< P1,P2,P3 >)>::type
287 
288 // End of include guard - code below here is executed in both .hpp and .cpp
289 #endif // SERIALIZATIONEXPORTWRAPPER_HPP_
290 
292 // Since CHASTE_CLASS_EXPORT_TEMPLATED and CHASTE_CLASS_EXPORT_INTERNAL are re-defined for the .cpp file
293 // in some Boost versions, the following macros will also need re-defining.
294 
295 #ifdef EXPORT_TEMPLATE_CLASS3_INTERNAL
296 // Avoid re-definition when called from a .cpp file
297 #undef EXPORT_TEMPLATE_CLASS3_INTERNAL
298 #undef EXPORT_TEMPLATE_CLASS2_INTERNAL
299 #undef EXPORT_TEMPLATE_CLASS1_INTERNAL
300 #undef EXPORT_TEMPLATE_CLASS_ALL_DIMS_INTERNAL
301 #undef EXPORT_TEMPLATE_CLASS_SAME_DIMS_INTERNAL
302 #endif // EXPORT_TEMPLATE_CLASS3_INTERNAL
303 
304 // Macros for templated classes
305 
314 #define EXPORT_TEMPLATE_CLASS3_INTERNAL(CLASS, E, S, P) \
315  CHASTE_CLASS_EXPORT_TEMPLATED( CHASTE_PACK_3(CLASS, E, S, P), CHASTE_EXPORT_KEY_3(CLASS, E, S, P) )
316 
324 #define EXPORT_TEMPLATE_CLASS2_INTERNAL(CLASS, E, S) \
325  CHASTE_CLASS_EXPORT_TEMPLATED( CHASTE_PACK_2(CLASS, E, S), CHASTE_EXPORT_KEY_2(CLASS, E, S) )
326 
333 #define EXPORT_TEMPLATE_CLASS1_INTERNAL(CLASS, D) \
334  CHASTE_CLASS_EXPORT_TEMPLATED( CHASTE_PACK_1(CLASS, D), CHASTE_EXPORT_KEY_1(CLASS, D) )
335 
342 #define EXPORT_TEMPLATE_CLASS_ALL_DIMS_INTERNAL(CLASS) \
343  EXPORT_TEMPLATE_CLASS2(CLASS, 1, 1) \
344  EXPORT_TEMPLATE_CLASS2(CLASS, 1, 2) \
345  EXPORT_TEMPLATE_CLASS2(CLASS, 1, 3) \
346  EXPORT_TEMPLATE_CLASS2(CLASS, 2, 2) \
347  EXPORT_TEMPLATE_CLASS2(CLASS, 2, 3) \
348  EXPORT_TEMPLATE_CLASS2(CLASS, 3, 3)
349 
355 #define EXPORT_TEMPLATE_CLASS_SAME_DIMS_INTERNAL(CLASS) \
356  EXPORT_TEMPLATE_CLASS1(CLASS, 1) \
357  EXPORT_TEMPLATE_CLASS1(CLASS, 2) \
358  EXPORT_TEMPLATE_CLASS1(CLASS, 3)
359 
360 // Now define the macros that users actually call.
361 // Again this goes outside the include guard, so it is seen by both .hpp and .cpp files.
362 
363 // However, we don't want to define things twice, so...
364 #if !defined(CHASTE_CLASS_EXPORT) || defined(CHASTE_SERIALIZATION_CPP)
365 #ifdef CHASTE_SERIALIZATION_CPP
366 // Remove the definitions from when we were included via an .hpp file
367 #undef CHASTE_CLASS_EXPORT
368 #undef EXPORT_TEMPLATE_CLASS_SAME_DIMS
369 #undef EXPORT_TEMPLATE_CLASS_ALL_DIMS
370 #undef EXPORT_TEMPLATE_CLASS1
371 #undef EXPORT_TEMPLATE_CLASS2
372 #undef EXPORT_TEMPLATE_CLASS3
373 #endif // CHASTE_SERIALIZATION_CPP
374 
375 #if (BOOST_VERSION < 103600 && ! defined(CHASTE_SERIALIZATION_CPP)) || \
376  (BOOST_VERSION >= 103600 && defined(CHASTE_SERIALIZATION_CPP)) || \
377  (BOOST_VERSION >= 104100)
378 // Boost 1.34 and older - export goes in headers
379 // Boost 1.36 and newer - export goes in .cpp
380 // Boost 1.41 and newer - key goes in .hpp, implement goes in .cpp
381 
386 #define CHASTE_CLASS_EXPORT(T) CHASTE_CLASS_EXPORT_INTERNAL(T)
387 
391 #define EXPORT_TEMPLATE_CLASS_SAME_DIMS(CLASS) EXPORT_TEMPLATE_CLASS_SAME_DIMS_INTERNAL(CLASS)
392 
397 #define EXPORT_TEMPLATE_CLASS_ALL_DIMS(CLASS) EXPORT_TEMPLATE_CLASS_ALL_DIMS_INTERNAL(CLASS)
398 
403 #define EXPORT_TEMPLATE_CLASS1(CLASS, D) EXPORT_TEMPLATE_CLASS1_INTERNAL(CLASS, D)
404 
410 #define EXPORT_TEMPLATE_CLASS2(CLASS, E, S) EXPORT_TEMPLATE_CLASS2_INTERNAL(CLASS, E, S)
411 
418 #define EXPORT_TEMPLATE_CLASS3(CLASS, E, S, P) EXPORT_TEMPLATE_CLASS3_INTERNAL(CLASS, E, S, P)
419 
420 #else
421 
426 #define CHASTE_CLASS_EXPORT(T)
427 
431 #define EXPORT_TEMPLATE_CLASS_SAME_DIMS(CLASS)
432 
436 #define EXPORT_TEMPLATE_CLASS_ALL_DIMS(CLASS)
437 
442 #define EXPORT_TEMPLATE_CLASS1(CLASS, D)
443 
449 #define EXPORT_TEMPLATE_CLASS2(CLASS, E, S)
450 
457 #define EXPORT_TEMPLATE_CLASS3(CLASS, E, S, P)
458 
459 #endif // Long if!
460 #endif // !defined(CHASTE_CLASS_EXPORT) || defined(CHASTE_SERIALIZATION_CPP)
461 
462 #undef COVERAGE_IGNORE