$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r51674 - trunk/boost/serialization
From: ramey_at_[hidden]
Date: 2009-03-09 19:38:39
Author: ramey
Date: 2009-03-09 19:38:38 EDT (Mon, 09 Mar 2009)
New Revision: 51674
URL: http://svn.boost.org/trac/boost/changeset/51674
Log:
checked in new type trait - is_virtual_base_of.hpp
changes to speed up void cast
Added:
   trunk/boost/serialization/is_virtual_base_of.hpp   (contents, props changed)
Text files modified: 
   trunk/boost/serialization/void_cast.hpp |   122 +++++++++++++++++++++++++++++++-------- 
   1 files changed, 95 insertions(+), 27 deletions(-)
Added: trunk/boost/serialization/is_virtual_base_of.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/serialization/is_virtual_base_of.hpp	2009-03-09 19:38:38 EDT (Mon, 09 Mar 2009)
@@ -0,0 +1,62 @@
+//  (C) Copyright Daniel Frey and Robert Ramey 2009.
+//  Use, modification and distribution are 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/libs/type_traits for most recent version including documentation.
+ 
+#ifndef BOOST_TT_IS_VIRTUAL_BASE_OF_HPP_INCLUDED
+#define BOOST_TT_IS_VIRTUAL_BASE_OF_HPP_INCLUDED
+
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/detail/ice_not.hpp>
+#include <boost/type_traits/detail/ice_and.hpp>
+
+// should be the last #include
+#include <boost/type_traits/detail/bool_trait_def.hpp>
+
+namespace boost {
+namespace detail {
+
+
+#ifdef BOOST_MSVC
+#pragma warning( push )
+#pragma warning( disable : 4584 )
+#endif
+
+template<typename Base, typename Derived>
+struct is_virtual_base_of_impl
+{
+    struct X : Derived, virtual Base {};
+    BOOST_STATIC_CONSTANT(bool, value = sizeof(X)==sizeof(Derived));
+};
+
+#ifdef BOOST_MSVC
+#pragma warning( pop )
+#endif
+
+} // namespace detail
+
+BOOST_TT_AUX_BOOL_TRAIT_DEF2(
+      is_virtual_base_of
+    , Base
+    , Derived
+    , (::boost::type_traits::ice_and<      
+         (::boost::detail::is_virtual_base_of_impl<Base,Derived>::value),
+         (::boost::type_traits::ice_not<
+            (::boost::is_same<Base,Derived>::value)
+         >::value)
+    >::value)
+)
+
+#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC2_2(typename Base,typename Derived,is_virtual_base_of,Base&,Derived,false)
+BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC2_2(typename Base,typename Derived,is_virtual_base_of,Base,Derived&,false)
+BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC2_2(typename Base,typename Derived,is_virtual_base_of,Base&,Derived&,false)
+#endif
+
+} // namespace boost
+
+#include <boost/type_traits/detail/bool_trait_undef.hpp>
+
+#endif
Modified: trunk/boost/serialization/void_cast.hpp
==============================================================================
--- trunk/boost/serialization/void_cast.hpp	(original)
+++ trunk/boost/serialization/void_cast.hpp	2009-03-09 19:38:38 EDT (Mon, 09 Mar 2009)
@@ -17,12 +17,14 @@
 
 //  See http://www.boost.org for updates, documentation, and revision history.
 
+#include <cstddef> // for ptrdiff_t
+#include <boost/serialization/config.hpp>
 #include <boost/serialization/smart_cast.hpp>
 #include <boost/serialization/singleton.hpp>
 #include <boost/serialization/force_include.hpp>
 #include <boost/serialization/type_info_implementation.hpp>
-#include <boost/serialization/config.hpp>
-#include <boost/serialization/force_include.hpp>
+#include <boost/serialization/is_virtual_base_of.hpp>
+
 #include <boost/config/abi_prefix.hpp> // must be the last header
 
 #ifdef BOOST_MSVC
