[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