Squashed 'third_party/boostorg/serialization/' content from commit 738695b

Change-Id: I48528198ad1f62b90288d249eb2243d4db02fd5d
git-subtree-dir: third_party/boostorg/serialization
git-subtree-split: 738695b70733f9d592a570fb17a505d6a029b48a
diff --git a/src/void_cast.cpp b/src/void_cast.cpp
new file mode 100644
index 0000000..4051303
--- /dev/null
+++ b/src/void_cast.cpp
@@ -0,0 +1,379 @@
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// void_cast.cpp: implementation of run-time casting of void pointers
+
+// (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)
+// <gennadiy.rozental@tfn.com>
+
+//  See http://www.boost.org for updates, documentation, and revision history.
+
+#if (defined _MSC_VER) && (_MSC_VER == 1200)
+# pragma warning (disable : 4786) // too long name, harmless warning
+#endif
+
+// STL
+#include <set>
+#include <functional>
+#include <algorithm>
+#include <cstddef> // NULL
+#ifdef BOOST_SERIALIZATION_LOG
+#include <iostream>
+#endif
+
+// BOOST
+#include <boost/config.hpp>
+#include <boost/assert.hpp>
+
+#define BOOST_SERIALIZATION_SOURCE
+#include <boost/serialization/config.hpp>
+// it marks our code with proper attributes as being exported when
+// we're compiling it while marking it import when just the headers
+// is being included.
+#include <boost/serialization/singleton.hpp>
+#include <boost/serialization/extended_type_info.hpp>
+#include <boost/serialization/void_cast.hpp>
+
+namespace boost { 
+namespace serialization {
+namespace void_cast_detail {
+
+// note that void_casters are keyed on value of
+// member extended type info records - NOT their
+// addresses.  This is necessary in order for the
+// void cast operations to work across dll and exe
+// module boundries.
+bool void_caster::operator<(const void_caster & rhs) const {
+    // include short cut to save time and eliminate
+    // problems when when base class aren't virtual
+    if(m_derived != rhs.m_derived){
+        if(*m_derived < *rhs.m_derived)
+            return true;
+        if(*rhs.m_derived < *m_derived)
+            return false;
+    }
+    // m_derived == rhs.m_derived
+    if(m_base != rhs.m_base)
+        return *m_base < *rhs.m_base;
+    else
+        return false;
+}
+
+struct void_caster_compare {
+    bool operator()(const void_caster * lhs, const void_caster * rhs) const {
+        return *lhs < *rhs;
+    }
+};
+
+typedef std::set<const void_caster *, void_caster_compare> set_type;
+typedef boost::serialization::singleton<set_type> void_caster_registry;
+
+#ifdef BOOST_MSVC
+#  pragma warning(push)
+#  pragma warning(disable : 4511 4512)
+#endif
+
+// implementation of shortcut void caster
+class void_caster_shortcut : public void_caster
+{
+    bool m_includes_virtual_base;
+
+    void const * 
+    vbc_upcast(
+        void const * const t
+    ) const;
+    void const *
+    vbc_downcast(
+        void const * const t
+    ) const;
+    virtual void const *
+    upcast(void const * const t) const{
+        if(m_includes_virtual_base)
+            return vbc_upcast(t);
+        return static_cast<const char *> ( t ) - m_difference;
+    }
+    virtual void const *
+    downcast(void const * const t) const{
+        if(m_includes_virtual_base)
+            return vbc_downcast(t);
+        return static_cast<const char *> ( t ) + m_difference;
+    }
+    virtual bool is_shortcut() const {
+        return true;
+    }
+    virtual bool has_virtual_base() const {
+        return m_includes_virtual_base;
+    }
+public:
+    void_caster_shortcut(
+        extended_type_info const * derived,
+        extended_type_info const * base,
+        std::ptrdiff_t difference,
+        bool includes_virtual_base,
+        void_caster const * const parent
+    ) :
+        void_caster(derived, base, difference, parent),
+        m_includes_virtual_base(includes_virtual_base)
+    {
+        recursive_register(includes_virtual_base);
+    }
+    virtual ~void_caster_shortcut(){
+        recursive_unregister();
+    }
+};
+
+#ifdef BOOST_MSVC
+#  pragma warning(pop)
+#endif
+
+void const * 
+void_caster_shortcut::vbc_downcast(
+    void const * const t
+) const {
+    // try to find a chain that gives us what we want
+    const void_cast_detail::set_type & s
+        = void_cast_detail::void_caster_registry::get_const_instance();
+    void_cast_detail::set_type::const_iterator it;
+    for(it = s.begin(); it != s.end(); ++it){
+        // if the current candidate casts to the desired target type
+        if ((*it)->m_derived == m_derived){
+            // and if it's not us
+            if ((*it)->m_base != m_base){
+                // try to cast from the candidate base to our base
+                const void * t_new;
+                t_new = void_downcast(*(*it)->m_base, *m_base, t);
+                // if we were successful
+                if(NULL != t_new){
+                    // recast to our derived
+                    const void_caster * vc = *it;
+                    return vc->downcast(t_new);
+                }
+            }
+        }
+    }
+    return NULL;
+}
+
+void const * 
+void_caster_shortcut::vbc_upcast(
+    void const * const t
+) const {
+    // try to find a chain that gives us what we want
+    const void_cast_detail::set_type & s
+        = void_cast_detail::void_caster_registry::get_const_instance();
+    void_cast_detail::set_type::const_iterator it;
+    for(it = s.begin(); it != s.end(); ++it){
+        // if the current candidate casts from the desired base type
+        if((*it)->m_base == m_base){
+            // and if it's not us
+            if ((*it)->m_derived != m_derived){
+                // try to cast from the candidate derived to our our derived
+                const void * t_new;
+                t_new = void_upcast(*m_derived, *(*it)->m_derived, t);
+                if(NULL != t_new)
+                    return (*it)->upcast(t_new);
+            }
+        }
+    }
+    return NULL;
+}
+
+#ifdef BOOST_MSVC
+#  pragma warning(push)
+#  pragma warning(disable : 4511 4512)
+#endif
+
+// just used as a search key
+class void_caster_argument : public void_caster
+{
+    virtual void const *
+    upcast(void const * const /*t*/) const {
+        BOOST_ASSERT(false);
+        return NULL;
+    }
+    virtual void const *
+    downcast( void const * const /*t*/) const {
+        BOOST_ASSERT(false);
+        return NULL;
+    }
+    virtual bool has_virtual_base() const {
+        BOOST_ASSERT(false);
+        return false;
+    }
+public:
+    void_caster_argument(
+        extended_type_info const * derived,
+        extended_type_info const * base
+    ) :
+        void_caster(derived, base)
+    {}
+    virtual ~void_caster_argument(){};
+};
+
+#ifdef BOOST_MSVC
+#  pragma warning(pop)
+#endif
+
+// implementation of void caster base class
+BOOST_SERIALIZATION_DECL void
+void_caster::recursive_register(bool includes_virtual_base) const {
+    void_cast_detail::set_type & s
+        = void_cast_detail::void_caster_registry::get_mutable_instance();
+
+    #ifdef BOOST_SERIALIZATION_LOG
+    std::clog << "recursive_register\n";
+    std::clog << m_derived->get_debug_info();
+    std::clog << "<-";
+    std::clog << m_base->get_debug_info();
+    std::clog << "\n";
+    #endif
+
+    std::pair<void_cast_detail::set_type::const_iterator, bool> result;
+    // comment this out for now.  
+    result = s.insert(this);
+    //assert(result.second);
+
+    // generate all implied void_casts.
+    void_cast_detail::set_type::const_iterator it;
+    for(it = s.begin(); it != s.end(); ++it){
+        if(* m_derived == * (*it)->m_base){
+            const void_caster_argument vca(
+                (*it)->m_derived, 
+                m_base
+            );
+            void_cast_detail::set_type::const_iterator i;
+            i = s.find(& vca);
+            if(i == s.end()){
+                new void_caster_shortcut(
+                    (*it)->m_derived, 
+                    m_base,
+                    m_difference + (*it)->m_difference,
+                    (*it)->has_virtual_base() || includes_virtual_base,
+                    this
+                );
+            }
+        }
+        if(* (*it)->m_derived == * m_base){
+            const void_caster_argument vca(
+                m_derived, 
+                (*it)->m_base
+            );
+            void_cast_detail::set_type::const_iterator i;
+            i = s.find(& vca);
+            if(i == s.end()){
+                new void_caster_shortcut(
+                    m_derived, 
+                    (*it)->m_base, 
+                    m_difference + (*it)->m_difference,
+                    (*it)->has_virtual_base() || includes_virtual_base,
+                    this
+                );
+            }
+        }
+    }
+}
+
+BOOST_SERIALIZATION_DECL void
+void_caster::recursive_unregister() const {
+    BOOST_ASSERT(! void_caster_registry::is_destroyed());
+    if(void_caster_registry::is_destroyed())
+        return;
+
+    #ifdef BOOST_SERIALIZATION_LOG
+    std::clog << "recursive_unregister\n";
+    std::clog << m_derived->get_debug_info();
+    std::clog << "<-";
+    std::clog << m_base->get_debug_info();
+    std::clog << "\n";
+    #endif
+
+    void_cast_detail::set_type & s 
+        = void_caster_registry::get_mutable_instance();
+
+    // delete all shortcuts which use this primitive
+    void_cast_detail::set_type::iterator it;
+    for(it = s.begin(); it != s.end();){
+        const void_caster * vc = *it;
+        if(vc == this){
+            s.erase(it++);
+        }
+        else
+        if(vc->m_parent == this){
+            s.erase(it);
+            delete vc;
+            it = s.begin();
+        }
+        else
+            it++;
+    }
+}
+
+} // namespace void_cast_detail
+
+BOOST_SYMBOL_VISIBLE void const *
+void_upcast(
+    extended_type_info const & derived,
+    extended_type_info const & base,
+    void const * const t
+);
+
+// Given a void *, assume that it really points to an instance of one type
+// and alter it so that it would point to an instance of a related type.
+// Return the altered pointer. If there exists no sequence of casts that
+// can transform from_type to to_type, return a NULL.  
+BOOST_SERIALIZATION_DECL void const *
+void_upcast(
+    extended_type_info const & derived,
+    extended_type_info const & base,
+    void const * const t
+){
+    // same types - trivial case
+    if (derived == base)
+        return t;
+
+    // check to see if base/derived pair is found in the registry
+    const void_cast_detail::set_type & s
+        = void_cast_detail::void_caster_registry::get_const_instance();
+    const void_cast_detail::void_caster_argument ca(& derived, & base);
+
+    void_cast_detail::set_type::const_iterator it;
+    it = s.find(& ca);
+    if (s.end() != it)
+        return (*it)->upcast(t);
+
+    return NULL;
+}
+
+BOOST_SYMBOL_VISIBLE void const *
+void_downcast(
+    extended_type_info const & derived,
+    extended_type_info const & base,
+    void const * const t
+);
+
+BOOST_SERIALIZATION_DECL void const *
+void_downcast(
+    extended_type_info const & derived,
+    extended_type_info const & base,
+    void const * const t
+){
+    // same types - trivial case
+    if (derived == base)
+        return t;
+
+    // check to see if base/derived pair is found in the registry
+    const void_cast_detail::set_type & s
+        = void_cast_detail::void_caster_registry::get_const_instance();
+    const void_cast_detail::void_caster_argument ca(& derived, & base);
+
+    void_cast_detail::set_type::const_iterator it;
+    it = s.find(&ca);
+    if (s.end() != it)
+        return(*it)->downcast(t);
+
+    return NULL;
+}
+
+} // namespace serialization
+} // namespace boost