Boost logo

Boost :

From: Thorsten Ottosen (nesotto_at_[hidden])
Date: 2003-12-29 07:20:01


Thorsten Ottosen wrote:

>> Also, with
>> boost::shared_ptr I can supply an alternate deleter functor. I haven't
>> looked at your code very deeply yet, is there a similar capability built
>> in, or would you consider it doable or useful?
>
>Of course it is doable, I just don't see what purpose it has.

Well, for example, I just made a class embodying a bi-directional double
buffer for inter-thread communication, without using locks or mutexes. The
two buffers are allocated once and just re-used at runtime, so that there's
no time wasted in allocation and deallocation. It works by moving two
tokens representing the buffers, in a tight 6-cell array. When either the
producer or consumer acquires a token, it receives a shared-ptr to the
corresponding buffer. This allows the thread to pass the token among its
routines, without having to care about freeing the token. Once all
instances of the token go out of scope, the last one would free the
buffer's memory, but instead, it calls the routine I passed to it in the
constructor, resulting in a call of double_buffer's own function call
operator, which, instead of freeing the memory of the buffer, simply causes
the token to move along the array. I'm including the file,
double_buffer.hpp. I have not tested it yet, but you can see how I hand
out a shared_ptr, with a second argument in its constructor being 'this',
such that when all copies of the handle go out of scope, my function call
operator gets called, and I get the token moving along.

>> Would it make sense to have pointer container specializations for
>> auto_ptr<>, shared_ptr<> and weak_ptr<>, simply as a way of specifying
the
>> desired semantics?
>
>It makes sense if you can show what purpose it should serve.

Ever since I discovered the safety, versatility and power of shared_ptr,
I've never used auto_ptr again. Your pointer containers work as if they
were storing auto_ptr's. What I was suggesting was *not* that they store
shared_ptr's, but to have the ability to specify that they work *as if*
storing shared_ptr's.

>> I'm thinking, for instance,
>>
>> ptr_vector< auto_ptr<X> > would compile to same code, basically, as
>> ptr_vector<X>, except: it would take auto_ptr<> as input, and return
>> auto_ptr<> through functions that would otherwise return a pointer.
>
>there is not any functions that return a pointer. The way I have
implemented

I thought you mentioned ptr_begin()/ptr_end(). Anyways, I'm sure there's a
way of 'releasing' an object a pointer container owns; it just occured to
me that pointer iterators might as well return a smart pointer, or do so
upon having a release() method called on them.

>the stuff
>is by wrapping existing containers and you cannot put an auto_ptr into
>standard containers;
>you would have to use something special like NTL.

I understand that. I wasn't suggesting storing actual
auto_ptr/shared_ptr/weak_ptr, but to have similar functionality. shared_ptr
is infinitely more useful than auto_ptr, I find; even when you only want a
single owner, the fact that it can move across function calls, and that you
can specify any action on countdown to zero, not just deletion.

>> ptr_vector< shared_ptr<X> > would allow pointer containers to share
>> ownership, and would interface via shared_ptr<>'s; and...
>
>what interface did you have in mind.?

push_back( shared_ptr<T> t );
shared_ptr<T> ptr_begin();
shared_ptr<T> ptr_iterator(); //and so on, for the shared_ptr<T>
specialization

>> ptr_vector< weak_ptr<X> > might give us the advantage of simplified
>> algorithmic syntax, etceteras, but not take ownership.
>
>While the idea is nice, I need to be convinced. The current interface (and
>the whole desing idea) is build
>upon the idea of owning heap-allocated pointers and hiding them behind an
>indirected interface.

A use-count paradigm has infinitely more applications than merely
de-allocation. But even when de-allocation is intended, a custom allocator
might actually benefit from a call back on de-allocation, such as to delay
or buffer de-allocations, or to recycle rather than actually de-allocate
the memory, without having to overload new and delete for the objects in
question.
Being able to remove objects from the container's ownership may be as
important as to place them into it.
And the ability to have pointers to an object in more than one container,
with shared ownership, would be very desirable, almost indispensable I'd
say.

The way I understand your pointer containers, you've achieved two things:
1) They work *as if* storing auto_ptr<>'s but with higher efficiency and
better performance.
2) Syntax is simplified when using algorithms, such as "for_each".

What I wish to convince you of is:
A) that point 2 is very important in its own right, even in situations when
you don't want ownership by the container, such that the semantics would be
*as if* storing weak_ptr<>'s.
B) that in many situations, one may want to customize what happens when the
contained pointer gets erased, and
C) that if it were possible to achieve similar gains of efficiency and
performance as in point 1 but working *as if* storing shared_ptr<>'s, this
might be very useful too; --far more useful in many situations.

Cheers!

Dan

P.S.: Feel free to re-post this email to the mailing list; I just tire of
starting a new thread each time.. :(
How does one *reply* to a message?


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