epoc32/include/stdapis/boost/archive/detail/iserializer.hpp
branchSymbian2
changeset 2 2fe1408b6811
equal deleted inserted replaced
1:666f914201fb 2:2fe1408b6811
       
     1 #ifndef BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP
       
     2 #define BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP
       
     3 
       
     4 // MS compatible compilers support #pragma once
       
     5 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
       
     6 # pragma once
       
     7 #pragma inline_depth(511)
       
     8 #pragma inline_recursion(on)
       
     9 #endif
       
    10 
       
    11 #if defined(__MWERKS__)
       
    12 #pragma inline_depth(511)
       
    13 #endif
       
    14 
       
    15 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
       
    16 // iserializer.hpp: interface for serialization system.
       
    17 
       
    18 // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . 
       
    19 // Use, modification and distribution is subject to the Boost Software
       
    20 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
       
    21 // http://www.boost.org/LICENSE_1_0.txt)
       
    22 
       
    23 //  See http://www.boost.org for updates, documentation, and revision history.
       
    24 
       
    25 #include <new>     // for placement new
       
    26 #include <memory>  // for auto_ptr
       
    27 #include <cstddef> // size_t
       
    28 
       
    29 #include <boost/config.hpp>
       
    30 #include <boost/detail/workaround.hpp>
       
    31 #if defined(BOOST_NO_STDC_NAMESPACE)
       
    32 namespace std{ 
       
    33     using ::size_t; 
       
    34 } // namespace std
       
    35 #endif
       
    36 #include <boost/throw_exception.hpp>
       
    37 #include <boost/smart_cast.hpp>
       
    38 #include <boost/static_assert.hpp>
       
    39 #include <boost/static_warning.hpp>
       
    40 #include <boost/detail/no_exceptions_support.hpp>
       
    41 
       
    42 #include <boost/type_traits/is_pointer.hpp>
       
    43 #include <boost/type_traits/is_fundamental.hpp>
       
    44 #include <boost/type_traits/is_enum.hpp>
       
    45 #include <boost/type_traits/is_const.hpp>
       
    46 #include <boost/type_traits/remove_const.hpp>
       
    47 #include <boost/serialization/is_abstract.hpp>
       
    48 
       
    49 #include <boost/mpl/eval_if.hpp>
       
    50 #include <boost/mpl/if.hpp>
       
    51 #include <boost/mpl/identity.hpp>
       
    52 #include <boost/mpl/or.hpp>
       
    53 #include <boost/mpl/and.hpp>
       
    54 #include <boost/mpl/less.hpp>
       
    55 #include <boost/mpl/greater_equal.hpp>
       
    56 #include <boost/mpl/int.hpp>
       
    57 #include <boost/mpl/list.hpp>
       
    58 #include <boost/mpl/empty.hpp>
       
    59 #include <boost/mpl/not.hpp>
       
    60 
       
    61  #ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO   
       
    62      #include <boost/serialization/extended_type_info_typeid.hpp>   
       
    63  #endif 
       
    64 // the following is need only for dynamic cast of polymorphic pointers
       
    65 #include <boost/archive/detail/basic_iarchive.hpp>
       
    66 #include <boost/archive/detail/basic_iserializer.hpp>
       
    67 #include <boost/archive/detail/archive_pointer_iserializer.hpp>
       
    68 #include <boost/archive/archive_exception.hpp>
       
    69 
       
    70 #include <boost/serialization/force_include.hpp>
       
    71 #include <boost/serialization/serialization.hpp>
       
    72 #include <boost/serialization/version.hpp>
       
    73 #include <boost/serialization/level.hpp>
       
    74 #include <boost/serialization/tracking.hpp>
       
    75 #include <boost/serialization/type_info_implementation.hpp>
       
    76 #include <boost/serialization/nvp.hpp>
       
    77 #include <boost/serialization/binary_object.hpp>
       
    78 #include <boost/serialization/void_cast.hpp>
       
    79 
       
    80 namespace boost {
       
    81 
       
    82 namespace serialization {
       
    83     class extended_type_info;
       
    84 } // namespace serialization
       
    85 
       
    86 namespace archive {
       
    87 
       
    88 // an accessor to permit friend access to archives.  Needed because
       
    89 // some compilers don't handle friend templates completely
       
    90 class load_access {
       
    91 public:
       
    92     template<class Archive, class T>
       
    93     static void load_primitive(Archive &ar, T &t){
       
    94         ar.load(t);
       
    95     }
       
    96 };
       
    97 
       
    98 namespace detail {
       
    99 
       
   100 template<class Archive, class T>
       
   101 class iserializer : public basic_iserializer
       
   102 {
       
   103 private:
       
   104     virtual void destroy(/*const*/ void *address) const {
       
   105         boost::serialization::access::destroy(static_cast<T *>(address));
       
   106     }
       
   107     // private constructor to inhibit any existence other than the 
       
   108     // static one
       
   109     explicit iserializer() :
       
   110         basic_iserializer(
       
   111             * boost::serialization::type_info_implementation<T>::type::get_instance()
       
   112         )
       
   113     {}
       
   114 public:
       
   115     virtual BOOST_DLLEXPORT void load_object_data(
       
   116         basic_iarchive & ar,
       
   117         void *x, 
       
   118         const unsigned int file_version
       
   119     ) const BOOST_USED ;
       
   120     virtual bool class_info() const {
       
   121         return boost::serialization::implementation_level<T>::value 
       
   122             >= boost::serialization::object_class_info;
       
   123     }
       
   124     virtual bool tracking(const unsigned int flags) const {
       
   125 //        if(0 != (flags & no_tracking))
       
   126 //            return false;
       
   127         return boost::serialization::tracking_level<T>::value 
       
   128                 == boost::serialization::track_always
       
   129             || boost::serialization::tracking_level<T>::value 
       
   130                 == boost::serialization::track_selectivly
       
   131             && serialized_as_pointer();
       
   132     }
       
   133     virtual unsigned int version() const {
       
   134         return ::boost::serialization::version<T>::value;
       
   135     }
       
   136     virtual bool is_polymorphic() const {
       
   137         typedef BOOST_DEDUCED_TYPENAME 
       
   138             boost::serialization::type_info_implementation<
       
   139                 T
       
   140             >::type::is_polymorphic::type typex;
       
   141         return typex::value;
       
   142     }
       
   143     static iserializer & instantiate(){
       
   144         static iserializer instance;
       
   145         return instance;
       
   146     }
       
   147     virtual ~iserializer(){};
       
   148 };
       
   149 
       
   150 template<class Archive, class T>
       
   151 BOOST_DLLEXPORT void iserializer<Archive, T>::load_object_data(
       
   152     basic_iarchive & ar,
       
   153     void *x, 
       
   154     const unsigned int file_version
       
   155 ) const {
       
   156     // make sure call is routed through the higest interface that might
       
   157     // be specialized by the user.
       
   158     boost::serialization::serialize_adl(
       
   159         boost::smart_cast_reference<Archive &>(ar),
       
   160         * static_cast<T *>(x), 
       
   161         file_version
       
   162     );
       
   163 }
       
   164 
       
   165 // instantiation of this template creates a static object.  Note inversion of
       
   166 // normal argument order to workaround bizarre error in MSVC 6.0 which only
       
   167 // manifests iftself during compiler time.
       
   168 template<class T, class Archive>
       
   169 class pointer_iserializer : public archive_pointer_iserializer<Archive> 
       
   170 {
       
   171 private:
       
   172     virtual const basic_iserializer & get_basic_serializer() const {
       
   173         return iserializer<Archive, T>::instantiate();
       
   174     }
       
   175     virtual BOOST_DLLEXPORT void load_object_ptr(
       
   176         basic_iarchive & ar, 
       
   177         void * & x,
       
   178         const unsigned int file_version
       
   179     ) const BOOST_USED;
       
   180 #if defined(__GNUC__) || ( defined(BOOST_MSVC) && (_MSC_VER <= 1300) )
       
   181 public:
       
   182 #endif
       
   183     // private constructor to inhibit any existence other than the 
       
   184     // static one.  Note GCC doesn't permit constructor to be private
       
   185     explicit BOOST_DLLEXPORT pointer_iserializer() BOOST_USED;
       
   186     static const pointer_iserializer instance;
       
   187 public:
       
   188     // at least one compiler (CW) seems to require that serialize_adl
       
   189     // be explicitly instantiated. Still under investigation. 
       
   190     #if ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
       
   191     void (* const m)(Archive &, T &, const unsigned);
       
   192     boost::serialization::extended_type_info * (* e)();
       
   193     #endif
       
   194     static BOOST_DLLEXPORT const pointer_iserializer & instantiate() BOOST_USED;
       
   195     virtual ~pointer_iserializer(){};
       
   196 };
       
   197 
       
   198 template<class T, class Archive>
       
   199 BOOST_DLLEXPORT const pointer_iserializer<T, Archive> & 
       
   200 pointer_iserializer<T, Archive>::instantiate() {
       
   201     return instance;
       
   202 }
       
   203 
       
   204 // note: instances of this template to be constructed before the main
       
   205 // is called in order for things to be initialized properly.  For this
       
   206 // reason, hiding the instance in a static function as was done above
       
   207 // won't work here so we created a free instance here.
       
   208 template<class T, class Archive>
       
   209 const pointer_iserializer<T, Archive> pointer_iserializer<T, Archive>::instance;
       
   210 
       
   211 // note trick to be sure that operator new is using class specific
       
   212 // version if such exists. Due to Peter Dimov.
       
   213 // note: the following fails if T has no default constructor.
       
   214 // otherwise it would have been ideal
       
   215 //struct heap_allocator : public T 
       
   216 //{
       
   217 //    T * invoke(){
       
   218 //        return ::new(sizeof(T));
       
   219 //    }
       
   220 //}
       
   221 
       
   222 // note: this should really be a member of the load_ptr function
       
   223 // below but some compilers still complain about this.
       
   224 template<class T>
       
   225 struct heap_allocator
       
   226 {
       
   227     #if 0
       
   228         // note: this fails on msvc 7.0 and gcc 3.2
       
   229         template <class U, U x> struct test;
       
   230         typedef char* yes;
       
   231         typedef int* no;
       
   232         template <class U>
       
   233         yes has_op_new(U*, test<void* (*)(std::size_t), &U::operator new>* = 0);
       
   234         no has_op_new(...);
       
   235 
       
   236         template<class U>
       
   237         T * new_operator(U);
       
   238 
       
   239         T * new_operator(yes){
       
   240             return (T::operator new)(sizeof(T));
       
   241         }
       
   242         T * new_operator(no){
       
   243             return static_cast<T *>(operator new(sizeof(T)));
       
   244         }
       
   245         static T * invoke(){
       
   246             return new_operator(has_op_new(static_cast<T *>(NULL)));
       
   247         }
       
   248     #else
       
   249         // while this doesn't handle operator new overload for class T
       
   250         static T * invoke(){
       
   251             return static_cast<T *>(operator new(sizeof(T)));
       
   252         }
       
   253     #endif
       
   254 };
       
   255 
       
   256 // due to Martin Ecker
       
   257 template <typename T>
       
   258 class auto_ptr_with_deleter
       
   259 {
       
   260 public:
       
   261     explicit auto_ptr_with_deleter(T* p) :
       
   262         m_p(p)
       
   263     {}
       
   264     ~auto_ptr_with_deleter(){
       
   265         if (m_p)
       
   266             boost::serialization::access::destroy(m_p);
       
   267     }
       
   268     T* get() const {
       
   269         return m_p;
       
   270     }
       
   271 
       
   272     T* release() {
       
   273         T* p = m_p;
       
   274         m_p = NULL;
       
   275         return p;
       
   276     }
       
   277 private:
       
   278     T* m_p;
       
   279 };
       
   280 
       
   281 template<class T, class Archive>
       
   282 BOOST_DLLEXPORT void pointer_iserializer<T, Archive>::load_object_ptr(
       
   283     basic_iarchive & ar, 
       
   284     void * & x,
       
   285     const unsigned int file_version
       
   286 ) const {
       
   287     Archive & ar_impl = boost::smart_cast_reference<Archive &>(ar);
       
   288 
       
   289 //    if(0 != (ar.get_flags() & no_object_creation)){
       
   290 //        ar_impl >> boost::serialization::make_nvp(NULL, * static_cast<T *>(x));
       
   291 //        return;
       
   292 //    }
       
   293 
       
   294     auto_ptr_with_deleter<T> ap(heap_allocator<T>::invoke());
       
   295     if(NULL == ap.get())
       
   296         boost::throw_exception(std::bad_alloc()) ;
       
   297 
       
   298     T * t = ap.get();
       
   299     x = t;
       
   300 
       
   301     // catch exception during load_construct_data so that we don't
       
   302     // automatically delete the t which is most likely not fully
       
   303     // constructed
       
   304     BOOST_TRY {
       
   305         // this addresses an obscure situtation that occurs when 
       
   306         // load_constructor de-serializes something through a pointer.
       
   307         ar.next_object_pointer(t);
       
   308         boost::serialization::load_construct_data_adl<Archive, T>(
       
   309             ar_impl,
       
   310             t, 
       
   311             file_version
       
   312         );
       
   313     }
       
   314     BOOST_CATCH(...){
       
   315         BOOST_RETHROW;
       
   316     }
       
   317     BOOST_CATCH_END
       
   318 
       
   319     ar_impl >> boost::serialization::make_nvp(NULL, * t);
       
   320     ap.release();
       
   321 }
       
   322 
       
   323 template<class T, class Archive>
       
   324 #if ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
       
   325 BOOST_DLLEXPORT pointer_iserializer<T, Archive>::pointer_iserializer() :
       
   326     archive_pointer_iserializer<Archive>(
       
   327         * boost::serialization::type_info_implementation<T>::type::get_instance()
       
   328     ),
       
   329     m(boost::serialization::serialize_adl<Archive, T>),
       
   330     e(boost::serialization::type_info_implementation<T>::type::get_instance)
       
   331 #else
       
   332 BOOST_DLLEXPORT pointer_iserializer<T, Archive>::pointer_iserializer() :
       
   333     archive_pointer_iserializer<Archive>(
       
   334         * boost::serialization::type_info_implementation<T>::type::get_instance()
       
   335     )
       
   336 #endif
       
   337 {
       
   338     iserializer<Archive, T> & bis = iserializer<Archive, T>::instantiate();
       
   339     bis.set_bpis(this);
       
   340 }
       
   341 
       
   342 template<class Archive, class T>
       
   343 struct load_non_pointer_type {
       
   344     // note this bounces the call right back to the archive
       
   345     // with no runtime overhead
       
   346     struct load_primitive {
       
   347         static void invoke(Archive & ar, T & t){
       
   348             load_access::load_primitive(ar, t);
       
   349         }
       
   350     };
       
   351     // note this bounces the call right back to the archive
       
   352     // with no runtime overhead
       
   353     struct load_only {
       
   354         static void invoke(Archive & ar, T & t){
       
   355             // short cut to user's serializer
       
   356             // make sure call is routed through the higest interface that might
       
   357             // be specialized by the user.
       
   358             boost::serialization::serialize_adl(
       
   359                 ar, t, boost::serialization::version<T>::value
       
   360             );
       
   361         }
       
   362     };
       
   363 
       
   364     // note this save class information including version
       
   365     // and serialization level to the archive
       
   366     struct load_standard {
       
   367         static void invoke(Archive &ar, T &t){
       
   368             //BOOST_STATIC_ASSERT(! boost::is_const<T>::value);
       
   369             // borland - for some reason T is const here - even though
       
   370             // its not called that way - so fix it her
       
   371             typedef BOOST_DEDUCED_TYPENAME boost::remove_const<T>::type typex;
       
   372             void * x = & const_cast<typex &>(t);
       
   373             ar.load_object(x, iserializer<Archive, T>::instantiate());
       
   374         }
       
   375     };
       
   376 
       
   377     struct load_conditional {
       
   378         static void invoke(Archive &ar, T &t){
       
   379             //if(0 == (ar.get_flags() & no_tracking))
       
   380                 load_standard::invoke(ar, t);
       
   381             //else
       
   382             //    load_only::invoke(ar, t);
       
   383         }
       
   384     };
       
   385 
       
   386     typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
       
   387             // if its primitive
       
   388             mpl::equal_to<
       
   389                 boost::serialization::implementation_level<T>,
       
   390                 mpl::int_<boost::serialization::primitive_type>
       
   391             >,
       
   392             mpl::identity<load_primitive>,
       
   393         // else
       
   394         BOOST_DEDUCED_TYPENAME mpl::eval_if<
       
   395         // class info / version
       
   396         mpl::greater_equal<
       
   397                     boost::serialization::implementation_level<T>,
       
   398                     mpl::int_<boost::serialization::object_class_info>
       
   399                 >,
       
   400         // do standard load
       
   401         mpl::identity<load_standard>,
       
   402     // else
       
   403     BOOST_DEDUCED_TYPENAME mpl::eval_if<
       
   404         // no tracking
       
   405                 mpl::equal_to<
       
   406                     boost::serialization::tracking_level<T>,
       
   407                     mpl::int_<boost::serialization::track_never>
       
   408             >,
       
   409             // do a fast load
       
   410             mpl::identity<load_only>,
       
   411         // else
       
   412         // do a fast load only tracking is turned off
       
   413         mpl::identity<load_conditional>
       
   414     > > >::type typex;
       
   415 
       
   416     static void invoke(Archive & ar, T &t){
       
   417         BOOST_STATIC_ASSERT((
       
   418             mpl::greater_equal<
       
   419                 boost::serialization::implementation_level<T>, 
       
   420                 mpl::int_<boost::serialization::primitive_type>
       
   421             >::value
       
   422         ));
       
   423         typex::invoke(ar, t);
       
   424     }
       
   425 };
       
   426 
       
   427 template<class Archive, class Tptr>
       
   428 struct load_pointer_type {
       
   429     template<class T>
       
   430     struct abstract
       
   431     {
       
   432         static const basic_pointer_iserializer * register_type(Archive & /* ar */){
       
   433             #if ! defined(__BORLANDC__)
       
   434             typedef BOOST_DEDUCED_TYPENAME 
       
   435                 boost::serialization::type_info_implementation<T>::type::is_polymorphic typex;
       
   436             // it has? to be polymorphic
       
   437             BOOST_STATIC_ASSERT(typex::value);
       
   438             #endif
       
   439             return static_cast<basic_pointer_iserializer *>(NULL);
       
   440          }
       
   441     };
       
   442 
       
   443     template<class T>
       
   444     struct non_abstract
       
   445     {
       
   446         static const basic_pointer_iserializer * register_type(Archive & ar){
       
   447             return ar.register_type(static_cast<T *>(NULL));
       
   448         }
       
   449     };
       
   450 
       
   451     template<class T>
       
   452     static const basic_pointer_iserializer * register_type(Archive &ar, T & /*t*/){
       
   453         // there should never be any need to load an abstract polymorphic 
       
   454         // class pointer.  Inhibiting code generation for this
       
   455         // permits abstract base classes to be used - note: exception
       
   456         // virtual serialize functions used for plug-ins
       
   457         typedef BOOST_DEDUCED_TYPENAME
       
   458             mpl::eval_if<
       
   459                 serialization::is_abstract<T>,
       
   460                 mpl::identity<abstract<T> >,
       
   461                 mpl::identity<non_abstract<T> >    
       
   462             >::type typex;
       
   463         return typex::register_type(ar);
       
   464     }
       
   465 
       
   466     template<class T>
       
   467     static T * pointer_tweak(
       
   468         const boost::serialization::extended_type_info & eti,
       
   469         void * t,
       
   470         T &
       
   471     ) {
       
   472         // tweak the pointer back to the base class
       
   473         return static_cast<T *>(
       
   474             boost::serialization::void_upcast(
       
   475                 eti,
       
   476                 * boost::serialization::type_info_implementation<T>::type::get_instance(),
       
   477                 t
       
   478             )
       
   479         );
       
   480     }
       
   481 
       
   482     static void invoke(Archive & ar, Tptr & t){
       
   483         const basic_pointer_iserializer * bpis_ptr = register_type(ar, *t);
       
   484         const basic_pointer_iserializer * newbpis_ptr = ar.load_pointer(
       
   485             * reinterpret_cast<void **>(&t),
       
   486             bpis_ptr,
       
   487             archive_pointer_iserializer<Archive>::find
       
   488         );
       
   489         // if the pointer isn't that of the base class
       
   490         if(newbpis_ptr != bpis_ptr){
       
   491             t = pointer_tweak(newbpis_ptr->get_eti(), t, *t);
       
   492         }
       
   493     }
       
   494 };
       
   495 
       
   496 template<class Archive, class T>
       
   497 struct load_enum_type {
       
   498     static void invoke(Archive &ar, T &t){
       
   499         // convert integers to correct enum to load
       
   500         int i;
       
   501         ar >> boost::serialization::make_nvp(NULL, i);
       
   502         t = static_cast<T>(i);
       
   503     }
       
   504 };
       
   505 
       
   506 template<class Archive, class T>
       
   507 struct load_array_type {
       
   508     static void invoke(Archive &ar, T &t){
       
   509         // convert integers to correct enum to load
       
   510         int current_count = sizeof(t) / (
       
   511             static_cast<char *>(static_cast<void *>(&t[1])) 
       
   512             - static_cast<char *>(static_cast<void *>(&t[0]))
       
   513         );
       
   514         int count;
       
   515         ar >> BOOST_SERIALIZATION_NVP(count);
       
   516         if(count > current_count)
       
   517             boost::throw_exception(archive::archive_exception(
       
   518                 boost::archive::archive_exception::array_size_too_short
       
   519             ));
       
   520         int i;
       
   521         for(i = 0; i < count; ++i)
       
   522             ar >> boost::serialization::make_nvp("item", t[i]);
       
   523     }
       
   524 };
       
   525 
       
   526 // note bogus arguments to workaround msvc 6 silent runtime failure
       
   527 template<class Archive, class T>
       
   528 BOOST_DLLEXPORT 
       
   529 inline const basic_pointer_iserializer &
       
   530 instantiate_pointer_iserializer(
       
   531     Archive * /* ar = NULL */,
       
   532     T * /* t = NULL */
       
   533 ) BOOST_USED;
       
   534 
       
   535 template<class Archive, class T>
       
   536 BOOST_DLLEXPORT 
       
   537 inline const basic_pointer_iserializer &
       
   538 instantiate_pointer_iserializer(
       
   539     Archive * /* ar = NULL */,
       
   540     T * /* t = NULL */
       
   541 ){
       
   542     // note: reversal of order of arguments to work around msvc 6.0 bug
       
   543     // that manifests itself while trying to link.
       
   544     return pointer_iserializer<T, Archive>::instantiate();
       
   545 }
       
   546 
       
   547 } // detail
       
   548 
       
   549 template<class Archive, class T>
       
   550 inline void load(Archive &ar, T &t){
       
   551     // if this assertion trips. It means we're trying to load a
       
   552     // const object with a compiler that doesn't have correct
       
   553     // funtion template ordering.  On other compilers, this is
       
   554     // handled below.
       
   555     BOOST_STATIC_ASSERT(! boost::is_const<T>::value);
       
   556     typedef
       
   557         BOOST_DEDUCED_TYPENAME mpl::eval_if<is_pointer<T>,
       
   558             mpl::identity<detail::load_pointer_type<Archive, T> >
       
   559         ,//else
       
   560         BOOST_DEDUCED_TYPENAME mpl::eval_if<is_array<T>,
       
   561             mpl::identity<detail::load_array_type<Archive, T> >
       
   562         ,//else
       
   563         BOOST_DEDUCED_TYPENAME mpl::eval_if<is_enum<T>,
       
   564             mpl::identity<detail::load_enum_type<Archive, T> >
       
   565         ,//else
       
   566             mpl::identity<detail::load_non_pointer_type<Archive, T> >
       
   567         >
       
   568         >
       
   569         >::type typex;
       
   570     typex::invoke(ar, t);
       
   571 }
       
   572 
       
   573 // BORLAND
       
   574 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x560))
       
   575 // borland has a couple fo problems
       
   576 // a) if function is partiall specialized - see below
       
   577 // const paramters are transformed to non-const ones
       
   578 // b) implementation of base_object can't be made to work
       
   579 // correctly which results in all base_object s being const.
       
   580 // So, strip off the const for borland.  This breaks the trap
       
   581 // for loading const objects - but I see no alternative
       
   582 template<class Archive, class T>
       
   583 inline void load(Archive &ar, const T & t){
       
   584         load(ar, const_cast<T &>(t));
       
   585 }
       
   586 #endif
       
   587 
       
   588 // let wrappers through.  (Someday implement is_wrapper)
       
   589 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
       
   590 template<class Archive, class T>
       
   591 inline void load(Archive &ar, const serialization::nvp<T> &t){
       
   592         boost::archive::load(ar, const_cast<serialization::nvp<T> &>(t));
       
   593 }
       
   594 template<class Archive>
       
   595 inline void load(Archive &ar, const serialization::binary_object &t){
       
   596         boost::archive::load(ar, const_cast<serialization::binary_object &>(t));
       
   597 }
       
   598 
       
   599 //template<class Archive, class T>
       
   600 //inline void load(Archive &ar, const serialization::binary_object &t){
       
   601 //      load(ar, const_cast<binary_object &>(t));
       
   602 //}
       
   603 #endif
       
   604 
       
   605 } // namespace archive
       
   606 } // namespace boost
       
   607 
       
   608 #endif // BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP