Boost logo

Boost :

From: Gregory Colvin (gregory.colvin_at_[hidden])
Date: 2003-08-28 22:47:55


On Thursday, Aug 28, 2003, at 19:40 America/Denver, E. Gladyshev wrote:
> --- Gregory Colvin <gregory.colvin_at_[hidden]> wrote:
>>
>> shared_ptr doesn't allocate the data, it only deletes it, which is
>> the job of the
>> current deleter parameter. And the counter type is by design not
>> part of the
>> shared_ptr type, so it doesn't belong as parameter to the shared_ptr
>> template.
>> See:
>>
>> http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/boost/boost/boost/
>> shared_ptr.hpp
>>
>> So you what you might want is to add something more like this to
>> shared_ptr:
>>
>> template<typename Data, typename Deleter, template<class Counter>
>> class Allocator>
>> shared_ptr(
>> Data*,
>> Deleter,
>> const Allocator<boost::detail::sp_counted_base_impl<Data*,
>> Deleter> >& );
>>
>> The idea being that you can use this constructor to get complete
>> control over how
>> a particular shared_ptr manages memory.
>
> In this solution, there are some issues with who
> controls the instances of the allocator that allocates
> Data and instances that delete the Data.

Which issues concern you?

> But I guess it is not big deal as soon as people understand it.
> If are to use template template parameters,

Yes, the template template parameter is a pain. Probably better to
take an arbitrary allocator object and rebind it:

    template<class Y, class D, class A>
    shared_ptr(T* p, D d, const A& a)
    : px(p), pn(p, d, A::rebind<<detail::sp_counted_base_impl<Data*,D>
>(a))
    {
         detail::sp_enable_shared_from_this(p, p, pn);
    }

> it would be nice to be able to define one allocator
> type for both counter and data.
>
> template<typename Data, template<class>
> class Allocator>
> shared_ptr(
> Data*,
> Allocator<Data>,
> const Allocator<boost::detail::sp_counted_base_impl<Data*,
> Deleter> >& );

This constructor would conflict with the constructors that take a
deleter, which must be a function pointer or function object, and
which might not use an allocator.

But for the purpose of creating shared objects using an allocator
you could instead use a factory function something like:

    template<class Allocator,typename Data>
    shared_ptr<T>
    allocate_shared_data(const Data& data, Allocator allocator)
    {
       struct deleter {
          Allocator a;
          deleter(const Allocator& a) : a(a) {}
          void operator()(Data* p) {
             a.deallocate(p,1);
             a.destroy(p);
          }
       };
       Data* p = allocator.allocate(1);
       allocator.construct(p,data);
       return shared_ptr<Data>(p,deleter<Data>(allocator),allocator);
    }


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk