Re: [boost] shared_ptr extension with counter in object header

2003-02-23 Thread Greg Colvin
At 03:34 AM 2/23/2003, Thomas Witt wrote:

Greg,

I can not figure out how you make sure to satisfy the alignment constraints of 
T and counted_base_header_impl. Any hint would be appreciated.

I just used two char arrays, thinking there was a dispensation
somewhere in the standard to allow for placement new into char
arrays:

   templatetypename T struct object_with_counted_header {
  char header[sizeof(counted_base_header_implT*,checked_deleterT )];
  char object[sizeof(T)];
   };

If I'm wrong, an alternative might be:

   templatetypename T struct object_with_counted_header {
  counted_base_header_implT*,checked_deleterT  header;
  T object;
   };

But then you can't use offsetof, and some fancier tricks will
be in order.

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


[boost] shared_ptr extension with counter in object header

2003-02-22 Thread Greg Colvin
The weather kept me at home today, so I had time to hack in
a new constructor for shared_ptr that keeps the count in a
header which is allocated along with the counted object.
Like intrusive_ptr, but intrusive in a different way.  If
anyone has time to apply the patches and see if it is as
fast as it should be I would most grateful.

The new public constructor goes inside shared_ptr in
shared_ptr.hpp:

templatetypename Y
explicit shared_ptr(Y * p,const detail::counted_header_tagY)
: px(p), pn(detail::new_counted_base_in_object_header(p)) // Y must be complete
{
}

To make it easier to get the tags right I added a few
helper functions, which made me wish again for type-safe
variadic functions.  They go in the boost namespace in
shared_ptr.hpp:

   templatetypename T
   inline shared_ptrT new_counted() {
  detail::counted_header_tagT counted;
  return shared_ptrT(new(counted) T(),counted);
   }
   templatetypename T, typename P1
   inline shared_ptrT new_counted(const P1 p1) {
  detail::counted_header_tagT counted;
  return shared_ptrT(new(counted) T(p1),counted);
   }
   templatetypename T, typename P1, typename P2
   inline shared_ptrT new_counted(const P1 p1,const P2 p2) {
  detail::counted_header_tagT counted;
  return shared_ptrT(new(counted) T(p1,p2),counted);
   }
   templatetypename T, typename P1, typename P2, typename P3
   inline shared_ptrT new_counted(const P1 p1,const P2 p2,const P3 p3) {
  detail::counted_header_tagT counted;
  return shared_ptrT(new(counted) T(p1,p2,p3),counted);
   }
   // ... repeat above with more args until bored


The guts of the change go near the end of shared_count.hpp:

   namespace boost {
   namespace detail {

   templateclass P, class D class counted_base_header_impl: public counted_base
   {
   private:

   P ptr; // copy constructor must not throw
   D del; // copy constructor must not throw

   counted_base_header_impl(counted_base_header_impl const );
   counted_base_header_impl  operator= (counted_base_header_impl const );

   public:

   // pre: initial_use_count = initial_weak_count, d(p) must not throw

   counted_base_header_impl(P p, D d, long initial_use_count, long 
initial_weak_count):
   counted_base(initial_use_count, initial_weak_count), ptr(p), del(d)
   {
   }

   virtual void destruct() // nothrow
   {
   }

   virtual void dispose() // nothrow
   {
   del(ptr);
   }
   };

   templatetypename T struct object_with_counted_header {
  char header[sizeof(counted_base_header_implT*,checked_deleterT )];
  char object[sizeof(T)];
   };

   templatetypename T inline void* get_counted_object_header(T* p) {
  return (char*)p - offsetof(object_with_counted_headerT,object);
   }

   templateclass T struct checked_counted_header_deleter
   {
   typedef void result_type;
   typedef T* argument_type;

   void operator()(T* p)
   {
   typedef char type_must_be_complete[sizeof(T)];
   ::operator delete(get_counted_object_header(p));
   }
   };

   templatetypename T
   inline counted_base* new_counted_base_in_object_header(T* p) {
  return new (get_counted_object_header(p))
 counted_base_header_implT*,checked_counted_header_deleterT 
 (p,checked_counted_header_deleterT(),1,1);
   }

   templatetypename T struct counted_header_tag {};

   } // namespace detail
   } // namespace boost

   template typename T
   inline void* operator new(size_t n,const boost::detail::counted_header_tagT) {
   assert(n == sizeof(T));
   return (char*)::operator 
new(sizeof(boost::detail::object_with_counted_headerT))
  + offsetof(boost::detail::object_with_counted_headerT,object);
   }


I haven't bothered with an array version yet, and have tested
only with GCC on Cygwin.

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