os/ossrv/ossrv_pub/boost_apis/boost/archive/detail/oserializer.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/oserializer.hpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,574 @@
     1.4 +#ifndef BOOST_ARCHIVE_OSERIALIZER_HPP
     1.5 +#define BOOST_ARCHIVE_OSERIALIZER_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 +// oserializer.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 <cassert>
    1.29 +
    1.30 +#include <boost/config.hpp>
    1.31 +#include <boost/detail/workaround.hpp>
    1.32 +#include <boost/throw_exception.hpp>
    1.33 +#include <boost/smart_cast.hpp>
    1.34 +#include <boost/static_assert.hpp>
    1.35 +#include <boost/static_warning.hpp>
    1.36 +
    1.37 +#include <boost/type_traits/is_pointer.hpp>
    1.38 +#include <boost/type_traits/is_fundamental.hpp>
    1.39 +#include <boost/type_traits/is_enum.hpp>
    1.40 +#include <boost/type_traits/is_volatile.hpp>
    1.41 +#include <boost/type_traits/is_const.hpp>
    1.42 +#include <boost/type_traits/is_same.hpp>
    1.43 +#include <boost/serialization/is_abstract.hpp>
    1.44 +
    1.45 +#include <boost/mpl/eval_if.hpp>
    1.46 +#include <boost/mpl/and.hpp>
    1.47 +#include <boost/mpl/less.hpp>
    1.48 +#include <boost/mpl/greater_equal.hpp>
    1.49 +#include <boost/mpl/equal_to.hpp>
    1.50 +#include <boost/mpl/int.hpp>
    1.51 +#include <boost/mpl/identity.hpp>
    1.52 +#include <boost/mpl/list.hpp>
    1.53 +#include <boost/mpl/empty.hpp>
    1.54 +#include <boost/mpl/not.hpp>
    1.55 +
    1.56 + #ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO   
    1.57 +     #include <boost/serialization/extended_type_info_typeid.hpp>   
    1.58 + #endif 
    1.59 +// the following is need only for dynamic cast of polymorphic pointers
    1.60 +#include <boost/archive/detail/basic_oarchive.hpp>
    1.61 +#include <boost/archive/detail/basic_oserializer.hpp>
    1.62 +#include <boost/archive/detail/archive_pointer_oserializer.hpp>
    1.63 +
    1.64 +#include <boost/serialization/force_include.hpp>
    1.65 +#include <boost/serialization/serialization.hpp>
    1.66 +#include <boost/serialization/version.hpp>
    1.67 +#include <boost/serialization/level.hpp>
    1.68 +#include <boost/serialization/tracking.hpp>
    1.69 +#include <boost/serialization/type_info_implementation.hpp>
    1.70 +#include <boost/serialization/nvp.hpp>
    1.71 +#include <boost/serialization/void_cast.hpp>
    1.72 +
    1.73 +#include <boost/archive/archive_exception.hpp>
    1.74 +
    1.75 +namespace boost {
    1.76 +
    1.77 +namespace serialization {
    1.78 +    class extended_type_info;
    1.79 +} // namespace serialization
    1.80 +
    1.81 +namespace archive {
    1.82 +
    1.83 +// an accessor to permit friend access to archives.  Needed because
    1.84 +// some compilers don't handle friend templates completely
    1.85 +class save_access {
    1.86 +public:
    1.87 +    template<class Archive>
    1.88 +    static void end_preamble(Archive & ar){
    1.89 +        ar.end_preamble();
    1.90 +    }
    1.91 +    template<class Archive, class T>
    1.92 +    static void save_primitive(Archive & ar, const  T & t){
    1.93 +        ar.end_preamble();
    1.94 +        ar.save(t);
    1.95 +    }
    1.96 +};
    1.97 +
    1.98 +namespace detail {
    1.99 +
   1.100 +template<class Archive, class T>
   1.101 +class oserializer : public basic_oserializer
   1.102 +{
   1.103 +private:
   1.104 +    // private constructor to inhibit any existence other than the 
   1.105 +    // static one
   1.106 +    explicit oserializer() :
   1.107 +        basic_oserializer(
   1.108 +            * boost::serialization::type_info_implementation<T>::type::get_instance()
   1.109 +        )
   1.110 +    {}
   1.111 +public:
   1.112 +    virtual BOOST_DLLEXPORT void save_object_data(
   1.113 +        basic_oarchive & ar,    
   1.114 +        const void *x
   1.115 +    ) const BOOST_USED ;
   1.116 +    virtual bool class_info() const {
   1.117 +        return boost::serialization::implementation_level<T>::value 
   1.118 +            >= boost::serialization::object_class_info;
   1.119 +    }
   1.120 +    virtual bool tracking(const unsigned int flags) const {
   1.121 +//        if(0 != (flags &  no_tracking))
   1.122 +//            return false;
   1.123 +        return boost::serialization::tracking_level<T>::value == boost::serialization::track_always
   1.124 +            || boost::serialization::tracking_level<T>::value == boost::serialization::track_selectivly
   1.125 +            && serialized_as_pointer();
   1.126 +    }
   1.127 +    virtual unsigned int version() const {
   1.128 +        return ::boost::serialization::version<T>::value;
   1.129 +    }
   1.130 +    virtual bool is_polymorphic() const {
   1.131 +        typedef BOOST_DEDUCED_TYPENAME boost::serialization::type_info_implementation<
   1.132 +            T
   1.133 +        >::type::is_polymorphic::type typex;
   1.134 +        return typex::value;
   1.135 +    }
   1.136 +    static oserializer & instantiate(){
   1.137 +        static oserializer instance;
   1.138 +        return instance;
   1.139 +    }
   1.140 +    virtual ~oserializer(){}
   1.141 +};
   1.142 +
   1.143 +template<class Archive, class T>
   1.144 +BOOST_DLLEXPORT void oserializer<Archive, T>::save_object_data(
   1.145 +    basic_oarchive & ar,    
   1.146 +    const void *x
   1.147 +) const {
   1.148 +    // make sure call is routed through the highest interface that might
   1.149 +    // be specialized by the user.
   1.150 +    boost::serialization::serialize_adl(
   1.151 +        boost::smart_cast_reference<Archive &>(ar),
   1.152 +        * static_cast<T *>(const_cast<void *>(x)),
   1.153 +        version()
   1.154 +    );
   1.155 +}
   1.156 +
   1.157 +// instantiation of this template creates a static object.  Note inversion of
   1.158 +// normal argument order to workaround bizarre error in MSVC 6.0 which only
   1.159 +// manifests iftself during compiler time.
   1.160 +template<class T, class Archive>
   1.161 +class pointer_oserializer : public archive_pointer_oserializer<Archive> 
   1.162 +{
   1.163 +private:
   1.164 +    virtual const basic_oserializer & get_basic_serializer() const {
   1.165 +        return oserializer<Archive, T>::instantiate();
   1.166 +    }
   1.167 +    virtual BOOST_DLLEXPORT void save_object_ptr(
   1.168 +        basic_oarchive & ar,
   1.169 +        const void * x
   1.170 +    ) const BOOST_USED ;
   1.171 +#if defined(__GNUC__) || ( defined(BOOST_MSVC) && (_MSC_VER <= 1300) )
   1.172 +public:
   1.173 +#endif
   1.174 +    // private constructor to inhibit any existence other than the 
   1.175 +    // static one.  Note GCC doesn't permit constructor to be private
   1.176 +    explicit BOOST_DLLEXPORT pointer_oserializer() BOOST_USED;
   1.177 +    static const pointer_oserializer instance;
   1.178 +public:
   1.179 +    #if ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
   1.180 +    // at least one compiler (CW) seems to require that serialize_adl
   1.181 +    // be explicitly instantiated. Still under investigation. 
   1.182 +    void (* const m)(Archive &, T &, const unsigned);
   1.183 +    boost::serialization::extended_type_info * (* e)();
   1.184 +    #endif
   1.185 +    static BOOST_DLLEXPORT const pointer_oserializer & instantiate() BOOST_USED;
   1.186 +    virtual ~pointer_oserializer(){}
   1.187 +};
   1.188 +
   1.189 +template<class T, class Archive>
   1.190 +BOOST_DLLEXPORT const pointer_oserializer<T, Archive> & 
   1.191 +pointer_oserializer<T, Archive>::instantiate(){
   1.192 +    return instance;
   1.193 +}
   1.194 +
   1.195 +// note: instances of this template to be constructed before the main
   1.196 +// is called in order for things to be initialized properly.  For this
   1.197 +// reason, hiding the instance in a static function as was done above
   1.198 +// won't work here so we created a free instance here.
   1.199 +template<class T, class Archive>
   1.200 +const pointer_oserializer<T, Archive> pointer_oserializer<T, Archive>::instance;
   1.201 +
   1.202 +template<class T, class Archive>
   1.203 +BOOST_DLLEXPORT void pointer_oserializer<T, Archive>::save_object_ptr(
   1.204 +    basic_oarchive & ar,
   1.205 +    const void * x
   1.206 +) const {
   1.207 +    assert(NULL != x);
   1.208 +    // make sure call is routed through the highest interface that might
   1.209 +    // be specialized by the user.
   1.210 +    T * t = static_cast<T *>(const_cast<void *>(x));
   1.211 +    const unsigned int file_version = boost::serialization::version<T>::value;
   1.212 +    Archive & ar_impl = boost::smart_cast_reference<Archive &>(ar);
   1.213 +    boost::serialization::save_construct_data_adl<Archive, T>(
   1.214 +        ar_impl, 
   1.215 +        t, 
   1.216 +        file_version
   1.217 +    );
   1.218 +    ar_impl << boost::serialization::make_nvp(NULL, * t);
   1.219 +}
   1.220 +
   1.221 +template<class T, class Archive>
   1.222 +#if ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
   1.223 +BOOST_DLLEXPORT pointer_oserializer<T, Archive>::pointer_oserializer() :
   1.224 +    archive_pointer_oserializer<Archive>(
   1.225 +        * boost::serialization::type_info_implementation<T>::type::get_instance()
   1.226 +    ),
   1.227 +    m(boost::serialization::serialize_adl<Archive, T>),
   1.228 +    e(boost::serialization::type_info_implementation<T>::type::get_instance)
   1.229 +#else
   1.230 +BOOST_DLLEXPORT pointer_oserializer<T, Archive>::pointer_oserializer() :
   1.231 +    archive_pointer_oserializer<Archive>(
   1.232 +        * boost::serialization::type_info_implementation<T>::type::get_instance()
   1.233 +    )
   1.234 +#endif
   1.235 +{
   1.236 +    // make sure appropriate member function is instantiated
   1.237 +    oserializer<Archive, T> & bos = oserializer<Archive, T>::instantiate();
   1.238 +    bos.set_bpos(this);
   1.239 +}
   1.240 +
   1.241 +template<class Archive, class T>
   1.242 +struct save_non_pointer_type {
   1.243 +    // note this bounces the call right back to the archive
   1.244 +    // with no runtime overhead
   1.245 +    struct save_primitive {
   1.246 +        static void invoke(Archive & ar, const T & t){
   1.247 +            save_access::save_primitive(ar, t);
   1.248 +        }
   1.249 +    };
   1.250 +    // same as above but passes through serialization
   1.251 +    struct save_only {
   1.252 +        static void invoke(Archive & ar, const T & t){
   1.253 +            // make sure call is routed through the highest interface that might
   1.254 +            // be specialized by the user.
   1.255 +            boost::serialization::serialize_adl(
   1.256 +                ar, 
   1.257 +                const_cast<T &>(t), 
   1.258 +                ::boost::serialization::version<T>::value
   1.259 +            );
   1.260 +        }
   1.261 +    };
   1.262 +    // adds class information to the archive. This includes
   1.263 +    // serialization level and class version
   1.264 +    struct save_standard {
   1.265 +        static void invoke(Archive &ar, const T & t){
   1.266 +            ar.save_object(& t, oserializer<Archive, T>::instantiate());
   1.267 +        }
   1.268 +    };
   1.269 +
   1.270 +    // adds class information to the archive. This includes
   1.271 +    // serialization level and class version
   1.272 +    struct save_conditional {
   1.273 +        static void invoke(Archive &ar, const T &t){
   1.274 +            //if(0 == (ar.get_flags() & no_tracking))
   1.275 +                save_standard::invoke(ar, t);
   1.276 +            //else
   1.277 +            //   save_only::invoke(ar, t);
   1.278 +        }
   1.279 +    };
   1.280 +
   1.281 +    typedef 
   1.282 +        BOOST_DEDUCED_TYPENAME mpl::eval_if<
   1.283 +        // if its primitive
   1.284 +            mpl::equal_to<
   1.285 +                boost::serialization::implementation_level<T>,
   1.286 +                mpl::int_<boost::serialization::primitive_type>
   1.287 +            >,
   1.288 +            mpl::identity<save_primitive>,
   1.289 +        // else
   1.290 +        BOOST_DEDUCED_TYPENAME mpl::eval_if<
   1.291 +            // class info / version
   1.292 +            mpl::greater_equal<
   1.293 +                boost::serialization::implementation_level<T>,
   1.294 +                mpl::int_<boost::serialization::object_class_info>
   1.295 +            >,
   1.296 +            // do standard save
   1.297 +            mpl::identity<save_standard>,
   1.298 +        // else
   1.299 +        BOOST_DEDUCED_TYPENAME mpl::eval_if<
   1.300 +                // no tracking
   1.301 +            mpl::equal_to<
   1.302 +                boost::serialization::tracking_level<T>,
   1.303 +                mpl::int_<boost::serialization::track_never>
   1.304 +            >,
   1.305 +            // do a fast save
   1.306 +            mpl::identity<save_only>,
   1.307 +        // else
   1.308 +            // do a fast save only tracking is turned off
   1.309 +            mpl::identity<save_conditional>
   1.310 +    > > >::type typex; 
   1.311 +
   1.312 +    static void invoke(Archive & ar, const T & t){
   1.313 +        // check that we're not trying to serialize something that
   1.314 +        // has been marked not to be serialized.  If this your program
   1.315 +        // traps here, you've tried to serialize a class whose trait
   1.316 +        // has been marked "non-serializable". Either reset the trait
   1.317 +        // (see level.hpp) or change program not to serialize items of this class
   1.318 +        BOOST_STATIC_ASSERT((
   1.319 +            mpl::greater_equal<
   1.320 +                boost::serialization::implementation_level<T>, 
   1.321 +                mpl::int_<boost::serialization::primitive_type>
   1.322 +            >::value
   1.323 +        ));
   1.324 +        typex::invoke(ar, t);
   1.325 +    };
   1.326 +};
   1.327 +
   1.328 +template<class Archive, class TPtr>
   1.329 +struct save_pointer_type {
   1.330 +    template<class T>
   1.331 +    struct abstract
   1.332 +    {
   1.333 +        static const basic_pointer_oserializer * register_type(Archive & /* ar */){
   1.334 +            // it has? to be polymorphic
   1.335 +            BOOST_STATIC_ASSERT(
   1.336 +                boost::serialization::type_info_implementation<T>::type::is_polymorphic::value
   1.337 +            );
   1.338 +            return static_cast<const basic_pointer_oserializer *>(NULL);
   1.339 +        }
   1.340 +    };
   1.341 +
   1.342 +    template<class T>
   1.343 +    struct non_abstract
   1.344 +    {
   1.345 +        static const basic_pointer_oserializer * register_type(Archive & ar){
   1.346 +            return ar.register_type(static_cast<T *>(NULL));
   1.347 +        }
   1.348 +    };
   1.349 +
   1.350 +    template<class T>
   1.351 +    static const basic_pointer_oserializer * register_type(Archive &ar, T & /*t*/){
   1.352 +        // there should never be any need to save an abstract polymorphic 
   1.353 +        // class pointer.  Inhibiting code generation for this
   1.354 +        // permits abstract base classes to be used - note: exception
   1.355 +        // virtual serialize functions used for plug-ins
   1.356 +        typedef 
   1.357 +            BOOST_DEDUCED_TYPENAME mpl::eval_if<
   1.358 +                serialization::is_abstract<T>,
   1.359 +                mpl::identity<abstract<T> >,
   1.360 +                mpl::identity<non_abstract<T> >       
   1.361 +            >::type typex;
   1.362 +        return typex::register_type(ar);
   1.363 +    }
   1.364 +
   1.365 +    template<class T>
   1.366 +    struct non_polymorphic
   1.367 +    {
   1.368 +        static void save(
   1.369 +            Archive &ar, 
   1.370 +            const T & t, 
   1.371 +            const basic_pointer_oserializer * bpos_ptr
   1.372 +        ){
   1.373 +            // save the requested pointer type
   1.374 +            ar.save_pointer(& t, bpos_ptr);
   1.375 +        }
   1.376 +    };
   1.377 +
   1.378 +    template<class T>
   1.379 +    struct polymorphic
   1.380 +    {
   1.381 +        static void save(
   1.382 +            Archive &ar, 
   1.383 +            const T & t, 
   1.384 +            const basic_pointer_oserializer * bpos_ptr
   1.385 +        ){
   1.386 +            const boost::serialization::extended_type_info * this_type
   1.387 +                = boost::serialization::type_info_implementation<T>::type::get_instance();
   1.388 +            // retrieve the true type of the object pointed to
   1.389 +            // if this assertion fails its an error in this library
   1.390 +            assert(NULL != this_type);
   1.391 +            const boost::serialization::extended_type_info * true_type 
   1.392 +                = boost::serialization::type_info_implementation<T>::type::get_derived_extended_type_info(t);
   1.393 +            // note:if this exception is thrown, be sure that derived pointer
   1.394 +            // is either regsitered or exported.
   1.395 +            if(NULL == true_type){
   1.396 +                boost::throw_exception(
   1.397 +                    archive_exception(archive_exception::unregistered_class)
   1.398 +                );
   1.399 +            }
   1.400 +
   1.401 +            // if its not a pointer to a more derived type
   1.402 +            const void *vp = static_cast<const void *>(&t);
   1.403 +            if(*this_type == *true_type){
   1.404 +                ar.save_pointer(vp, bpos_ptr);
   1.405 +                return;
   1.406 +            }
   1.407 +            // convert pointer to more derived type. if this is thrown
   1.408 +            // it means that the base/derived relationship hasn't be registered
   1.409 +            vp = serialization::void_downcast(*true_type, *this_type, &t);
   1.410 +            if(NULL == vp){
   1.411 +                boost::throw_exception(
   1.412 +                    archive_exception(archive_exception::unregistered_cast)
   1.413 +                );
   1.414 +            }
   1.415 +
   1.416 +            // sice true_type is valid, and this only gets made if the 
   1.417 +            // pointer oserializer object has been created, this should never
   1.418 +            // fail
   1.419 +            bpos_ptr = archive_pointer_oserializer<Archive>::find(* true_type);
   1.420 +            assert(NULL != bpos_ptr);
   1.421 +            if(NULL == bpos_ptr)
   1.422 +                boost::throw_exception(
   1.423 +                    archive_exception(archive_exception::unregistered_class)
   1.424 +                );
   1.425 +            ar.save_pointer(vp, bpos_ptr);
   1.426 +        }
   1.427 +    };
   1.428 +
   1.429 +    template<class T>
   1.430 +    static void save(
   1.431 +        Archive & ar, 
   1.432 +        const T &t,
   1.433 +        const basic_pointer_oserializer * bpos_ptr
   1.434 +    ){
   1.435 +        typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
   1.436 +            BOOST_DEDUCED_TYPENAME boost::serialization::
   1.437 +                type_info_implementation<T>::type::is_polymorphic,
   1.438 +            mpl::identity<polymorphic<T> >,
   1.439 +            mpl::identity<non_polymorphic<T> >
   1.440 +        >::type typey;
   1.441 +        typey::save(ar, const_cast<T &>(t), bpos_ptr);
   1.442 +    }
   1.443 +
   1.444 +    template<class T>
   1.445 +    static void const_check(T & t){
   1.446 +        BOOST_STATIC_ASSERT(! boost::is_const<T>::value);
   1.447 +    }
   1.448 +
   1.449 +    static void invoke(Archive &ar, const TPtr t){
   1.450 +        #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
   1.451 +            // if your program traps here, its because you tried to do
   1.452 +            // something like ar << t where t is a pointer to a const value
   1.453 +            // void f3(A const* a, text_oarchive& oa)
   1.454 +            // {
   1.455 +            //     oa << a;
   1.456 +            // }
   1.457 +            // with a compiler which doesn't support remove_const
   1.458 +            // const_check(* t);
   1.459 +        #else
   1.460 +            // otherwise remove the const
   1.461 +        #endif
   1.462 +        const basic_pointer_oserializer * bpos_ptr =  register_type(ar, * t);
   1.463 +        if(NULL == t){
   1.464 +            basic_oarchive & boa = boost::smart_cast_reference<basic_oarchive &>(ar);
   1.465 +            boa.save_null_pointer();
   1.466 +            save_access::end_preamble(ar);
   1.467 +            return;
   1.468 +        }
   1.469 +        save(ar, * t, bpos_ptr);
   1.470 +    };
   1.471 +};
   1.472 +
   1.473 +template<class Archive, class T>
   1.474 +struct save_enum_type
   1.475 +{
   1.476 +    static void invoke(Archive &ar, const T &t){
   1.477 +        // convert enum to integers on save
   1.478 +        const int i = static_cast<int>(t);
   1.479 +        ar << boost::serialization::make_nvp(NULL, i);
   1.480 +    }
   1.481 +};
   1.482 +
   1.483 +template<class Archive, class T>
   1.484 +struct save_array_type
   1.485 +{
   1.486 +    static void invoke(Archive &ar, const T &t){
   1.487 +        save_access::end_preamble(ar);
   1.488 +        // consider alignment
   1.489 +        int count = sizeof(t) / (
   1.490 +            static_cast<const char *>(static_cast<const void *>(&t[1])) 
   1.491 +            - static_cast<const char *>(static_cast<const void *>(&t[0]))
   1.492 +        );
   1.493 +        ar << BOOST_SERIALIZATION_NVP(count);
   1.494 +        int i;
   1.495 +        for(i = 0; i < count; ++i)
   1.496 +            ar << boost::serialization::make_nvp("item", t[i]);
   1.497 +    }
   1.498 +};
   1.499 +
   1.500 +// note bogus arguments to workaround msvc 6 silent runtime failure
   1.501 +// declaration to satisfy gcc
   1.502 +template<class Archive, class T>
   1.503 +BOOST_DLLEXPORT const basic_pointer_oserializer &
   1.504 +instantiate_pointer_oserializer(
   1.505 +    Archive * /* ar = NULL */,
   1.506 +    T * /* t = NULL */
   1.507 +) BOOST_USED ;
   1.508 +// definition
   1.509 +template<class Archive, class T>
   1.510 +BOOST_DLLEXPORT const basic_pointer_oserializer &
   1.511 +instantiate_pointer_oserializer(
   1.512 +    Archive * /* ar = NULL */,
   1.513 +    T * /* t = NULL */
   1.514 +){
   1.515 +    // note: reversal of order of arguments to work around msvc 6.0 bug
   1.516 +    // that manifests itself while trying to link.
   1.517 +    return pointer_oserializer<T, Archive>::instantiate();
   1.518 +}
   1.519 +
   1.520 +} // detail
   1.521 +
   1.522 +template<class Archive, class T>
   1.523 +inline void save(Archive & ar, const T &t){
   1.524 +    typedef 
   1.525 +        BOOST_DEDUCED_TYPENAME mpl::eval_if<is_pointer<T>,
   1.526 +            mpl::identity<detail::save_pointer_type<Archive, T> >,
   1.527 +        //else
   1.528 +        BOOST_DEDUCED_TYPENAME mpl::eval_if<is_enum<T>,
   1.529 +            mpl::identity<detail::save_enum_type<Archive, T> >,
   1.530 +        //else
   1.531 +        BOOST_DEDUCED_TYPENAME mpl::eval_if<is_array<T>,
   1.532 +            mpl::identity<detail::save_array_type<Archive, T> >,
   1.533 +        //else
   1.534 +            mpl::identity<detail::save_non_pointer_type<Archive, T> >
   1.535 +        >
   1.536 +        >
   1.537 +        >::type typex;
   1.538 +    typex::invoke(ar, t);
   1.539 +}
   1.540 +
   1.541 +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
   1.542 +
   1.543 +template<class T>
   1.544 +struct check_tracking {
   1.545 +    typedef BOOST_DEDUCED_TYPENAME mpl::if_<
   1.546 +        // if its never tracked.
   1.547 +        BOOST_DEDUCED_TYPENAME mpl::equal_to<
   1.548 +            serialization::tracking_level<T>,
   1.549 +            mpl::int_<serialization::track_never>
   1.550 +        >,
   1.551 +        // it better not be a pointer
   1.552 +        mpl::not_<is_pointer<T> >,
   1.553 +    //else
   1.554 +        // otherwise if it might be tracked.  So there shouldn't
   1.555 +        // be any problem making a const
   1.556 +        is_const<T>
   1.557 +    >::type typex;
   1.558 +    BOOST_STATIC_CONSTANT(bool, value = typex::value);
   1.559 +};
   1.560 +
   1.561 +template<class Archive, class T>
   1.562 +inline void save(Archive & ar, T &t){
   1.563 +    // if your program traps here, it indicates taht your doing one of the following:
   1.564 +    // a) serializing an object of a type marked "track_never" through a pointer.
   1.565 +    // b) saving an non-const object of a type not markd "track_never)
   1.566 +    // Either of these conditions may be an indicator of an error usage of the
   1.567 +    // serialization library and should be double checked.  See documentation on
   1.568 +    // object tracking.
   1.569 +    BOOST_STATIC_ASSERT(check_tracking<T>::value);
   1.570 +        save(ar, const_cast<const T &>(t));
   1.571 +}
   1.572 +#endif
   1.573 +
   1.574 +} // namespace archive
   1.575 +} // namespace boost
   1.576 +
   1.577 +#endif // BOOST_ARCHIVE_OSERIALIZER_HPP