custom allocators for shared_ptr
It would be useful if shared_ptr and family provided a way to give a custom allocator. For instance, to replace the quick allocator with a lock-free one. -- Cory Nelson
On Thu, Sep 27, 2007 at 08:21:00PM -0700, Cory Nelson wrote:
It would be useful if shared_ptr and family provided a way to give a custom allocator. For instance, to replace the quick allocator with a lock-free one.
Eh, indeed. That's why I have switched to intrusive_ptr (which might not be possible in your case). If you read the FAQ about shared_ptr, you will see that configurability has NOT been the goal and you will be "forwarded" to Alexandrescu's MC++D for policy-based smart pointer design.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2232.html shared_ptr in c++0x will have custom allocators On 9/28/07, Zeljko Vrba <zvrba@ifi.uio.no> wrote:
On Thu, Sep 27, 2007 at 08:21:00PM -0700, Cory Nelson wrote:
It would be useful if shared_ptr and family provided a way to give a custom allocator. For instance, to replace the quick allocator with a lock-free one.
Eh, indeed. That's why I have switched to intrusive_ptr (which might not be possible in your case).
If you read the FAQ about shared_ptr, you will see that configurability has NOT been the goal and you will be "forwarded" to Alexandrescu's MC++D for policy-based smart pointer design.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Cory Nelson wrote:
It would be useful if shared_ptr and family provided a way to give a custom allocator. For instance, to replace the quick allocator with a lock-free one.
boost::shared_ptr is already ready to accept allocators: http://www.boost.org/libs/smart_ptr/shared_ptr.htm template<class Y, class D> shared_ptr(Y * p, D d); template<class Y, class D, class A> shared_ptr(Y * p, D d, A a); Requirements: p must be convertible to T *. D must be CopyConstructible. The copy constructor and destructor of D must not throw. The expression d(p) must be well-formed, must not invoke undefined behavior, and must not throw exceptions. A must be an Allocator, as described in section 20.1.5 (Allocator requirements) of the C++ Standard. Effects: Constructs a shared_ptr that owns the pointer p and the deleter d. The second constructor allocates memory using a copy of a. Postconditions: use_count() == 1 && get() == p. Throws: std::bad_alloc, or an implementation-defined exception when a resource other than memory could not be obtained. Exception safety: If an exception is thrown, d(p) is called. Notes: When the the time comes to delete the object pointed to by p, the stored copy of d is invoked with the stored copy of p as an argument. Regards, Ion
On Fri, Sep 28, 2007 at 10:59:32AM +0200, Ion Gaztañaga wrote:
Notes: When the the time comes to delete the object pointed to by p, the stored copy of d is invoked with the stored copy of p as an argument.
I think that the original poster was referring to internal allocation that shared_ptr does for *its own* needs (shared_ptr dynamically allocates a counter class per every 'vivifying' instance [i.e. when created from a raw pointer, not from another shared_ptr]).
Zeljko Vrba wrote:
On Fri, Sep 28, 2007 at 10:59:32AM +0200, Ion Gaztañaga wrote:
Notes: When the the time comes to delete the object pointed to by p, the stored copy of d is invoked with the stored copy of p as an argument.
I think that the original poster was referring to internal allocation that shared_ptr does for *its own* needs
That's what the A argument is for. You quoted the wrong clause.
On Fri, Sep 28, 2007 at 12:55:07PM +0300, Peter Dimov wrote:
That's what the A argument is for. You quoted the wrong clause.
Oh, sorry. You mean this constructor: template<class Y, class D, class A> shared_ptr(Y * p, D d, A a); A question: why is the API designed so that using a custom allocator forces the user to specify a deallocator? I.e. the two are orthogonal, so why force the (use A) => (must use D) implication? Is there a standard deleter class that can be just used in place of D?
Zeljko Vrba wrote:
On Fri, Sep 28, 2007 at 12:55:07PM +0300, Peter Dimov wrote:
That's what the A argument is for. You quoted the wrong clause.
Oh, sorry. You mean this constructor:
template<class Y, class D, class A> shared_ptr(Y * p, D d, A a);
A question: why is the API designed so that using a custom allocator forces the user to specify a deallocator? I.e. the two are orthogonal, so why force the (use A) => (must use D) implication?
Given an Allocator concept, it'd be possible to add template<class Y, Allocator A> shared_ptr( Y * p, A a ); In practice, it's rare for the user to want to use a custom allocator for the control block, yet not use a custom allocator for the object, so forcing him to pass a deleter as well is not as constraining. One might even argue that it removes the ambiguity that is present in the above form, where it isn't clear whether A should be used to deallocate *p as well.
On Fri, Sep 28, 2007 at 03:39:31PM +0300, Peter Dimov wrote:
In practice, it's rare for the user to want to use a custom allocator for the control block, yet not use a custom allocator for the object, so forcing him to pass a deleter as well is not as constraining.
But isn't overloading of new/delete the "usual" way of implementing a custom allocator for a class? In that case, an ordinary "delete" will deallocate the class properly (hence my question about standard deleter class).
Zeljko Vrba wrote:
On Fri, Sep 28, 2007 at 03:39:31PM +0300, Peter Dimov wrote:
In practice, it's rare for the user to want to use a custom allocator for the control block, yet not use a custom allocator for the object, so forcing him to pass a deleter as well is not as constraining.
But isn't overloading of new/delete the "usual" way of implementing a custom allocator for a class? In that case, an ordinary "delete" will deallocate the class properly (hence my question about standard deleter class).
The latest draft (N2369) has default_delete in the unique_ptr section (20.6.5.1). I'd have named it default_deleter though. :-) Boost has checked_deleter that's pretty much identical.
Cory Nelson wrote:
It would be useful if shared_ptr and family provided a way to give a custom allocator. For instance, to replace the quick allocator with a lock-free one.
By a quirk of excellent timing this recipe submitted earlier today illustrates how to do it quite nicely. http://www.boostcookbook.com/Recipe:/1234950 It still uses new and delete, but they look quite simple to replace. K
participants (6)
-
Chris Fairles
-
Cory Nelson
-
Ion Gaztañaga
-
Kirit Sælensminde
-
Peter Dimov
-
Zeljko Vrba