@@ -84,7 +86,6 @@
 
 class BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY()) void_caster
 {
-    friend struct void_caster_compare ;
     friend 
     BOOST_SERIALIZATION_DECL(void const *)
     boost::serialization::void_upcast(
@@ -99,27 +100,43 @@
         extended_type_info const & base,
         void const * const
     );
-    // Data members
-    const extended_type_info & m_derived;
-    const extended_type_info & m_base;
-    // each derived class must re-implement these;
-    virtual void const * upcast(void const * const t) const = 0;
-    virtual void const * downcast(void const * const t) const = 0;
     // cw 8.3 requires this!!
     void_caster& operator=(void_caster const &);
 protected:
-    void
-    static_register() const;
-    void
-    static_unregister() const;
+    void recursive_register(bool includes_virtual_base = false) const;
+    void recursive_unregister() const;
 public:
+    // Data members
+    const extended_type_info * m_derived;
+    const extended_type_info * m_base;
+    const std::ptrdiff_t m_difference;
+    virtual bool is_shortcut() const {
+        return false;
+    }
+    // note that void_casters are keyed on value of
+    // addresses to member extended type info records
+    bool operator<(const void_caster & lhs) const {
+        if(m_derived < lhs.m_derived)
+            return true;
+        if(m_derived == lhs.m_derived)
+            if(m_base < lhs.m_base)
+                return true;
+        return false;
+    }
+    // each derived class must re-implement these;
+    virtual void const * upcast(void const * const t) const = 0;
+    virtual void const * downcast(void const * const t) const = 0;
     // Constructor
     void_caster(
-        extended_type_info const & derived,
-        extended_type_info const & base
-    );
-    virtual ~void_caster(){};
-    bool operator==(const void_caster & rhs) const;
+        extended_type_info const * derived,
+        extended_type_info const * base,
+        std::ptrdiff_t difference = 0
+    ) :
+        m_derived(derived),
+        m_base(base),
+        m_difference(difference)
+    {}
+    virtual ~void_caster(){}
 };
 
 template <class Derived, class Base>
@@ -141,23 +158,66 @@
         return b;
     }
 public:
-    BOOST_DLLEXPORT void_caster_primitive() BOOST_USED;
+    void_caster_primitive();
     ~void_caster_primitive();
 };
 
 template <class Derived, class Base>
-BOOST_DLLEXPORT void_caster_primitive<Derived, Base>::void_caster_primitive() :
+void_caster_primitive<Derived, Base>::void_caster_primitive() :
     void_caster( 
-        type_info_implementation<Derived>::type::get_const_instance(), 
-        type_info_implementation<Base>::type::get_const_instance()
+        & type_info_implementation<Derived>::type::get_const_instance(), 
+        & type_info_implementation<Base>::type::get_const_instance(),
+        reinterpret_cast<int>(
+            static_cast<Derived *>(
+                reinterpret_cast<Base *>(1)
+            )
+        ) - 1
     )
 {
-    static_register();
+    recursive_register();
 }
 
 template <class Derived, class Base>
 void_caster_primitive<Derived, Base>::~void_caster_primitive(){
-    static_unregister();
+    recursive_unregister();
+}
+
+template <class Derived, class Base>
+class void_caster_virtual_base : 
+    public void_caster
+{
+public:
+    virtual void const * downcast(void const * const t) const {
+        const Derived * d = 
+            dynamic_cast<const Derived *>(
+                static_cast<const Base *>(t)
+            );
+        return d;
+    }
+    virtual void const * upcast(void const * const t) const {
+        const Base * b = 
+            dynamic_cast<const Base *>(
+                static_cast<const Derived *>(t)
+            );
+        return b;
+    }
+    void_caster_virtual_base();
+    ~void_caster_virtual_base();
+};
+
+template <class Derived, class Base>
+void_caster_virtual_base<Derived,Base>::void_caster_virtual_base() :
+    void_caster( 
+        & type_info_implementation<Derived>::type::get_const_instance(), 
+        & type_info_implementation<Base>::type::get_const_instance()
+    )
+{
+    recursive_register(true);
+}
+
+template <class Derived, class Base>
+void_caster_virtual_base<Derived,Base>::~void_caster_virtual_base(){
+    recursive_unregister();
 }
 
 } // void_cast_detail 
@@ -179,9 +239,17 @@
     Derived const * /* dnull = NULL */, 
     Base const * /* bnull = NULL */
 ){
-    return singleton<void_cast_detail::void_caster_primitive<
-        Derived, Base
-    > >::get_const_instance();
+    typedef
+        BOOST_DEDUCED_TYPENAME mpl::eval_if<boost::is_virtual_base_of<Base,Derived>,
+            mpl::identity<
+                void_cast_detail::void_caster_virtual_base<Derived, Base>
+            >
+        ,// else
+            mpl::identity<
+                void_cast_detail::void_caster_primitive<Derived, Base>
+            >
+        >::type typex;
+    return singleton<typex>::get_const_instance();
 }
 
 } // namespace serialization