diff DEPENDENCIES/generic/include/boost/archive/detail/oserializer.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DEPENDENCIES/generic/include/boost/archive/detail/oserializer.hpp	Tue Aug 05 11:11:38 2014 +0100
@@ -0,0 +1,531 @@
+#ifndef BOOST_ARCHIVE_OSERIALIZER_HPP
+#define BOOST_ARCHIVE_OSERIALIZER_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
+// oserializer.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 <boost/assert.hpp>
+#include <cstddef> // NULL
+
+#include <boost/config.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/detail/workaround.hpp>
+
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/equal_to.hpp>
+#include <boost/mpl/greater_equal.hpp>
+#include <boost/mpl/identity.hpp>
+
+#ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO   
+    #include <boost/serialization/extended_type_info_typeid.hpp>   
+#endif
+#include <boost/serialization/throw_exception.hpp>
+#include <boost/serialization/smart_cast.hpp>
+#include <boost/serialization/assume_abstract.hpp>
+#include <boost/serialization/static_warning.hpp>
+
+#include <boost/type_traits/is_pointer.hpp>
+#include <boost/type_traits/is_enum.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/is_polymorphic.hpp>
+#include <boost/type_traits/remove_extent.hpp>
+
+#include <boost/serialization/serialization.hpp>
+#include <boost/serialization/version.hpp>
+#include <boost/serialization/level.hpp>
+#include <boost/serialization/tracking.hpp>
+#include <boost/serialization/type_info_implementation.hpp>
+#include <boost/serialization/nvp.hpp>
+#include <boost/serialization/void_cast.hpp>
+#include <boost/serialization/array.hpp>
+#include <boost/serialization/collection_size_type.hpp>
+#include <boost/serialization/singleton.hpp>
+
+#include <boost/archive/archive_exception.hpp>
+#include <boost/archive/detail/basic_oarchive.hpp>
+#include <boost/archive/detail/basic_oserializer.hpp>
+#include <boost/archive/detail/basic_pointer_oserializer.hpp>
+#include <boost/archive/detail/archive_serializer_map.hpp>
+#include <boost/archive/detail/check.hpp>
+
+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 save_access {
+public:
+    template<class Archive>
+    static void end_preamble(Archive & ar){
+        ar.end_preamble();
+    }
+    template<class Archive, class T>
+    static void save_primitive(Archive & ar, const  T & t){
+        ar.end_preamble();
+        ar.save(t);
+    }
+};
+
+namespace detail {
+
+#ifdef BOOST_MSVC
+#  pragma warning(push)
+#  pragma warning(disable : 4511 4512)
+#endif
+
+template<class Archive, class T>
+class oserializer : public basic_oserializer
+{
+private:
+    // private constructor to inhibit any existence other than the 
+    // static one
+public:
+    explicit BOOST_DLLEXPORT oserializer() :
+        basic_oserializer(
+            boost::serialization::singleton<
+                BOOST_DEDUCED_TYPENAME 
+                boost::serialization::type_info_implementation< T >::type
+            >::get_const_instance()
+        )
+    {}
+    virtual BOOST_DLLEXPORT void save_object_data(
+        basic_oarchive & ar,    
+        const void *x
+    ) const BOOST_USED;
+    virtual bool class_info() const {
+        return boost::serialization::implementation_level< T >::value 
+            >= boost::serialization::object_class_info;
+    }
+    virtual bool tracking(const unsigned int /* flags */) const {
+        return boost::serialization::tracking_level< T >::value == boost::serialization::track_always
+            || (boost::serialization::tracking_level< T >::value == boost::serialization::track_selectively
+                && serialized_as_pointer());
+    }
+    virtual version_type version() const {
+        return version_type(::boost::serialization::version< T >::value);
+    }
+    virtual bool is_polymorphic() const {
+        return boost::is_polymorphic< T >::value;
+    }
+    virtual ~oserializer(){}
+};
+
+#ifdef BOOST_MSVC
+#  pragma warning(pop)
+#endif
+
+template<class Archive, class T>
+BOOST_DLLEXPORT void oserializer<Archive, T>::save_object_data(
+    basic_oarchive & ar,    
+    const void *x
+) const {
+    // make sure call is routed through the highest interface that might
+    // be specialized by the user.
+    BOOST_STATIC_ASSERT(boost::is_const< T >::value == false);
+    boost::serialization::serialize_adl(
+        boost::serialization::smart_cast_reference<Archive &>(ar),
+        * static_cast<T *>(const_cast<void *>(x)),
+        version()
+    );
+}
+
+#ifdef BOOST_MSVC
+#  pragma warning(push)
+#  pragma warning(disable : 4511 4512)
+#endif
+
+template<class Archive, class T>
+class pointer_oserializer :
+    public basic_pointer_oserializer
+{
+private:
+    const basic_oserializer & 
+    get_basic_serializer() const {
+        return boost::serialization::singleton<
+            oserializer<Archive, T>
+        >::get_const_instance();
+    }
+    virtual BOOST_DLLEXPORT void save_object_ptr(
+        basic_oarchive & ar,
+        const void * x
+    ) const BOOST_USED;
+public:
+    pointer_oserializer();
+    ~pointer_oserializer();
+};
+
+#ifdef BOOST_MSVC
+#  pragma warning(pop)
+#endif
+
+template<class Archive, class T>
+BOOST_DLLEXPORT void pointer_oserializer<Archive, T>::save_object_ptr(
+    basic_oarchive & ar,
+    const void * x
+) const {
+    BOOST_ASSERT(NULL != x);
+    // make sure call is routed through the highest interface that might
+    // be specialized by the user.
+    T * t = static_cast<T *>(const_cast<void *>(x));
+    const unsigned int file_version = boost::serialization::version< T >::value;
+    Archive & ar_impl 
+        = boost::serialization::smart_cast_reference<Archive &>(ar);
+    boost::serialization::save_construct_data_adl<Archive, T>(
+        ar_impl, 
+        t, 
+        file_version
+    );
+    ar_impl << boost::serialization::make_nvp(NULL, * t);
+}
+
+template<class Archive, class T>
+pointer_oserializer<Archive, T>::pointer_oserializer() :
+    basic_pointer_oserializer(
+        boost::serialization::singleton<
+            BOOST_DEDUCED_TYPENAME 
+            boost::serialization::type_info_implementation< T >::type
+        >::get_const_instance()
+    )
+{
+    // make sure appropriate member function is instantiated
+    boost::serialization::singleton<
+        oserializer<Archive, T> 
+    >::get_mutable_instance().set_bpos(this);
+    archive_serializer_map<Archive>::insert(this);
+}
+
+template<class Archive, class T>
+pointer_oserializer<Archive, T>::~pointer_oserializer(){
+    archive_serializer_map<Archive>::erase(this);
+}
+
+template<class Archive>
+struct save_non_pointer_type {
+    // note this bounces the call right back to the archive
+    // with no runtime overhead
+    struct save_primitive {
+        template<class T>
+        static void invoke(Archive & ar, const T & t){
+            save_access::save_primitive(ar, t);
+        }
+    };
+    // same as above but passes through serialization
+    struct save_only {
+        template<class T>
+        static void invoke(Archive & ar, const T & t){
+            // make sure call is routed through the highest interface that might
+            // be specialized by the user.
+            boost::serialization::serialize_adl(
+                ar, 
+                const_cast<T &>(t), 
+                ::boost::serialization::version< T >::value
+            );
+        }
+    };
+    // adds class information to the archive. This includes
+    // serialization level and class version
+    struct save_standard {
+        template<class T>
+        static void invoke(Archive &ar, const T & t){
+            ar.save_object(
+                & t, 
+                boost::serialization::singleton<
+                    oserializer<Archive, T>
+                >::get_const_instance()
+            );
+        }
+    };
+
+    // adds class information to the archive. This includes
+    // serialization level and class version
+    struct save_conditional {
+        template<class T>
+        static void invoke(Archive &ar, const T &t){
+            //if(0 == (ar.get_flags() & no_tracking))
+                save_standard::invoke(ar, t);
+            //else
+            //   save_only::invoke(ar, t);
+        }
+    };
+
+
+    template<class T>
+    static void invoke(Archive & ar, const T & t){
+        typedef 
+            BOOST_DEDUCED_TYPENAME mpl::eval_if<
+            // if its primitive
+                mpl::equal_to<
+                    boost::serialization::implementation_level< T >,
+                    mpl::int_<boost::serialization::primitive_type>
+                >,
+                mpl::identity<save_primitive>,
+            // else
+            BOOST_DEDUCED_TYPENAME mpl::eval_if<
+                // class info / version
+                mpl::greater_equal<
+                    boost::serialization::implementation_level< T >,
+                    mpl::int_<boost::serialization::object_class_info>
+                >,
+                // do standard save
+                mpl::identity<save_standard>,
+            // else
+            BOOST_DEDUCED_TYPENAME mpl::eval_if<
+                    // no tracking
+                mpl::equal_to<
+                    boost::serialization::tracking_level< T >,
+                    mpl::int_<boost::serialization::track_never>
+                >,
+                // do a fast save
+                mpl::identity<save_only>,
+            // else
+                // do a fast save only tracking is turned off
+                mpl::identity<save_conditional>
+            > > >::type typex; 
+        check_object_versioning< T >();
+        typex::invoke(ar, t);
+    }
+    template<class T>
+    static void invoke(Archive & ar, T & t){
+        check_object_level< T >();
+        check_object_tracking< T >();
+        invoke(ar, const_cast<const T &>(t));
+    }
+};
+
+template<class Archive>
+struct save_pointer_type {
+    struct abstract
+    {
+        template<class T>
+        static const basic_pointer_oserializer * register_type(Archive & /* ar */){
+            // it has? to be polymorphic
+            BOOST_STATIC_ASSERT(boost::is_polymorphic< T >::value);
+            return NULL;
+        }
+    };
+
+    struct non_abstract
+    {
+        template<class T>
+        static const basic_pointer_oserializer * register_type(Archive & ar){
+            return ar.register_type(static_cast<T *>(NULL));
+        }
+    };
+
+    template<class T>
+    static const basic_pointer_oserializer * register_type(Archive &ar, T & /*t*/){
+        // there should never be any need to save 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<
+                boost::serialization::is_abstract< T >,
+                mpl::identity<abstract>,
+                mpl::identity<non_abstract>       
+            >::type typex;
+        return typex::template register_type< T >(ar);
+    }
+
+    struct non_polymorphic
+    {
+        template<class T>
+        static void save(
+            Archive &ar, 
+            T & t
+        ){
+            const basic_pointer_oserializer & bpos = 
+                boost::serialization::singleton<
+                    pointer_oserializer<Archive, T>
+                >::get_const_instance();
+            // save the requested pointer type
+            ar.save_pointer(& t, & bpos);
+        }
+    };
+
+    struct polymorphic
+    {
+        template<class T>
+        static void save(
+            Archive &ar, 
+            T & t
+        ){
+            BOOST_DEDUCED_TYPENAME 
+            boost::serialization::type_info_implementation< T >::type const
+            & i = boost::serialization::singleton<
+                BOOST_DEDUCED_TYPENAME 
+                boost::serialization::type_info_implementation< T >::type
+            >::get_const_instance();
+
+            boost::serialization::extended_type_info const * const this_type = & i;
+
+            // retrieve the true type of the object pointed to
+            // if this assertion fails its an error in this library
+            BOOST_ASSERT(NULL != this_type);
+
+            const boost::serialization::extended_type_info * true_type =
+                i.get_derived_extended_type_info(t);
+
+            // note:if this exception is thrown, be sure that derived pointer
+            // is either registered or exported.
+            if(NULL == true_type){
+                boost::serialization::throw_exception(
+                    archive_exception(
+                        archive_exception::unregistered_class,
+                        "derived class not registered or exported"
+                    )
+                );
+            }
+
+            // if its not a pointer to a more derived type
+            const void *vp = static_cast<const void *>(&t);
+            if(*this_type == *true_type){
+                const basic_pointer_oserializer * bpos = register_type(ar, t);
+                ar.save_pointer(vp, bpos);
+                return;
+            }
+            // convert pointer to more derived type. if this is thrown
+            // it means that the base/derived relationship hasn't be registered
+            vp = serialization::void_downcast(
+                *true_type, 
+                *this_type, 
+                static_cast<const void *>(&t)
+            );
+            if(NULL == vp){
+                boost::serialization::throw_exception(
+                    archive_exception(
+                        archive_exception::unregistered_cast,
+                        true_type->get_debug_info(),
+                        this_type->get_debug_info()
+                    )
+                );
+            }
+
+            // since true_type is valid, and this only gets made if the 
+            // pointer oserializer object has been created, this should never
+            // fail
+            const basic_pointer_oserializer * bpos
+                = static_cast<const basic_pointer_oserializer *>(
+                    boost::serialization::singleton<
+                        archive_serializer_map<Archive>
+                    >::get_const_instance().find(*true_type)
+                );
+            BOOST_ASSERT(NULL != bpos);
+            if(NULL == bpos)
+                boost::serialization::throw_exception(
+                    archive_exception(
+                        archive_exception::unregistered_class,
+                        "derived class not registered or exported"
+                    )
+                );
+            ar.save_pointer(vp, bpos);
+        }
+    };
+
+    template<class T>
+    static void save(
+        Archive & ar, 
+        const T & t
+    ){
+        check_pointer_level< T >();
+        check_pointer_tracking< T >();
+        typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
+            is_polymorphic< T >,
+            mpl::identity<polymorphic>,
+            mpl::identity<non_polymorphic>
+        >::type type;
+        type::save(ar, const_cast<T &>(t));
+    }
+
+    template<class TPtr>
+    static void invoke(Archive &ar, const TPtr t){
+        register_type(ar, * t);
+        if(NULL == t){
+            basic_oarchive & boa 
+                = boost::serialization::smart_cast_reference<basic_oarchive &>(ar);
+            boa.save_null_pointer();
+            save_access::end_preamble(ar);
+            return;
+        }
+        save(ar, * t);
+    }
+};
+
+template<class Archive>
+struct save_enum_type
+{
+    template<class T>
+    static void invoke(Archive &ar, const T &t){
+        // convert enum to integers on save
+        const int i = static_cast<int>(t);
+        ar << boost::serialization::make_nvp(NULL, i);
+    }
+};
+
+template<class Archive>
+struct save_array_type
+{
+    template<class T>
+    static void invoke(Archive &ar, const T &t){
+        typedef BOOST_DEDUCED_TYPENAME boost::remove_extent< T >::type value_type;
+        
+        save_access::end_preamble(ar);
+        // consider alignment
+        std::size_t c = sizeof(t) / (
+            static_cast<const char *>(static_cast<const void *>(&t[1])) 
+            - static_cast<const char *>(static_cast<const void *>(&t[0]))
+        );
+        boost::serialization::collection_size_type count(c);
+        ar << BOOST_SERIALIZATION_NVP(count);
+        ar << serialization::make_array(static_cast<value_type const*>(&t[0]),count);
+    }
+};
+
+} // detail
+
+template<class Archive, class T>
+inline void save(Archive & ar, /*const*/ T &t){
+    typedef 
+        BOOST_DEDUCED_TYPENAME mpl::eval_if<is_pointer< T >,
+            mpl::identity<detail::save_pointer_type<Archive> >,
+        //else
+        BOOST_DEDUCED_TYPENAME mpl::eval_if<is_enum< T >,
+            mpl::identity<detail::save_enum_type<Archive> >,
+        //else
+        BOOST_DEDUCED_TYPENAME mpl::eval_if<is_array< T >,
+            mpl::identity<detail::save_array_type<Archive> >,
+        //else
+            mpl::identity<detail::save_non_pointer_type<Archive> >
+        >
+        >
+        >::type typex;
+    typex::invoke(ar, t);
+}
+
+} // namespace archive
+} // namespace boost
+
+#endif // BOOST_ARCHIVE_OSERIALIZER_HPP