Boost logo

Boost-Commit :

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


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk