#ifndef BOOST_ARCHIVE_SHARED_PTR_HELPER_HPP
#define BOOST_ARCHIVE_SHARED_PTR_HELPER_HPP

// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// shared_ptr_helper.hpp: serialization for boost shared pointern

// (C) Copyright 2004-2009 Robert Ramey, Martin Ecker and Takatoshi Kondo
// 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 <set>
#include <list>
#include <utility>
#include <cstddef> // NULL

#include <boost/config.hpp>
#include <boost/shared_ptr.hpp>

#include <boost/type_traits/is_polymorphic.hpp>
#include <boost/serialization/type_info_implementation.hpp>
#include <boost/serialization/shared_ptr_132.hpp>
#include <boost/serialization/throw_exception.hpp>

#include <boost/archive/archive_exception.hpp>
#include <boost/archive/detail/decl.hpp>

#include <boost/archive/detail/abi_prefix.hpp> // must be the last headern

namespace boost_132 {
    template<class T> class shared_ptr;
}
namespace boost {
    template<class T> class shared_ptr;
    namespace serialization {
        class extended_type_info;
        template<class Archive, class T>
        inline void load(
            Archive & ar,
            boost::shared_ptr< T > &t,
            const unsigned int file_version
        );
    }
namespace archive{
namespace detail {

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// a common class for holding various types of shared pointers

class shared_ptr_helper {
    struct collection_type_compare {
        bool operator()(
            const shared_ptr<const void> &lhs,
            const shared_ptr<const void> &rhs
        )const{
            return lhs.get() < rhs.get();
        }
    };
    typedef std::set<
        boost::shared_ptr<const void>,
        collection_type_compare
    > collection_type;
    typedef collection_type::const_iterator iterator_type;
    // list of shared_pointers create accessable by raw pointer. This
    // is used to "match up" shared pointers loaded at different
    // points in the archive. Note, we delay construction until
    // it is actually used since this is by default included as
    // a "mix-in" even if shared_ptr isn't used.
    collection_type * m_pointers;

    struct null_deleter {
        void operator()(void const *) const {}
    };

    struct void_deleter {
        const boost::serialization::extended_type_info * m_eti;
        void_deleter(const boost::serialization::extended_type_info *eti) :
            m_eti(eti)
        {}
        void operator()(void *vp) const {
            m_eti->destroy(vp);
        }
    };

#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
public:
#else
    template<class Archive, class T>
    friend inline void boost::serialization::load(
        Archive & ar,
        boost::shared_ptr< T > &t,
        const unsigned int file_version
    );
#endif

//  #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP
    // list of loaded pointers.  This is used to be sure that the pointers
    // stay around long enough to be "matched" with other pointers loaded
    // by the same archive.  These are created with a "null_deleter" so that
    // when this list is destroyed - the underlaying raw pointers are not
    // destroyed.  This has to be done because the pointers are also held by
    // new system which is disjoint from this set.  This is implemented
    // by a change in load_construct_data below.  It makes this file suitable
    // only for loading pointers into a 1.33 or later boost system.
    std::list<boost_132::shared_ptr<const void> > * m_pointers_132;
//  #endif

    // returns pointer to object and an indicator whether this is a
    // new entry (true) or a previous one (false)
    BOOST_ARCHIVE_DECL(shared_ptr<void>) 
    get_od(
        const void * od,
        const boost::serialization::extended_type_info * true_type, 
        const boost::serialization::extended_type_info * this_type
    );

    BOOST_ARCHIVE_DECL(void)
    append(const boost::shared_ptr<const void> &);

    template<class T>
    struct non_polymorphic {
        static const boost::serialization::extended_type_info * 
        get_object_identifier(T & t){
            return & boost::serialization::singleton<
                BOOST_DEDUCED_TYPENAME 
                boost::serialization::type_info_implementation< T >::type
            >::get_const_instance();
        }
    };
    template<class T>
    struct polymorphic {
        static const boost::serialization::extended_type_info * 
        get_object_identifier(T & t){
            return boost::serialization::singleton<
                BOOST_DEDUCED_TYPENAME 
                boost::serialization::type_info_implementation< T >::type
            >::get_const_instance().get_derived_extended_type_info(t);
        }
    };
public:
    template<class T>
    void reset(shared_ptr< T > & s, T * t){
        if(NULL == t){
            s.reset();
            return;
        }
        const boost::serialization::extended_type_info * this_type
            = & boost::serialization::type_info_implementation< T >::type
                    ::get_const_instance();

        // get pointer to the most derived object.  This is effectively
        // the object identifern
        typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
            is_polymorphic< T >,
            mpl::identity<polymorphic< T > >,
            mpl::identity<non_polymorphic< T > >
        >::type type;

        const boost::serialization::extended_type_info * true_type
            = type::get_object_identifier(*t);

        // note:if this exception is thrown, be sure that derived pointern
        // is either registered or exported.
        if(NULL == true_type)
            boost::serialization::throw_exception(
                archive_exception(
                    archive_exception::unregistered_class,
                    this_type->get_debug_info()
                )
            );
        shared_ptr<void> r =
            get_od(
                static_cast<const void *>(t), 
                true_type,
                this_type
            );
        if(!r){
            s.reset(t);
            const void * od = void_downcast(
                *true_type,
                *this_type,
                static_cast<const void *>(t)
            );
            shared_ptr<const void> sp(s, od);
            append(sp);
        }
        else{
            s = shared_ptr< T >(
                r,
                static_cast<T *>(r.get())
            );
        }
    }

//  #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP
    BOOST_ARCHIVE_DECL(void)
    append(const boost_132::shared_ptr<const void> & t);
//  #endif
public:
    BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
    shared_ptr_helper();
    BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
    ~shared_ptr_helper();
};

} // namespace detail
} // namespace archive
} // namespace boost

#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas

#endif // BOOST_ARCHIVE_SHARED_PTR_HELPER_HPP
