[prev in list] [next in list] [prev in thread] [next in thread] 

List:       boost
Subject:    Re: [boost] [Any] Reference counting
From:       Michael Howell <mhowell123 () gmail ! com>
Date:       2009-04-08 4:59:30
Message-ID: 200904072159.35062.mhowell123 () gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/signed)]

[Attachment #4 (multipart/mixed)]


On Sunday 05 April 2009 18:06:46 I wrote:
> Thorsten Ottosen <thorsten.ottosen@dezide.com> wrote:
> >If you want to improve the performance of any, the thing to do is to add
> > a small buffer optimization such that all buildin types (or equally
> > small UDT) are created on the stack.
>
> I'll look into that.
I've managed to make a patch to do it.

-- 
Please do not send HTML mail. Please, if you forward email, clean off the 
garbage. Thanks for making everyone's email experience more enjoyable. 

Michael Howell 
mhowell123@gmail.com

["patch.diff" (text/x-patch)]

--- /usr/include/boost/any.hpp	2009-02-26 05:16:09.000000000 -0700
+++ any.hpp	2009-04-07 21:53:43.630130210 -0700
@@ -12,38 +12,135 @@
 
 #include <algorithm>
 #include <typeinfo>
+#include <map>
 
 #include "boost/config.hpp"
-#include <boost/type_traits/remove_reference.hpp>
-#include <boost/type_traits/is_reference.hpp>
+#include <boost/type_traits/is_pod.hpp>
 #include <boost/throw_exception.hpp>
 #include <boost/static_assert.hpp>
+#include <boost/shared_ptr.hpp>
+#include <iostream>
 
 namespace boost
 {
+
+    namespace detail
+    {
+    namespace any
+    {
+
+        template<bool Big> struct fn_table_impl
+        {
+            template <typename T> struct t
+            {
+
+                static inline const void * clone(const void * in)
+                {
+                    return new T(*(static_cast<const T *>(in)));
+                }
+
+                static inline const void * clone(const T& in)
+                {
+                    return new T(in);
+                }
+
+                static inline T * get(const void * in)
+                {
+                    return const_cast<T *>(static_cast<const T *>(in));
+                }
+
+                static inline void release(const void * in)
+                {
+                    delete const_cast<T *>(static_cast<const T *>(in));
+                }
+
+            };
+
+        };
+
+        template <> struct fn_table_impl<true>
+        {
+            template <typename T> struct t {
+                static inline const void * clone(const void * in)
+                {
+                    return reinterpret_cast<void*>(T(reinterpret_cast<const \
T>(in))); +                }
+
+                static inline const void * clone(const T& in)
+                {
+                    return reinterpret_cast<void*>(T(in));
+                }
+
+                static inline T * get(const void * in)
+                {
+                    return const_cast<T *>(reinterpret_cast<const T *>(&in));
+                }
+
+                static inline void release(const void *) {}; // Will fall out of \
scope +            };
+        };
+
+        template <typename ValueType> struct fn_table {
+
+            typedef fn_table_impl<is_pod<ValueType>::value> type;
+
+            static inline const void * clone(const void * in)
+            {
+                return type::template t<ValueType>::clone(in);
+            }
+
+            static inline const void * clone(const ValueType& in)
+            {
+                return type::template t<ValueType>::clone(in);
+            }
+
+            static inline ValueType * get(const void * in)
+            {
+                return type::template t<ValueType>::get(in);
+            }
+
+            static inline void release(const void * in)
+            {
+                type::template t<ValueType>::release(in);
+            }
+
+            static inline const void * clone(const shared_ptr<const void>& in)
+            {
+                return type::template t<ValueType>::clone(in.get());
+            }
+
+            static inline ValueType * get(const shared_ptr<const void>& in)
+            {
+                return type::template t<ValueType>::get(in.get());
+            }
+
+        };
+
+    }
+    }
+
     class any
     {
     public: // structors
 
-        any()
-          : content(0)
+        any() : type_info(typeid(void))
         {
         }
 
         template<typename ValueType>
         any(const ValueType & value)
-          : content(new holder<ValueType>(value))
+            : content(detail::any::fn_table<ValueType>::clone(value), \
&(detail::any::fn_table<ValueType>::release)), +              \
type_info(typeid(ValueType))  {
         }
 
         any(const any & other)
-          : content(other.content ? other.content->clone() : 0)
+          : content(other.content), type_info(other.type_info)
         {
         }
 
         ~any()
         {
-            delete content;
         }
 
     public: // modifiers
@@ -76,60 +173,10 @@
 
         const std::type_info & type() const
         {
-            return content ? content->type() : typeid(void);
+            return type_info;
         }
 
 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
-    private: // types
-#else
-    public: // types (public so any_cast can be non-friend)
-#endif
-
-        class placeholder
-        {
-        public: // structors
-
-            virtual ~placeholder()
-            {
-            }
-
-        public: // queries
-
-            virtual const std::type_info & type() const = 0;
-
-            virtual placeholder * clone() const = 0;
-
-        };
-
-        template<typename ValueType>
-        class holder : public placeholder
-        {
-        public: // structors
-
-            holder(const ValueType & value)
-              : held(value)
-            {
-            }
-
-        public: // queries
-
-            virtual const std::type_info & type() const
-            {
-                return typeid(ValueType);
-            }
-
-            virtual placeholder * clone() const
-            {
-                return new holder(held);
-            }
-
-        public: // representation
-
-            ValueType held;
-
-        };
-
-#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
 
     private: // representation
 
@@ -137,6 +184,9 @@
         friend ValueType * any_cast(any *);
 
         template<typename ValueType>
+        friend const ValueType& any_cast(any &);
+
+        template<typename ValueType>
         friend ValueType * unsafe_any_cast(any *);
 
 #else
@@ -145,8 +195,8 @@
 
 #endif
 
-        placeholder * content;
-
+        shared_ptr<const void> content;
+        const std::type_info& type_info;
     };
 
     class bad_any_cast : public std::bad_cast
@@ -162,9 +212,10 @@
     template<typename ValueType>
     ValueType * any_cast(any * operand)
     {
-        return operand && operand->type() == typeid(ValueType)
-                    ? &static_cast<any::holder<ValueType> *>(operand->content)->held
-                    : 0;
+        if (operand->type() != typeid(ValueType)) return;
+        if (operand->content.use_count() != 1)
+            operand->content.reset(detail::any::fn_table<ValueType>::clone(operand->content));
 +        return detail::any::fn_table<ValueType>::get(operand->content);
     }
 
     template<typename ValueType>
@@ -173,42 +224,18 @@
         return any_cast<ValueType>(const_cast<any *>(operand));
     }
 
-    template<typename ValueType>
-    ValueType any_cast(const any & operand)
+    template <typename ValueType>
+    const ValueType& any_cast(any & operand)
     {
-        typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
-
-#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
-        // If 'nonref' is still reference type, it means the user has not
-        // specialized 'remove_reference'.
-
-        // Please use BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION macro
-        // to generate specialization of remove_reference for your class
-        // See type traits library documentation for details
-        BOOST_STATIC_ASSERT(!is_reference<nonref>::value);
-#endif
-
-        const nonref * result = any_cast<nonref>(&operand);
-        if(!result)
+        if (operand.type() != typeid(ValueType))
             boost::throw_exception(bad_any_cast());
-        return *result;
+        return *(detail::any::fn_table<ValueType>::get(operand.content));
     }
 
     template<typename ValueType>
-    ValueType any_cast(any & operand)
+    const ValueType& any_cast(const any & operand)
     {
-        typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
-
-#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
-        // The comment in the above version of 'any_cast' explains when this
-        // assert is fired and what to do.
-        BOOST_STATIC_ASSERT(!is_reference<nonref>::value);
-#endif
-
-        nonref * result = any_cast<nonref>(&operand);
-        if(!result)
-            boost::throw_exception(bad_any_cast());
-        return *result;
+        return any_cast<ValueType>(const_cast<any &>(operand));
     }
 
     // Note: The "unsafe" versions of any_cast are not part of the
@@ -219,7 +246,9 @@
     template<typename ValueType>
     inline ValueType * unsafe_any_cast(any * operand)
     {
-        return &static_cast<any::holder<ValueType> *>(operand->content)->held;
+        if (operand->content.use_count() != 1)
+            operand->content.reset(detail::any::fn_table<ValueType>::clone(operand->content));
 +        return detail::any::fn_table<ValueType>::get(operand->content);
     }
 
     template<typename ValueType>


["signature.asc" (application/pgp-signature)]

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic