Re: [boost] [function] allocator template parameter question

On Jun 4, 2007, at 10:57 PM, Emil Dotchevski wrote:> > One important advantage of using boost::function is that it acts > > like a> > function pointer, reducing physical coupling between compilation > > units. This> > is very much like shared_ptr.> >> > A nice feature of shared_ptr is that it has a single template > > parameter, T,> > even though diferent instances of shared_ptr<T> can use different> > allocators.> >> > When using boost::function, one can also provide an allocator, but > > unlike> > shared_ptr, the allocator is a default parameter of the > > boost::function> > class template.> > > Is there a reason why this is necessary? Can't boost::function use > > similar> > technique to the one employed by shared_ptr to avoid the need for this> > second template parameter?> > You know, I never even thought about adding it. I didn't know about > the shared_ptr technique when I put the allocator into > boost::function, and after the C++ committee removed the allocator I > didn't think about it any more. Perhaps if the allocator it's moved to the constructor, the committee would accept it? :)
<snip>> I don't know when I would have time to implement this, although I > would certainly consider adding this functionality to Boost's > "function". Might you be interested in implementing it? OK, I'll give it a shot, and I'll let you know how it goes.
Emil Dotchevski _________________________________________________________________ Live Earth is coming. Learn more about the hottest summer event - only on MSN. http://liveearth.msn.com?source=msntaglineliveearthwlm

On Jun 5, 2007, at 12:42 PM, Emil Dotchevski wrote:
On Jun 4, 2007, at 10:57 PM, Emil Dotchevski wrote:> > One important advantage of using boost::function is that it acts > > like a> > function pointer, reducing physical coupling between compilation > > units. This> > is very much like shared_ptr.> >> > A nice feature of shared_ptr is that it has a single template > > parameter, T,> > even though diferent instances of shared_ptr<T> can use different> > allocators.> >> > When using boost::function, one can also provide an allocator, but > > unlike> > shared_ptr, the allocator is a default parameter of the > > boost::function> > class template.> > > Is there a reason why this is necessary? Can't boost::function use > > similar> > technique to the one employed by shared_ptr to avoid the need for this> > second template parameter?> > You know, I never even thought about adding it. I didn't know about > the shared_ptr technique when I put the allocator into > boost::function, and after the C++ committee removed the allocator I > didn't think about it any more. Perhaps if the allocator it's moved to the constructor, the committee would accept it? :)
Since shared_ptr already has this functionality in its constructor, they may accept it. You could certainly write a short proposal to the C++ committee...
<snip>> I don't know when I would have time to implement this, although I > would certainly consider adding this functionality to Boost's > "function". Might you be interested in implementing it? OK, I'll give it a shot, and I'll let you know how it goes.
Great! - Doug

I wrote an implementation which removes the Allocator parameter of boost::function: http://www.revergestudios.com/boost-function/ All tests pass on msvc 7.1, 8.0, and gcc 3.4.4 (I had to modify the allocator test.) To try my implementation, you'll need the rest of the boost::function files from CVS HEAD. Allocators are supported as an argument to the following boost::function constructor: template<typename Functor,typename Allocator> function(Functor f, Allocator a); A copy of the passed allocator is stored in the boost::function object, the same way it's done in shared_ptr. Notes: 1) As in the current official boost::function implementation, the allocator is only used if the boost::function object is initialized with a function object which does not fit in a "small" static buffer. 2) When a function object that can not use the small object optimization is assigned (by operator=) to an existing boost::function object, the boost::function object will not have an allocator and will use new/delete. To allow users to supply an allocator in an assignment operation, I added a new member function: template<typename Functor,typename Allocator> void assign(Functor f, Allocator a); Emil Dotchevski ----- Original Message ----- From: "Douglas Gregor" <doug.gregor@gmail.com> To: <boost@lists.boost.org> Sent: Tuesday, June 05, 2007 10:46 AM Subject: Re: [boost] [function] allocator template parameter question
On Jun 5, 2007, at 12:42 PM, Emil Dotchevski wrote:
On Jun 4, 2007, at 10:57 PM, Emil Dotchevski wrote:> > One important advantage of using boost::function is that it acts > > like a> > function pointer, reducing physical coupling between compilation > > units. This> > is very much like shared_ptr.> >> > A nice feature of shared_ptr is that it has a single template > > parameter, T,> > even though diferent instances of shared_ptr<T> can use different> > allocators.> >> > When using boost::function, one can also provide an allocator, but > > unlike> > shared_ptr, the allocator is a default parameter of the > > boost::function> > class template.> > > Is there a reason why this is necessary? Can't boost::function use > > similar> > technique to the one employed by shared_ptr to avoid the need for this> > second template parameter?> > You know, I never even thought about adding it. I didn't know about > the shared_ptr technique when I put the allocator into > boost::function, and after the C++ committee removed the allocator I > didn't think about it any more. Perhaps if the allocator it's moved to the constructor, the committee would accept it? :)
Since shared_ptr already has this functionality in its constructor, they may accept it. You could certainly write a short proposal to the C++ committee...
<snip>> I don't know when I would have time to implement this, although I > would certainly consider adding this functionality to Boost's > "function". Might you be interested in implementing it? OK, I'll give it a shot, and I'll let you know how it goes.
Great!
- Doug _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Umm I just realized that the implementation I posted (see my other post) hasn't been fully tested. I had written another implementation which added the allocator parameter where necessary, and the allocator-less code simply passed an std::allocator where allocator was required. This means that even when the user does not supply an allocator, the allocator code is still instantiated in the tests (even though the allocator might not get used due to optimizations.) In the implementation I posted, I opted for a parallel line of allocator support functions next to the original allocator-less functions. I liked this better because no allocator-related stuff is ever instantiated unless the user passes an allocator (and most users don't.) The problem is that most boost::function tests do not use allocators. So while the allocator code should work (because it got tested in its original form), in it's current form it has only been proven to pass the allocator_test.cpp, which is rather simplistic. To really test everything, one needs to run all tests with the following variations: - pointer to function - pointer to member function - function object that fits the small object optimization - function object that does not fit the small object optimization - all of the above variations using an user-supplied allocator. Emil Dotchevski

