Chaste Release::3.1
SerializationExportWrapper.hpp
Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (c) 2005-2012, University of Oxford.
00004 All rights reserved.
00005 
00006 University of Oxford means the Chancellor, Masters and Scholars of the
00007 University of Oxford, having an administrative office at Wellington
00008 Square, Oxford OX1 2JD, UK.
00009 
00010 This file is part of Chaste.
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided that the following conditions are met:
00014  * Redistributions of source code must retain the above copyright notice,
00015    this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright notice,
00017    this list of conditions and the following disclaimer in the documentation
00018    and/or other materials provided with the distribution.
00019  * Neither the name of the University of Oxford nor the names of its
00020    contributors may be used to endorse or promote products derived from this
00021    software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 
00034 */
00035 
00037 #define COVERAGE_IGNORE
00038 
00078 #include <boost/version.hpp>
00079 
00081 // Make sure includes happen in the correct place.  This has to go before
00082 // the SERIALIZATIONEXPORTWRAPPER_HPP_ guard, since we need it to be seen
00083 // by both .hpp and .cpp files.
00084 
00085 #if BOOST_VERSION < 103600
00086 // Boost 1.34 and older - export goes in headers
00087 #ifndef CHASTE_SERIALIZATION_CPP
00088 #include <boost/serialization/export.hpp>
00089 #endif // CHASTE_SERIALIZATION_CPP
00090 
00091 #elif BOOST_VERSION < 104100
00092 // Boost 1.36-1.40 - export goes in .cpp, along with archive includes
00093 #ifdef CHASTE_SERIALIZATION_CPP
00094 #include "CheckpointArchiveTypes.hpp"
00095 #include <boost/serialization/export.hpp>
00096 #endif // CHASTE_SERIALIZATION_CPP
00097 
00098 #else
00099 // Boost 1.41 and newer - export goes in both, with archive includes in .cpp
00100 #include <boost/serialization/extended_type_info.hpp> // We get compile errors without this...
00101 #include <boost/serialization/export.hpp>
00102 #ifdef CHASTE_SERIALIZATION_CPP
00103 #include "CheckpointArchiveTypes.hpp"
00104 #endif // CHASTE_SERIALIZATION_CPP
00105 
00106 #endif
00107 // Done includes
00108 
00110 #if BOOST_VERSION >= 104100 && defined(CHASTE_SERIALIZATION_CPP)
00111 // .cpp file needs to use BOOST_CLASS_EXPORT_IMPLEMENT, so we need
00112 // to redefine the macros from the .hpp file.  Hence this can't go
00113 // in the include guard.
00114 
00115 #undef CHASTE_CLASS_EXPORT_TEMPLATED
00116 
00121 #define CHASTE_CLASS_EXPORT_TEMPLATED(T, S)    \
00122    BOOST_CLASS_EXPORT_IMPLEMENT(T)
00123 
00124 #undef CHASTE_CLASS_EXPORT_INTERNAL
00125 
00129 #define CHASTE_CLASS_EXPORT_INTERNAL(T)        \
00130    BOOST_CLASS_EXPORT_IMPLEMENT(T)
00131 
00132 #endif // BOOST_VERSION >= 104100 && defined(CHASTE_SERIALIZATION_CPP)
00133 
00135 
00136 #ifndef SERIALIZATIONEXPORTWRAPPER_HPP_
00137 #define SERIALIZATIONEXPORTWRAPPER_HPP_
00138 // Code in the next block is only compiled when the .hpp is first seen
00139 
00141 
00142 #include <boost/preprocessor/cat.hpp>
00143 #include <boost/preprocessor/stringize.hpp>
00144 
00145 // Handle broken BOOST_CLASS_EXPORT in Boost 1.36 & 1.37
00146 #if BOOST_VERSION >= 103600 && BOOST_VERSION < 103800
00147 
00155 #define CHASTE_CLASS_EXPORT_GUID(T, K, S)                                           \
00156 namespace                                                                           \
00157 {                                                                                   \
00158     ::boost::archive::detail::guid_initializer< T > const &                         \
00159         BOOST_PP_CAT(BOOST_PP_CAT(boost_serialization_guid_initializer_, __LINE__), S)               \
00160         = ::boost::serialization::singleton<                                        \
00161             ::boost::archive::detail::guid_initializer< T >                         \
00162           >::get_mutable_instance().export_guid(K);                                 \
00163 }
00164 
00170 #define CHASTE_CLASS_EXPORT_TEMPLATED(T, S)    \
00171     CHASTE_CLASS_EXPORT_GUID(                  \
00172         T,                                     \
00173         BOOST_PP_STRINGIZE(T), S               \
00174     )                                          \
00175 
00176 
00180 #define CHASTE_CLASS_EXPORT_INTERNAL(T)        \
00181    CHASTE_CLASS_EXPORT_TEMPLATED(T, T)
00182 
00183 
00184 // The interface changes yet again in Boost 1.41, and we need something in both .hpp and .cpp...
00185 #elif BOOST_VERSION >= 104100
00186 // .hpp file needs to use BOOST_CLASS_EXPORT_KEY
00187 
00193 #define CHASTE_CLASS_EXPORT_TEMPLATED(T, S)   \
00194    BOOST_CLASS_EXPORT_KEY(T)
00195 
00200 #define CHASTE_CLASS_EXPORT_INTERNAL(T)       \
00201    BOOST_CLASS_EXPORT_KEY(T)
00202 
00203 #else // BOOST_VERSION < 103600 || (BOOST_VERSION >= 103800 && BOOST_VERSION < 104100)
00204 //Do exactly as we did before (so that archives created with 1.33 don't have to be re-generated)
00205 
00211 #define CHASTE_CLASS_EXPORT_TEMPLATED(T, S)    \
00212    BOOST_CLASS_EXPORT(T)
00213 
00218 #define CHASTE_CLASS_EXPORT_INTERNAL(T)        \
00219    BOOST_CLASS_EXPORT(T)
00220 
00221 #endif // BOOST_VERSION >= 103600 && BOOST_VERSION < 103800
00222 
00223 template<class> struct pack;
00230 template<class T> struct pack<void (T)> {
00231     typedef T type; 
00232 };
00233 
00239 #define CHASTE_EXPORT_KEY_1(CLASS, P1) \
00240     BOOST_PP_CAT(CLASS, P1)
00241 
00248 #define CHASTE_EXPORT_KEY_2(CLASS, P1, P2) \
00249     BOOST_PP_CAT(BOOST_PP_CAT(CLASS, P1), P2)
00250 
00258 #define CHASTE_EXPORT_KEY_3(CLASS, P1, P2, P3) \
00259     BOOST_PP_CAT(BOOST_PP_CAT(BOOST_PP_CAT(CLASS, P1), P2), P3)
00260 
00266 #define CHASTE_PACK_1(CLASS, P1) pack<void (CLASS< P1 >)>::type
00267 
00274 #define CHASTE_PACK_2(CLASS, P1, P2) pack<void (CLASS< P1,P2 >)>::type
00275 
00283 #define CHASTE_PACK_3(CLASS, P1, P2, P3) pack<void (CLASS< P1,P2,P3 >)>::type
00284 
00285 // End of include guard - code below here is executed in both .hpp and .cpp
00286 #endif // SERIALIZATIONEXPORTWRAPPER_HPP_
00287 
00288 
00289 // Since CHASTE_CLASS_EXPORT_TEMPLATED and CHASTE_CLASS_EXPORT_INTERNAL are re-defined for the .cpp file
00290 // in some Boost versions, the following macros will also need re-defining.
00291 
00292 #ifdef EXPORT_TEMPLATE_CLASS3_INTERNAL
00293 // Avoid re-definition when called from a .cpp file
00294 #undef EXPORT_TEMPLATE_CLASS3_INTERNAL
00295 #undef EXPORT_TEMPLATE_CLASS2_INTERNAL
00296 #undef EXPORT_TEMPLATE_CLASS1_INTERNAL
00297 #undef EXPORT_TEMPLATE_CLASS_ALL_DIMS_INTERNAL
00298 #undef EXPORT_TEMPLATE_CLASS_SAME_DIMS_INTERNAL
00299 #endif // EXPORT_TEMPLATE_CLASS3_INTERNAL
00300 
00301 // Macros for templated classes
00302 
00311 #define EXPORT_TEMPLATE_CLASS3_INTERNAL(CLASS, E, S, P) \
00312     CHASTE_CLASS_EXPORT_TEMPLATED( CHASTE_PACK_3(CLASS, E, S, P), CHASTE_EXPORT_KEY_3(CLASS, E, S, P) )
00313 
00321 #define EXPORT_TEMPLATE_CLASS2_INTERNAL(CLASS, E, S) \
00322     CHASTE_CLASS_EXPORT_TEMPLATED( CHASTE_PACK_2(CLASS, E, S), CHASTE_EXPORT_KEY_2(CLASS, E, S) )
00323 
00330 #define EXPORT_TEMPLATE_CLASS1_INTERNAL(CLASS, D) \
00331     CHASTE_CLASS_EXPORT_TEMPLATED( CHASTE_PACK_1(CLASS, D), CHASTE_EXPORT_KEY_1(CLASS, D) )
00332 
00339 #define EXPORT_TEMPLATE_CLASS_ALL_DIMS_INTERNAL(CLASS) \
00340     EXPORT_TEMPLATE_CLASS2(CLASS, 1, 1) \
00341     EXPORT_TEMPLATE_CLASS2(CLASS, 1, 2) \
00342     EXPORT_TEMPLATE_CLASS2(CLASS, 1, 3) \
00343     EXPORT_TEMPLATE_CLASS2(CLASS, 2, 2) \
00344     EXPORT_TEMPLATE_CLASS2(CLASS, 2, 3) \
00345     EXPORT_TEMPLATE_CLASS2(CLASS, 3, 3)
00346 
00353 #define EXPORT_TEMPLATE_CLASS_SAME_DIMS_INTERNAL(CLASS) \
00354     EXPORT_TEMPLATE_CLASS1(CLASS, 1) \
00355     EXPORT_TEMPLATE_CLASS1(CLASS, 2) \
00356     EXPORT_TEMPLATE_CLASS1(CLASS, 3)
00357 
00358 // Now define the macros that users actually call.
00359 // Again this goes outside the include guard, so it is seen by both .hpp and .cpp files.
00360 
00361 // However, we don't want to define things twice, so...
00362 #if !defined(CHASTE_CLASS_EXPORT) || defined(CHASTE_SERIALIZATION_CPP)
00363 #ifdef CHASTE_SERIALIZATION_CPP
00364 // Remove the definitions from when we were included via an .hpp file
00365 #undef CHASTE_CLASS_EXPORT
00366 #undef EXPORT_TEMPLATE_CLASS_SAME_DIMS
00367 #undef EXPORT_TEMPLATE_CLASS_ALL_DIMS
00368 #undef EXPORT_TEMPLATE_CLASS1
00369 #undef EXPORT_TEMPLATE_CLASS2
00370 #undef EXPORT_TEMPLATE_CLASS3
00371 #endif // CHASTE_SERIALIZATION_CPP
00372 
00373 #if (BOOST_VERSION < 103600  && ! defined(CHASTE_SERIALIZATION_CPP)) || \
00374     (BOOST_VERSION >= 103600 && defined(CHASTE_SERIALIZATION_CPP)) || \
00375     (BOOST_VERSION >= 104100)
00376 // Boost 1.34 and older - export goes in headers
00377 // Boost 1.36 and newer - export goes in .cpp
00378 // Boost 1.41 and newer - key goes in .hpp, implement goes in .cpp
00379 
00384 #define CHASTE_CLASS_EXPORT(T)                 CHASTE_CLASS_EXPORT_INTERNAL(T)
00385 
00390 #define EXPORT_TEMPLATE_CLASS_SAME_DIMS(CLASS) EXPORT_TEMPLATE_CLASS_SAME_DIMS_INTERNAL(CLASS)
00391 
00396 #define EXPORT_TEMPLATE_CLASS_ALL_DIMS(CLASS)  EXPORT_TEMPLATE_CLASS_ALL_DIMS_INTERNAL(CLASS)
00397 
00402 #define EXPORT_TEMPLATE_CLASS1(CLASS, D)       EXPORT_TEMPLATE_CLASS1_INTERNAL(CLASS, D)
00403 
00409 #define EXPORT_TEMPLATE_CLASS2(CLASS, E, S)    EXPORT_TEMPLATE_CLASS2_INTERNAL(CLASS, E, S)
00410 
00417 #define EXPORT_TEMPLATE_CLASS3(CLASS, E, S, P) EXPORT_TEMPLATE_CLASS3_INTERNAL(CLASS, E, S, P)
00418 
00419 #else
00420 
00425 #define CHASTE_CLASS_EXPORT(T)
00426 
00430 #define EXPORT_TEMPLATE_CLASS_SAME_DIMS(CLASS)
00431 
00435 #define EXPORT_TEMPLATE_CLASS_ALL_DIMS(CLASS)
00436 
00441 #define EXPORT_TEMPLATE_CLASS1(CLASS, D)
00442 
00448 #define EXPORT_TEMPLATE_CLASS2(CLASS, E, S)
00449 
00456 #define EXPORT_TEMPLATE_CLASS3(CLASS, E, S, P)
00457 
00458 #endif // Long if!
00459 #endif // !defined(CHASTE_CLASS_EXPORT) || defined(CHASTE_SERIALIZATION_CPP)
00460 
00461 #undef COVERAGE_IGNORE