epoc32/include/stdapis/boost/serialization/export.hpp
branchSymbian2
changeset 2 2fe1408b6811
equal deleted inserted replaced
1:666f914201fb 2:2fe1408b6811
       
     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) && (_MSC_VER >= 1020)
       
     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 // 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.
       
    22 
       
    23 #include <utility>
       
    24 
       
    25 #include <boost/config.hpp>
       
    26 
       
    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)
       
    32 
       
    33 #else
       
    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>
       
    43 
       
    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>
       
    48 
       
    49 namespace boost {
       
    50 namespace archive {
       
    51 namespace detail {
       
    52 
       
    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;
       
    58 
       
    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;
       
    63 
       
    64 namespace export_impl
       
    65 {
       
    66     struct nothing{
       
    67         static void instantiate(){}
       
    68     };
       
    69 
       
    70     template<class Archive, class T>
       
    71     struct archive {
       
    72         struct i {
       
    73             static void invoke(){
       
    74                 instantiate_pointer_iserializer(
       
    75                     static_cast<Archive *>(NULL),
       
    76                     static_cast<T *>(NULL)
       
    77                 );
       
    78             }
       
    79         };
       
    80         struct o {
       
    81             static void invoke(){
       
    82                 instantiate_pointer_oserializer(
       
    83                     static_cast<Archive *>(NULL),
       
    84                     static_cast<T *>(NULL)
       
    85                 );
       
    86             }
       
    87         };
       
    88         static void instantiate(){
       
    89             #if defined(__GNUC__) && (__GNUC__ >= 3)
       
    90             BOOST_STATIC_ASSERT(
       
    91                 Archive::is_loading::value || Archive::is_saving::value
       
    92             );
       
    93             #endif
       
    94             typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
       
    95                 BOOST_DEDUCED_TYPENAME Archive::is_saving,
       
    96                 mpl::identity<o>,
       
    97             // else
       
    98             BOOST_DEDUCED_TYPENAME mpl::eval_if<
       
    99                 BOOST_DEDUCED_TYPENAME Archive::is_loading,
       
   100                 mpl::identity<i>,
       
   101             // else
       
   102                 mpl::identity<nothing>
       
   103             > >::type typex;
       
   104             typex::invoke();
       
   105         }
       
   106     };
       
   107 
       
   108     template<class ASeq, class T>
       
   109     struct for_each_archive {
       
   110     private:
       
   111         typedef BOOST_DEDUCED_TYPENAME mpl::pop_front<ASeq>::type tail;
       
   112         typedef BOOST_DEDUCED_TYPENAME mpl::front<ASeq>::type head;
       
   113     public:
       
   114         static void instantiate(){
       
   115             archive<head, T>::instantiate();
       
   116             typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
       
   117                 mpl::empty<tail>,
       
   118                 mpl::identity<nothing>,
       
   119                 mpl::identity<for_each_archive<tail, T> >
       
   120             >::type typex;
       
   121             typex::instantiate();
       
   122         }
       
   123     };
       
   124 
       
   125 } // namespace export_impl
       
   126 
       
   127 // strictly conforming
       
   128 template<class T, class ASeq>
       
   129 struct export_generator {
       
   130     export_generator(){
       
   131         export_impl::for_each_archive<ASeq, T>::instantiate();
       
   132     }
       
   133     static const export_generator instance;
       
   134 };
       
   135 
       
   136 template<class T, class ASeq>
       
   137 const export_generator<T, ASeq>
       
   138     export_generator<T, ASeq>::instance;
       
   139 
       
   140 // instantiation of this template creates a static object.
       
   141 template<class T>
       
   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);
       
   146     }
       
   147     static const guid_initializer instance;
       
   148     guid_initializer(const char *key = 0) BOOST_USED ;
       
   149 };
       
   150 
       
   151 template<class T>
       
   152 guid_initializer<T>::guid_initializer(const char *key){
       
   153     if(0 != key)
       
   154         export_register(key);
       
   155 }
       
   156 
       
   157 template<class T>
       
   158 const guid_initializer<T> guid_initializer<T>::instance;
       
   159 
       
   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
       
   162 
       
   163 // the following optimization - inhibiting explicit instantiation for abstract
       
   164 // classes breaks msvc compliles
       
   165 template<class T, class ASeq>
       
   166 struct export_instance {
       
   167     struct abstract {
       
   168         static const export_generator<T, ASeq> *
       
   169         invoke(){
       
   170             return 0;
       
   171         }
       
   172     };
       
   173     struct not_abstract {
       
   174         static const export_generator<T, ASeq> *
       
   175         invoke(){
       
   176             return & export_generator<T, ASeq>::instance;
       
   177         }
       
   178     };
       
   179 };
       
   180 
       
   181 template<class T, class ASeq>
       
   182 BOOST_DLLEXPORT
       
   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>
       
   189     >::type typex;
       
   190     return std::pair<const export_generator<T, ASeq> *, const guid_initializer<T> *>(
       
   191         typex::invoke(),
       
   192         & guid_initializer<T>::instance
       
   193     );
       
   194 }
       
   195 
       
   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> *>
       
   201         invoke(){
       
   202             return std::pair<const export_generator<T, ASeq> *,
       
   203                              const guid_initializer<T> *>(0, 0);
       
   204         }
       
   205     };
       
   206     struct non_empty_archive_list {
       
   207         static BOOST_DLLEXPORT
       
   208         std::pair<const export_generator<T, ASeq> *, const guid_initializer<T> *>
       
   209         invoke(){
       
   210             return export_instance_invoke<T, ASeq>();
       
   211         }
       
   212     };
       
   213 };
       
   214 
       
   215 template<class T, class ASeq>
       
   216 BOOST_DLLEXPORT
       
   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<
       
   220         mpl::empty<ASeq>,
       
   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>
       
   223     >::type typex;
       
   224     return typex::invoke();
       
   225 }
       
   226 
       
   227 } // namespace detail
       
   228 } // namespace archive
       
   229 } // namespace boost
       
   230 
       
   231 #define BOOST_CLASS_EXPORT_GUID_ARCHIVE_LIST(T, K, ASEQ)         \
       
   232     namespace boost {                                            \
       
   233     namespace archive {                                          \
       
   234     namespace detail {                                           \
       
   235     template<>                                                   \
       
   236     const guid_initializer< T >                                  \
       
   237         guid_initializer< T >::instance(K);                      \
       
   238     template                                                     \
       
   239     BOOST_DLLEXPORT                                              \
       
   240     std::pair<const export_generator<T, ASEQ> *, const guid_initializer< T > *> \
       
   241     export_archives_invoke<T, ASEQ>(T &, ASEQ &);                \
       
   242     } } }                                                        \
       
   243     /**/
       
   244 
       
   245 #endif
       
   246 
       
   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                        \
       
   253     );                                                           \
       
   254     /**/
       
   255 
       
   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(                        \
       
   259         T,                                                       \
       
   260         K,                                                       \
       
   261         boost::archive::detail::known_archive_types::type        \
       
   262     )                                                            \
       
   263     /**/
       
   264 
       
   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)
       
   268 
       
   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(                        \
       
   274         T,                                                       \
       
   275         BOOST_PP_STRINGIZE(T),                                   \
       
   276         boost::archive::detail::known_archive_types::type        \
       
   277     )                                                            \
       
   278     /**/
       
   279 
       
   280 #endif // BOOST_SERIALIZATION_EXPORT_HPP