On Jun 7, 2007, at 2:22 PM, Emil Dotchevski wrote:
In the implementation I posted, I opted for a parallel line of allocator support functions next to the original allocator-less functions. I liked this better because no allocator-related stuff is ever instantiated unless the user passes an allocator (and most users don't.)
Okay, that makes sense.
The problem is that most boost::function tests do not use allocators. So while the allocator code should work (because it got tested in its original form), in it's current form it has only been proven to pass the allocator_test.cpp, which is rather simplistic.
Ah.
To really test everything, one needs to run all tests with the following variations:
- pointer to function - pointer to member function - function object that fits the small object optimization - function object that does not fit the small object optimization - all of the above variations using an user-supplied allocator.
function_test and function_n_test test most of these, but without the user-supplied allocator. You could probably hack up those. Thanks for implementing this, and so quickly! Looking briefly through the code... I see that you're not actually storing the value of the allocator object itself along with the function object. Was that decision intentional, or were you just following the behavior of the existing boost::function? I haven't done a thorough review of the code, but I'd be inclined to move boost::function toward this approach. It's a better extension to tr1::function than the existing code, and it might be the right way for C++0x's "function" to go. If you're interested in this feature going into the next standard, I suggest writing a short proposal to the C++ Library Working Group for this extension. - Doug

function_test and function_n_test test most of these, but without the user-supplied allocator. You could probably hack up those.
I'll take a look.
Thanks for implementing this, and so quickly!
No problem.
Looking briefly through the code... I see that you're not actually storing the value of the allocator object itself along with the function object. Was that decision intentional, or were you just following the behavior of the existing boost::function?
I am storing the allocator, in struct functor_wrapper from function_base.hpp, but it has a partial specialization for std::allocator which doesn't store the allocator, and perhaps that's what you saw. Please take another look: http://www.revergestudios.com/boost-function/function_base.hpp Of course if the function object can use the small object optimization, the functor_wrapper template is not used and no copy of the allocator is stored in the boost::function.
I haven't done a thorough review of the code, but I'd be inclined to move boost::function toward this approach. It's a better extension to tr1::function than the existing code, and it might be the right way for C++0x's "function" to go. If you're interested in this feature going into the next standard, I suggest writing a short proposal to the C++ Library Working Group for this extension.
Will do. Emil Dotchevski

On Jun 7, 2007, at 10:21 PM, Emil Dotchevski wrote:
I am storing the allocator, in struct functor_wrapper from function_base.hpp, but it has a partial specialization for std::allocator which doesn't store the allocator, and perhaps that's what you saw. Please take another look:
http://www.revergestudios.com/boost-function/function_base.hpp
Of course if the function object can use the small object optimization, the functor_wrapper template is not used and no copy of the allocator is stored in the boost::function.
Ah, right. I was looking at part of the code where the allocator wasn't being passed on, but of course that part of the code didn't need to do any allocation. Two comments: (1) Often, one inherits from the allocator rather than storing it in a member. That way, if the allocator type is empty, we don't need to use up any storage. (2) Visual C++ strikes again: we'll have to #ifdef out these allocator versions for Microsoft's compiler prior to version 7.1, both because of the reliance on partial specialization of class templates and because of the use of rebind.
I haven't done a thorough review of the code, but I'd be inclined to move boost::function toward this approach. It's a better extension to tr1::function than the existing code, and it might be the right way for C++0x's "function" to go. If you're interested in this feature going into the next standard, I suggest writing a short proposal to the C++ Library Working Group for this extension.
Will do.
Looking forward to it. If you write it soon, it should get on the agenda for the July meeting of the C++ committee. I expect it will be easily accepted. - Doug
participants (2)
-
Douglas Gregor
-
Emil Dotchevski