diff -r 000000000000 -r bde4ae8d615e os/ossrv/ossrv_pub/boost_apis/boost/archive/detail/iserializer.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/ossrv/ossrv_pub/boost_apis/boost/archive/detail/iserializer.hpp Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,608 @@ +#ifndef BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP +#define BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#pragma inline_depth(511) +#pragma inline_recursion(on) +#endif + +#if defined(__MWERKS__) +#pragma inline_depth(511) +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// iserializer.hpp: interface for serialization system. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // for placement new +#include // for auto_ptr +#include // size_t + +#include +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + #ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO + #include + #endif +// the following is need only for dynamic cast of polymorphic pointers +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + +namespace serialization { + class extended_type_info; +} // namespace serialization + +namespace archive { + +// an accessor to permit friend access to archives. Needed because +// some compilers don't handle friend templates completely +class load_access { +public: + template + static void load_primitive(Archive &ar, T &t){ + ar.load(t); + } +}; + +namespace detail { + +template +class iserializer : public basic_iserializer +{ +private: + virtual void destroy(/*const*/ void *address) const { + boost::serialization::access::destroy(static_cast(address)); + } + // private constructor to inhibit any existence other than the + // static one + explicit iserializer() : + basic_iserializer( + * boost::serialization::type_info_implementation::type::get_instance() + ) + {} +public: + virtual BOOST_DLLEXPORT void load_object_data( + basic_iarchive & ar, + void *x, + const unsigned int file_version + ) const BOOST_USED ; + virtual bool class_info() const { + return boost::serialization::implementation_level::value + >= boost::serialization::object_class_info; + } + virtual bool tracking(const unsigned int flags) const { +// if(0 != (flags & no_tracking)) +// return false; + return boost::serialization::tracking_level::value + == boost::serialization::track_always + || boost::serialization::tracking_level::value + == boost::serialization::track_selectivly + && serialized_as_pointer(); + } + virtual unsigned int version() const { + return ::boost::serialization::version::value; + } + virtual bool is_polymorphic() const { + typedef BOOST_DEDUCED_TYPENAME + boost::serialization::type_info_implementation< + T + >::type::is_polymorphic::type typex; + return typex::value; + } + static iserializer & instantiate(){ + static iserializer instance; + return instance; + } + virtual ~iserializer(){}; +}; + +template +BOOST_DLLEXPORT void iserializer::load_object_data( + basic_iarchive & ar, + void *x, + const unsigned int file_version +) const { + // make sure call is routed through the higest interface that might + // be specialized by the user. + boost::serialization::serialize_adl( + boost::smart_cast_reference(ar), + * static_cast(x), + file_version + ); +} + +// instantiation of this template creates a static object. Note inversion of +// normal argument order to workaround bizarre error in MSVC 6.0 which only +// manifests iftself during compiler time. +template +class pointer_iserializer : public archive_pointer_iserializer +{ +private: + virtual const basic_iserializer & get_basic_serializer() const { + return iserializer::instantiate(); + } + virtual BOOST_DLLEXPORT void load_object_ptr( + basic_iarchive & ar, + void * & x, + const unsigned int file_version + ) const BOOST_USED; +#if defined(__GNUC__) || ( defined(BOOST_MSVC) && (_MSC_VER <= 1300) ) +public: +#endif + // private constructor to inhibit any existence other than the + // static one. Note GCC doesn't permit constructor to be private + explicit BOOST_DLLEXPORT pointer_iserializer() BOOST_USED; + static const pointer_iserializer instance; +public: + // at least one compiler (CW) seems to require that serialize_adl + // be explicitly instantiated. Still under investigation. + #if ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) + void (* const m)(Archive &, T &, const unsigned); + boost::serialization::extended_type_info * (* e)(); + #endif + static BOOST_DLLEXPORT const pointer_iserializer & instantiate() BOOST_USED; + virtual ~pointer_iserializer(){}; +}; + +template +BOOST_DLLEXPORT const pointer_iserializer & +pointer_iserializer::instantiate() { + return instance; +} + +// note: instances of this template to be constructed before the main +// is called in order for things to be initialized properly. For this +// reason, hiding the instance in a static function as was done above +// won't work here so we created a free instance here. +template +const pointer_iserializer pointer_iserializer::instance; + +// note trick to be sure that operator new is using class specific +// version if such exists. Due to Peter Dimov. +// note: the following fails if T has no default constructor. +// otherwise it would have been ideal +//struct heap_allocator : public T +//{ +// T * invoke(){ +// return ::new(sizeof(T)); +// } +//} + +// note: this should really be a member of the load_ptr function +// below but some compilers still complain about this. +template +struct heap_allocator +{ + #if 0 + // note: this fails on msvc 7.0 and gcc 3.2 + template struct test; + typedef char* yes; + typedef int* no; + template + yes has_op_new(U*, test* = 0); + no has_op_new(...); + + template + T * new_operator(U); + + T * new_operator(yes){ + return (T::operator new)(sizeof(T)); + } + T * new_operator(no){ + return static_cast(operator new(sizeof(T))); + } + static T * invoke(){ + return new_operator(has_op_new(static_cast(NULL))); + } + #else + // while this doesn't handle operator new overload for class T + static T * invoke(){ + return static_cast(operator new(sizeof(T))); + } + #endif +}; + +// due to Martin Ecker +template +class auto_ptr_with_deleter +{ +public: + explicit auto_ptr_with_deleter(T* p) : + m_p(p) + {} + ~auto_ptr_with_deleter(){ + if (m_p) + boost::serialization::access::destroy(m_p); + } + T* get() const { + return m_p; + } + + T* release() { + T* p = m_p; + m_p = NULL; + return p; + } +private: + T* m_p; +}; + +template +BOOST_DLLEXPORT void pointer_iserializer::load_object_ptr( + basic_iarchive & ar, + void * & x, + const unsigned int file_version +) const { + Archive & ar_impl = boost::smart_cast_reference(ar); + +// if(0 != (ar.get_flags() & no_object_creation)){ +// ar_impl >> boost::serialization::make_nvp(NULL, * static_cast(x)); +// return; +// } + + auto_ptr_with_deleter ap(heap_allocator::invoke()); + if(NULL == ap.get()) + boost::throw_exception(std::bad_alloc()) ; + + T * t = ap.get(); + x = t; + + // catch exception during load_construct_data so that we don't + // automatically delete the t which is most likely not fully + // constructed + BOOST_TRY { + // this addresses an obscure situtation that occurs when + // load_constructor de-serializes something through a pointer. + ar.next_object_pointer(t); + boost::serialization::load_construct_data_adl( + ar_impl, + t, + file_version + ); + } + BOOST_CATCH(...){ + BOOST_RETHROW; + } + BOOST_CATCH_END + + ar_impl >> boost::serialization::make_nvp(NULL, * t); + ap.release(); +} + +template +#if ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) +BOOST_DLLEXPORT pointer_iserializer::pointer_iserializer() : + archive_pointer_iserializer( + * boost::serialization::type_info_implementation::type::get_instance() + ), + m(boost::serialization::serialize_adl), + e(boost::serialization::type_info_implementation::type::get_instance) +#else +BOOST_DLLEXPORT pointer_iserializer::pointer_iserializer() : + archive_pointer_iserializer( + * boost::serialization::type_info_implementation::type::get_instance() + ) +#endif +{ + iserializer & bis = iserializer::instantiate(); + bis.set_bpis(this); +} + +template +struct load_non_pointer_type { + // note this bounces the call right back to the archive + // with no runtime overhead + struct load_primitive { + static void invoke(Archive & ar, T & t){ + load_access::load_primitive(ar, t); + } + }; + // note this bounces the call right back to the archive + // with no runtime overhead + struct load_only { + static void invoke(Archive & ar, T & t){ + // short cut to user's serializer + // make sure call is routed through the higest interface that might + // be specialized by the user. + boost::serialization::serialize_adl( + ar, t, boost::serialization::version::value + ); + } + }; + + // note this save class information including version + // and serialization level to the archive + struct load_standard { + static void invoke(Archive &ar, T &t){ + //BOOST_STATIC_ASSERT(! boost::is_const::value); + // borland - for some reason T is const here - even though + // its not called that way - so fix it her + typedef BOOST_DEDUCED_TYPENAME boost::remove_const::type typex; + void * x = & const_cast(t); + ar.load_object(x, iserializer::instantiate()); + } + }; + + struct load_conditional { + static void invoke(Archive &ar, T &t){ + //if(0 == (ar.get_flags() & no_tracking)) + load_standard::invoke(ar, t); + //else + // load_only::invoke(ar, t); + } + }; + + typedef BOOST_DEDUCED_TYPENAME mpl::eval_if< + // if its primitive + mpl::equal_to< + boost::serialization::implementation_level, + mpl::int_ + >, + mpl::identity, + // else + BOOST_DEDUCED_TYPENAME mpl::eval_if< + // class info / version + mpl::greater_equal< + boost::serialization::implementation_level, + mpl::int_ + >, + // do standard load + mpl::identity, + // else + BOOST_DEDUCED_TYPENAME mpl::eval_if< + // no tracking + mpl::equal_to< + boost::serialization::tracking_level, + mpl::int_ + >, + // do a fast load + mpl::identity, + // else + // do a fast load only tracking is turned off + mpl::identity + > > >::type typex; + + static void invoke(Archive & ar, T &t){ + BOOST_STATIC_ASSERT(( + mpl::greater_equal< + boost::serialization::implementation_level, + mpl::int_ + >::value + )); + typex::invoke(ar, t); + } +}; + +template +struct load_pointer_type { + template + struct abstract + { + static const basic_pointer_iserializer * register_type(Archive & /* ar */){ + #if ! defined(__BORLANDC__) + typedef BOOST_DEDUCED_TYPENAME + boost::serialization::type_info_implementation::type::is_polymorphic typex; + // it has? to be polymorphic + BOOST_STATIC_ASSERT(typex::value); + #endif + return static_cast(NULL); + } + }; + + template + struct non_abstract + { + static const basic_pointer_iserializer * register_type(Archive & ar){ + return ar.register_type(static_cast(NULL)); + } + }; + + template + static const basic_pointer_iserializer * register_type(Archive &ar, T & /*t*/){ + // there should never be any need to load an abstract polymorphic + // class pointer. Inhibiting code generation for this + // permits abstract base classes to be used - note: exception + // virtual serialize functions used for plug-ins + typedef BOOST_DEDUCED_TYPENAME + mpl::eval_if< + serialization::is_abstract, + mpl::identity >, + mpl::identity > + >::type typex; + return typex::register_type(ar); + } + + template + static T * pointer_tweak( + const boost::serialization::extended_type_info & eti, + void * t, + T & + ) { + // tweak the pointer back to the base class + return static_cast( + boost::serialization::void_upcast( + eti, + * boost::serialization::type_info_implementation::type::get_instance(), + t + ) + ); + } + + static void invoke(Archive & ar, Tptr & t){ + const basic_pointer_iserializer * bpis_ptr = register_type(ar, *t); + const basic_pointer_iserializer * newbpis_ptr = ar.load_pointer( + * reinterpret_cast(&t), + bpis_ptr, + archive_pointer_iserializer::find + ); + // if the pointer isn't that of the base class + if(newbpis_ptr != bpis_ptr){ + t = pointer_tweak(newbpis_ptr->get_eti(), t, *t); + } + } +}; + +template +struct load_enum_type { + static void invoke(Archive &ar, T &t){ + // convert integers to correct enum to load + int i; + ar >> boost::serialization::make_nvp(NULL, i); + t = static_cast(i); + } +}; + +template +struct load_array_type { + static void invoke(Archive &ar, T &t){ + // convert integers to correct enum to load + int current_count = sizeof(t) / ( + static_cast(static_cast(&t[1])) + - static_cast(static_cast(&t[0])) + ); + int count; + ar >> BOOST_SERIALIZATION_NVP(count); + if(count > current_count) + boost::throw_exception(archive::archive_exception( + boost::archive::archive_exception::array_size_too_short + )); + int i; + for(i = 0; i < count; ++i) + ar >> boost::serialization::make_nvp("item", t[i]); + } +}; + +// note bogus arguments to workaround msvc 6 silent runtime failure +template +BOOST_DLLEXPORT +inline const basic_pointer_iserializer & +instantiate_pointer_iserializer( + Archive * /* ar = NULL */, + T * /* t = NULL */ +) BOOST_USED; + +template +BOOST_DLLEXPORT +inline const basic_pointer_iserializer & +instantiate_pointer_iserializer( + Archive * /* ar = NULL */, + T * /* t = NULL */ +){ + // note: reversal of order of arguments to work around msvc 6.0 bug + // that manifests itself while trying to link. + return pointer_iserializer::instantiate(); +} + +} // detail + +template +inline void load(Archive &ar, T &t){ + // if this assertion trips. It means we're trying to load a + // const object with a compiler that doesn't have correct + // funtion template ordering. On other compilers, this is + // handled below. + BOOST_STATIC_ASSERT(! boost::is_const::value); + typedef + BOOST_DEDUCED_TYPENAME mpl::eval_if, + mpl::identity > + ,//else + BOOST_DEDUCED_TYPENAME mpl::eval_if, + mpl::identity > + ,//else + BOOST_DEDUCED_TYPENAME mpl::eval_if, + mpl::identity > + ,//else + mpl::identity > + > + > + >::type typex; + typex::invoke(ar, t); +} + +// BORLAND +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x560)) +// borland has a couple fo problems +// a) if function is partiall specialized - see below +// const paramters are transformed to non-const ones +// b) implementation of base_object can't be made to work +// correctly which results in all base_object s being const. +// So, strip off the const for borland. This breaks the trap +// for loading const objects - but I see no alternative +template +inline void load(Archive &ar, const T & t){ + load(ar, const_cast(t)); +} +#endif + +// let wrappers through. (Someday implement is_wrapper) +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING +template +inline void load(Archive &ar, const serialization::nvp &t){ + boost::archive::load(ar, const_cast &>(t)); +} +template +inline void load(Archive &ar, const serialization::binary_object &t){ + boost::archive::load(ar, const_cast(t)); +} + +//template +//inline void load(Archive &ar, const serialization::binary_object &t){ +// load(ar, const_cast(t)); +//} +#endif + +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP