os/ossrv/ossrv_pub/boost_apis/boost/archive/detail/iserializer.hpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/ossrv_pub/boost_apis/boost/archive/detail/iserializer.hpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,608 @@
     1.4 +#ifndef BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP
     1.5 +#define BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP
     1.6 +
     1.7 +// MS compatible compilers support #pragma once
     1.8 +#if defined(_MSC_VER) && (_MSC_VER >= 1020)
     1.9 +# pragma once
    1.10 +#pragma inline_depth(511)
    1.11 +#pragma inline_recursion(on)
    1.12 +#endif
    1.13 +
    1.14 +#if defined(__MWERKS__)
    1.15 +#pragma inline_depth(511)
    1.16 +#endif
    1.17 +
    1.18 +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
    1.19 +// iserializer.hpp: interface for serialization system.
    1.20 +
    1.21 +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . 
    1.22 +// Use, modification and distribution is subject to the Boost Software
    1.23 +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
    1.24 +// http://www.boost.org/LICENSE_1_0.txt)
    1.25 +
    1.26 +//  See http://www.boost.org for updates, documentation, and revision history.
    1.27 +
    1.28 +#include <new>     // for placement new
    1.29 +#include <memory>  // for auto_ptr
    1.30 +#include <cstddef> // size_t
    1.31 +
    1.32 +#include <boost/config.hpp>
    1.33 +#include <boost/detail/workaround.hpp>
    1.34 +#if defined(BOOST_NO_STDC_NAMESPACE)
    1.35 +namespace std{ 
    1.36 +    using ::size_t; 
    1.37 +} // namespace std
    1.38 +#endif
    1.39 +#include <boost/throw_exception.hpp>
    1.40 +#include <boost/smart_cast.hpp>
    1.41 +#include <boost/static_assert.hpp>
    1.42 +#include <boost/static_warning.hpp>
    1.43 +#include <boost/detail/no_exceptions_support.hpp>
    1.44 +
    1.45 +#include <boost/type_traits/is_pointer.hpp>
    1.46 +#include <boost/type_traits/is_fundamental.hpp>
    1.47 +#include <boost/type_traits/is_enum.hpp>
    1.48 +#include <boost/type_traits/is_const.hpp>
    1.49 +#include <boost/type_traits/remove_const.hpp>
    1.50 +#include <boost/serialization/is_abstract.hpp>
    1.51 +
    1.52 +#include <boost/mpl/eval_if.hpp>
    1.53 +#include <boost/mpl/if.hpp>
    1.54 +#include <boost/mpl/identity.hpp>
    1.55 +#include <boost/mpl/or.hpp>
    1.56 +#include <boost/mpl/and.hpp>
    1.57 +#include <boost/mpl/less.hpp>
    1.58 +#include <boost/mpl/greater_equal.hpp>
    1.59 +#include <boost/mpl/int.hpp>
    1.60 +#include <boost/mpl/list.hpp>
    1.61 +#include <boost/mpl/empty.hpp>
    1.62 +#include <boost/mpl/not.hpp>
    1.63 +
    1.64 + #ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO   
    1.65 +     #include <boost/serialization/extended_type_info_typeid.hpp>   
    1.66 + #endif 
    1.67 +// the following is need only for dynamic cast of polymorphic pointers
    1.68 +#include <boost/archive/detail/basic_iarchive.hpp>
    1.69 +#include <boost/archive/detail/basic_iserializer.hpp>
    1.70 +#include <boost/archive/detail/archive_pointer_iserializer.hpp>
    1.71 +#include <boost/archive/archive_exception.hpp>
    1.72 +
    1.73 +#include <boost/serialization/force_include.hpp>
    1.74 +#include <boost/serialization/serialization.hpp>
    1.75 +#include <boost/serialization/version.hpp>
    1.76 +#include <boost/serialization/level.hpp>
    1.77 +#include <boost/serialization/tracking.hpp>
    1.78 +#include <boost/serialization/type_info_implementation.hpp>
    1.79 +#include <boost/serialization/nvp.hpp>
    1.80 +#include <boost/serialization/binary_object.hpp>
    1.81 +#include <boost/serialization/void_cast.hpp>
    1.82 +
    1.83 +namespace boost {
    1.84 +
    1.85 +namespace serialization {
    1.86 +    class extended_type_info;
    1.87 +} // namespace serialization
    1.88 +
    1.89 +namespace archive {
    1.90 +
    1.91 +// an accessor to permit friend access to archives.  Needed because
    1.92 +// some compilers don't handle friend templates completely
    1.93 +class load_access {
    1.94 +public:
    1.95 +    template<class Archive, class T>
    1.96 +    static void load_primitive(Archive &ar, T &t){
    1.97 +        ar.load(t);
    1.98 +    }
    1.99 +};
   1.100 +
   1.101 +namespace detail {
   1.102 +
   1.103 +template<class Archive, class T>
   1.104 +class iserializer : public basic_iserializer
   1.105 +{
   1.106 +private:
   1.107 +    virtual void destroy(/*const*/ void *address) const {
   1.108 +        boost::serialization::access::destroy(static_cast<T *>(address));
   1.109 +    }
   1.110 +    // private constructor to inhibit any existence other than the 
   1.111 +    // static one
   1.112 +    explicit iserializer() :
   1.113 +        basic_iserializer(
   1.114 +            * boost::serialization::type_info_implementation<T>::type::get_instance()
   1.115 +        )
   1.116 +    {}
   1.117 +public:
   1.118 +    virtual BOOST_DLLEXPORT void load_object_data(
   1.119 +        basic_iarchive & ar,
   1.120 +        void *x, 
   1.121 +        const unsigned int file_version
   1.122 +    ) const BOOST_USED ;
   1.123 +    virtual bool class_info() const {
   1.124 +        return boost::serialization::implementation_level<T>::value 
   1.125 +            >= boost::serialization::object_class_info;
   1.126 +    }
   1.127 +    virtual bool tracking(const unsigned int flags) const {
   1.128 +//        if(0 != (flags & no_tracking))
   1.129 +//            return false;
   1.130 +        return boost::serialization::tracking_level<T>::value 
   1.131 +                == boost::serialization::track_always
   1.132 +            || boost::serialization::tracking_level<T>::value 
   1.133 +                == boost::serialization::track_selectivly
   1.134 +            && serialized_as_pointer();
   1.135 +    }
   1.136 +    virtual unsigned int version() const {
   1.137 +        return ::boost::serialization::version<T>::value;
   1.138 +    }
   1.139 +    virtual bool is_polymorphic() const {
   1.140 +        typedef BOOST_DEDUCED_TYPENAME 
   1.141 +            boost::serialization::type_info_implementation<
   1.142 +                T
   1.143 +            >::type::is_polymorphic::type typex;
   1.144 +        return typex::value;
   1.145 +    }
   1.146 +    static iserializer & instantiate(){
   1.147 +        static iserializer instance;
   1.148 +        return instance;
   1.149 +    }
   1.150 +    virtual ~iserializer(){};
   1.151 +};
   1.152 +
   1.153 +template<class Archive, class T>
   1.154 +BOOST_DLLEXPORT void iserializer<Archive, T>::load_object_data(
   1.155 +    basic_iarchive & ar,
   1.156 +    void *x, 
   1.157 +    const unsigned int file_version
   1.158 +) const {
   1.159 +    // make sure call is routed through the higest interface that might
   1.160 +    // be specialized by the user.
   1.161 +    boost::serialization::serialize_adl(
   1.162 +        boost::smart_cast_reference<Archive &>(ar),
   1.163 +        * static_cast<T *>(x), 
   1.164 +        file_version
   1.165 +    );
   1.166 +}
   1.167 +
   1.168 +// instantiation of this template creates a static object.  Note inversion of
   1.169 +// normal argument order to workaround bizarre error in MSVC 6.0 which only
   1.170 +// manifests iftself during compiler time.
   1.171 +template<class T, class Archive>
   1.172 +class pointer_iserializer : public archive_pointer_iserializer<Archive> 
   1.173 +{
   1.174 +private:
   1.175 +    virtual const basic_iserializer & get_basic_serializer() const {
   1.176 +        return iserializer<Archive, T>::instantiate();
   1.177 +    }
   1.178 +    virtual BOOST_DLLEXPORT void load_object_ptr(
   1.179 +        basic_iarchive & ar, 
   1.180 +        void * & x,
   1.181 +        const unsigned int file_version
   1.182 +    ) const BOOST_USED;
   1.183 +#if defined(__GNUC__) || ( defined(BOOST_MSVC) && (_MSC_VER <= 1300) )
   1.184 +public:
   1.185 +#endif
   1.186 +    // private constructor to inhibit any existence other than the 
   1.187 +    // static one.  Note GCC doesn't permit constructor to be private
   1.188 +    explicit BOOST_DLLEXPORT pointer_iserializer() BOOST_USED;
   1.189 +    static const pointer_iserializer instance;
   1.190 +public:
   1.191 +    // at least one compiler (CW) seems to require that serialize_adl
   1.192 +    // be explicitly instantiated. Still under investigation. 
   1.193 +    #if ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
   1.194 +    void (* const m)(Archive &, T &, const unsigned);
   1.195 +    boost::serialization::extended_type_info * (* e)();
   1.196 +    #endif
   1.197 +    static BOOST_DLLEXPORT const pointer_iserializer & instantiate() BOOST_USED;
   1.198 +    virtual ~pointer_iserializer(){};
   1.199 +};
   1.200 +
   1.201 +template<class T, class Archive>
   1.202 +BOOST_DLLEXPORT const pointer_iserializer<T, Archive> & 
   1.203 +pointer_iserializer<T, Archive>::instantiate() {
   1.204 +    return instance;
   1.205 +}
   1.206 +
   1.207 +// note: instances of this template to be constructed before the main
   1.208 +// is called in order for things to be initialized properly.  For this
   1.209 +// reason, hiding the instance in a static function as was done above
   1.210 +// won't work here so we created a free instance here.
   1.211 +template<class T, class Archive>
   1.212 +const pointer_iserializer<T, Archive> pointer_iserializer<T, Archive>::instance;
   1.213 +
   1.214 +// note trick to be sure that operator new is using class specific
   1.215 +// version if such exists. Due to Peter Dimov.
   1.216 +// note: the following fails if T has no default constructor.
   1.217 +// otherwise it would have been ideal
   1.218 +//struct heap_allocator : public T 
   1.219 +//{
   1.220 +//    T * invoke(){
   1.221 +//        return ::new(sizeof(T));
   1.222 +//    }
   1.223 +//}
   1.224 +
   1.225 +// note: this should really be a member of the load_ptr function
   1.226 +// below but some compilers still complain about this.
   1.227 +template<class T>
   1.228 +struct heap_allocator
   1.229 +{
   1.230 +    #if 0
   1.231 +        // note: this fails on msvc 7.0 and gcc 3.2
   1.232 +        template <class U, U x> struct test;
   1.233 +        typedef char* yes;
   1.234 +        typedef int* no;
   1.235 +        template <class U>
   1.236 +        yes has_op_new(U*, test<void* (*)(std::size_t), &U::operator new>* = 0);
   1.237 +        no has_op_new(...);
   1.238 +
   1.239 +        template<class U>
   1.240 +        T * new_operator(U);
   1.241 +
   1.242 +        T * new_operator(yes){
   1.243 +            return (T::operator new)(sizeof(T));
   1.244 +        }
   1.245 +        T * new_operator(no){
   1.246 +            return static_cast<T *>(operator new(sizeof(T)));
   1.247 +        }
   1.248 +        static T * invoke(){
   1.249 +            return new_operator(has_op_new(static_cast<T *>(NULL)));
   1.250 +        }
   1.251 +    #else
   1.252 +        // while this doesn't handle operator new overload for class T
   1.253 +        static T * invoke(){
   1.254 +            return static_cast<T *>(operator new(sizeof(T)));
   1.255 +        }
   1.256 +    #endif
   1.257 +};
   1.258 +
   1.259 +// due to Martin Ecker
   1.260 +template <typename T>
   1.261 +class auto_ptr_with_deleter
   1.262 +{
   1.263 +public:
   1.264 +    explicit auto_ptr_with_deleter(T* p) :
   1.265 +        m_p(p)
   1.266 +    {}
   1.267 +    ~auto_ptr_with_deleter(){
   1.268 +        if (m_p)
   1.269 +            boost::serialization::access::destroy(m_p);
   1.270 +    }
   1.271 +    T* get() const {
   1.272 +        return m_p;
   1.273 +    }
   1.274 +
   1.275 +    T* release() {
   1.276 +        T* p = m_p;
   1.277 +        m_p = NULL;
   1.278 +        return p;
   1.279 +    }
   1.280 +private:
   1.281 +    T* m_p;
   1.282 +};
   1.283 +
   1.284 +template<class T, class Archive>
   1.285 +BOOST_DLLEXPORT void pointer_iserializer<T, Archive>::load_object_ptr(
   1.286 +    basic_iarchive & ar, 
   1.287 +    void * & x,
   1.288 +    const unsigned int file_version
   1.289 +) const {
   1.290 +    Archive & ar_impl = boost::smart_cast_reference<Archive &>(ar);
   1.291 +
   1.292 +//    if(0 != (ar.get_flags() & no_object_creation)){
   1.293 +//        ar_impl >> boost::serialization::make_nvp(NULL, * static_cast<T *>(x));
   1.294 +//        return;
   1.295 +//    }
   1.296 +
   1.297 +    auto_ptr_with_deleter<T> ap(heap_allocator<T>::invoke());
   1.298 +    if(NULL == ap.get())
   1.299 +        boost::throw_exception(std::bad_alloc()) ;
   1.300 +
   1.301 +    T * t = ap.get();
   1.302 +    x = t;
   1.303 +
   1.304 +    // catch exception during load_construct_data so that we don't
   1.305 +    // automatically delete the t which is most likely not fully
   1.306 +    // constructed
   1.307 +    BOOST_TRY {
   1.308 +        // this addresses an obscure situtation that occurs when 
   1.309 +        // load_constructor de-serializes something through a pointer.
   1.310 +        ar.next_object_pointer(t);
   1.311 +        boost::serialization::load_construct_data_adl<Archive, T>(
   1.312 +            ar_impl,
   1.313 +            t, 
   1.314 +            file_version
   1.315 +        );
   1.316 +    }
   1.317 +    BOOST_CATCH(...){
   1.318 +        BOOST_RETHROW;
   1.319 +    }
   1.320 +    BOOST_CATCH_END
   1.321 +
   1.322 +    ar_impl >> boost::serialization::make_nvp(NULL, * t);
   1.323 +    ap.release();
   1.324 +}
   1.325 +
   1.326 +template<class T, class Archive>
   1.327 +#if ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
   1.328 +BOOST_DLLEXPORT pointer_iserializer<T, Archive>::pointer_iserializer() :
   1.329 +    archive_pointer_iserializer<Archive>(
   1.330 +        * boost::serialization::type_info_implementation<T>::type::get_instance()
   1.331 +    ),
   1.332 +    m(boost::serialization::serialize_adl<Archive, T>),
   1.333 +    e(boost::serialization::type_info_implementation<T>::type::get_instance)
   1.334 +#else
   1.335 +BOOST_DLLEXPORT pointer_iserializer<T, Archive>::pointer_iserializer() :
   1.336 +    archive_pointer_iserializer<Archive>(
   1.337 +        * boost::serialization::type_info_implementation<T>::type::get_instance()
   1.338 +    )
   1.339 +#endif
   1.340 +{
   1.341 +    iserializer<Archive, T> & bis = iserializer<Archive, T>::instantiate();
   1.342 +    bis.set_bpis(this);
   1.343 +}
   1.344 +
   1.345 +template<class Archive, class T>
   1.346 +struct load_non_pointer_type {
   1.347 +    // note this bounces the call right back to the archive
   1.348 +    // with no runtime overhead
   1.349 +    struct load_primitive {
   1.350 +        static void invoke(Archive & ar, T & t){
   1.351 +            load_access::load_primitive(ar, t);
   1.352 +        }
   1.353 +    };
   1.354 +    // note this bounces the call right back to the archive
   1.355 +    // with no runtime overhead
   1.356 +    struct load_only {
   1.357 +        static void invoke(Archive & ar, T & t){
   1.358 +            // short cut to user's serializer
   1.359 +            // make sure call is routed through the higest interface that might
   1.360 +            // be specialized by the user.
   1.361 +            boost::serialization::serialize_adl(
   1.362 +                ar, t, boost::serialization::version<T>::value
   1.363 +            );
   1.364 +        }
   1.365 +    };
   1.366 +
   1.367 +    // note this save class information including version
   1.368 +    // and serialization level to the archive
   1.369 +    struct load_standard {
   1.370 +        static void invoke(Archive &ar, T &t){
   1.371 +            //BOOST_STATIC_ASSERT(! boost::is_const<T>::value);
   1.372 +            // borland - for some reason T is const here - even though
   1.373 +            // its not called that way - so fix it her
   1.374 +            typedef BOOST_DEDUCED_TYPENAME boost::remove_const<T>::type typex;
   1.375 +            void * x = & const_cast<typex &>(t);
   1.376 +            ar.load_object(x, iserializer<Archive, T>::instantiate());
   1.377 +        }
   1.378 +    };
   1.379 +
   1.380 +    struct load_conditional {
   1.381 +        static void invoke(Archive &ar, T &t){
   1.382 +            //if(0 == (ar.get_flags() & no_tracking))
   1.383 +                load_standard::invoke(ar, t);
   1.384 +            //else
   1.385 +            //    load_only::invoke(ar, t);
   1.386 +        }
   1.387 +    };
   1.388 +
   1.389 +    typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
   1.390 +            // if its primitive
   1.391 +            mpl::equal_to<
   1.392 +                boost::serialization::implementation_level<T>,
   1.393 +                mpl::int_<boost::serialization::primitive_type>
   1.394 +            >,
   1.395 +            mpl::identity<load_primitive>,
   1.396 +        // else
   1.397 +        BOOST_DEDUCED_TYPENAME mpl::eval_if<
   1.398 +        // class info / version
   1.399 +        mpl::greater_equal<
   1.400 +                    boost::serialization::implementation_level<T>,
   1.401 +                    mpl::int_<boost::serialization::object_class_info>
   1.402 +                >,
   1.403 +        // do standard load
   1.404 +        mpl::identity<load_standard>,
   1.405 +    // else
   1.406 +    BOOST_DEDUCED_TYPENAME mpl::eval_if<
   1.407 +        // no tracking
   1.408 +                mpl::equal_to<
   1.409 +                    boost::serialization::tracking_level<T>,
   1.410 +                    mpl::int_<boost::serialization::track_never>
   1.411 +            >,
   1.412 +            // do a fast load
   1.413 +            mpl::identity<load_only>,
   1.414 +        // else
   1.415 +        // do a fast load only tracking is turned off
   1.416 +        mpl::identity<load_conditional>
   1.417 +    > > >::type typex;
   1.418 +
   1.419 +    static void invoke(Archive & ar, T &t){
   1.420 +        BOOST_STATIC_ASSERT((
   1.421 +            mpl::greater_equal<
   1.422 +                boost::serialization::implementation_level<T>, 
   1.423 +                mpl::int_<boost::serialization::primitive_type>
   1.424 +            >::value
   1.425 +        ));
   1.426 +        typex::invoke(ar, t);
   1.427 +    }
   1.428 +};
   1.429 +
   1.430 +template<class Archive, class Tptr>
   1.431 +struct load_pointer_type {
   1.432 +    template<class T>
   1.433 +    struct abstract
   1.434 +    {
   1.435 +        static const basic_pointer_iserializer * register_type(Archive & /* ar */){
   1.436 +            #if ! defined(__BORLANDC__)
   1.437 +            typedef BOOST_DEDUCED_TYPENAME 
   1.438 +                boost::serialization::type_info_implementation<T>::type::is_polymorphic typex;
   1.439 +            // it has? to be polymorphic
   1.440 +            BOOST_STATIC_ASSERT(typex::value);
   1.441 +            #endif
   1.442 +            return static_cast<basic_pointer_iserializer *>(NULL);
   1.443 +         }
   1.444 +    };
   1.445 +
   1.446 +    template<class T>
   1.447 +    struct non_abstract
   1.448 +    {
   1.449 +        static const basic_pointer_iserializer * register_type(Archive & ar){
   1.450 +            return ar.register_type(static_cast<T *>(NULL));
   1.451 +        }
   1.452 +    };
   1.453 +
   1.454 +    template<class T>
   1.455 +    static const basic_pointer_iserializer * register_type(Archive &ar, T & /*t*/){
   1.456 +        // there should never be any need to load an abstract polymorphic 
   1.457 +        // class pointer.  Inhibiting code generation for this
   1.458 +        // permits abstract base classes to be used - note: exception
   1.459 +        // virtual serialize functions used for plug-ins
   1.460 +        typedef BOOST_DEDUCED_TYPENAME
   1.461 +            mpl::eval_if<
   1.462 +                serialization::is_abstract<T>,
   1.463 +                mpl::identity<abstract<T> >,
   1.464 +                mpl::identity<non_abstract<T> >    
   1.465 +            >::type typex;
   1.466 +        return typex::register_type(ar);
   1.467 +    }
   1.468 +
   1.469 +    template<class T>
   1.470 +    static T * pointer_tweak(
   1.471 +        const boost::serialization::extended_type_info & eti,
   1.472 +        void * t,
   1.473 +        T &
   1.474 +    ) {
   1.475 +        // tweak the pointer back to the base class
   1.476 +        return static_cast<T *>(
   1.477 +            boost::serialization::void_upcast(
   1.478 +                eti,
   1.479 +                * boost::serialization::type_info_implementation<T>::type::get_instance(),
   1.480 +                t
   1.481 +            )
   1.482 +        );
   1.483 +    }
   1.484 +
   1.485 +    static void invoke(Archive & ar, Tptr & t){
   1.486 +        const basic_pointer_iserializer * bpis_ptr = register_type(ar, *t);
   1.487 +        const basic_pointer_iserializer * newbpis_ptr = ar.load_pointer(
   1.488 +            * reinterpret_cast<void **>(&t),
   1.489 +            bpis_ptr,
   1.490 +            archive_pointer_iserializer<Archive>::find
   1.491 +        );
   1.492 +        // if the pointer isn't that of the base class
   1.493 +        if(newbpis_ptr != bpis_ptr){
   1.494 +            t = pointer_tweak(newbpis_ptr->get_eti(), t, *t);
   1.495 +        }
   1.496 +    }
   1.497 +};
   1.498 +
   1.499 +template<class Archive, class T>
   1.500 +struct load_enum_type {
   1.501 +    static void invoke(Archive &ar, T &t){
   1.502 +        // convert integers to correct enum to load
   1.503 +        int i;
   1.504 +        ar >> boost::serialization::make_nvp(NULL, i);
   1.505 +        t = static_cast<T>(i);
   1.506 +    }
   1.507 +};
   1.508 +
   1.509 +template<class Archive, class T>
   1.510 +struct load_array_type {
   1.511 +    static void invoke(Archive &ar, T &t){
   1.512 +        // convert integers to correct enum to load
   1.513 +        int current_count = sizeof(t) / (
   1.514 +            static_cast<char *>(static_cast<void *>(&t[1])) 
   1.515 +            - static_cast<char *>(static_cast<void *>(&t[0]))
   1.516 +        );
   1.517 +        int count;
   1.518 +        ar >> BOOST_SERIALIZATION_NVP(count);
   1.519 +        if(count > current_count)
   1.520 +            boost::throw_exception(archive::archive_exception(
   1.521 +                boost::archive::archive_exception::array_size_too_short
   1.522 +            ));
   1.523 +        int i;
   1.524 +        for(i = 0; i < count; ++i)
   1.525 +            ar >> boost::serialization::make_nvp("item", t[i]);
   1.526 +    }
   1.527 +};
   1.528 +
   1.529 +// note bogus arguments to workaround msvc 6 silent runtime failure
   1.530 +template<class Archive, class T>
   1.531 +BOOST_DLLEXPORT 
   1.532 +inline const basic_pointer_iserializer &
   1.533 +instantiate_pointer_iserializer(
   1.534 +    Archive * /* ar = NULL */,
   1.535 +    T * /* t = NULL */
   1.536 +) BOOST_USED;
   1.537 +
   1.538 +template<class Archive, class T>
   1.539 +BOOST_DLLEXPORT 
   1.540 +inline const basic_pointer_iserializer &
   1.541 +instantiate_pointer_iserializer(
   1.542 +    Archive * /* ar = NULL */,
   1.543 +    T * /* t = NULL */
   1.544 +){
   1.545 +    // note: reversal of order of arguments to work around msvc 6.0 bug
   1.546 +    // that manifests itself while trying to link.
   1.547 +    return pointer_iserializer<T, Archive>::instantiate();
   1.548 +}
   1.549 +
   1.550 +} // detail
   1.551 +
   1.552 +template<class Archive, class T>
   1.553 +inline void load(Archive &ar, T &t){
   1.554 +    // if this assertion trips. It means we're trying to load a
   1.555 +    // const object with a compiler that doesn't have correct
   1.556 +    // funtion template ordering.  On other compilers, this is
   1.557 +    // handled below.
   1.558 +    BOOST_STATIC_ASSERT(! boost::is_const<T>::value);
   1.559 +    typedef
   1.560 +        BOOST_DEDUCED_TYPENAME mpl::eval_if<is_pointer<T>,
   1.561 +            mpl::identity<detail::load_pointer_type<Archive, T> >
   1.562 +        ,//else
   1.563 +        BOOST_DEDUCED_TYPENAME mpl::eval_if<is_array<T>,
   1.564 +            mpl::identity<detail::load_array_type<Archive, T> >
   1.565 +        ,//else
   1.566 +        BOOST_DEDUCED_TYPENAME mpl::eval_if<is_enum<T>,
   1.567 +            mpl::identity<detail::load_enum_type<Archive, T> >
   1.568 +        ,//else
   1.569 +            mpl::identity<detail::load_non_pointer_type<Archive, T> >
   1.570 +        >
   1.571 +        >
   1.572 +        >::type typex;
   1.573 +    typex::invoke(ar, t);
   1.574 +}
   1.575 +
   1.576 +// BORLAND
   1.577 +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x560))
   1.578 +// borland has a couple fo problems
   1.579 +// a) if function is partiall specialized - see below
   1.580 +// const paramters are transformed to non-const ones
   1.581 +// b) implementation of base_object can't be made to work
   1.582 +// correctly which results in all base_object s being const.
   1.583 +// So, strip off the const for borland.  This breaks the trap
   1.584 +// for loading const objects - but I see no alternative
   1.585 +template<class Archive, class T>
   1.586 +inline void load(Archive &ar, const T & t){
   1.587 +        load(ar, const_cast<T &>(t));
   1.588 +}
   1.589 +#endif
   1.590 +
   1.591 +// let wrappers through.  (Someday implement is_wrapper)
   1.592 +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
   1.593 +template<class Archive, class T>
   1.594 +inline void load(Archive &ar, const serialization::nvp<T> &t){
   1.595 +        boost::archive::load(ar, const_cast<serialization::nvp<T> &>(t));
   1.596 +}
   1.597 +template<class Archive>
   1.598 +inline void load(Archive &ar, const serialization::binary_object &t){
   1.599 +        boost::archive::load(ar, const_cast<serialization::binary_object &>(t));
   1.600 +}
   1.601 +
   1.602 +//template<class Archive, class T>
   1.603 +//inline void load(Archive &ar, const serialization::binary_object &t){
   1.604 +//      load(ar, const_cast<binary_object &>(t));
   1.605 +//}
   1.606 +#endif
   1.607 +
   1.608 +} // namespace archive
   1.609 +} // namespace boost
   1.610 +
   1.611 +#endif // BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP