
Matt Calabrese skrev:
On Wed, Mar 4, 2009 at 6:54 PM, Thorsten Ottosen < thorsten.ottosen@dezide.com> wrote:
Dear All,
Hereby an updated class. Thanks to all who contributed with comments to the first try.
...
Comments most welcome!
Looking good.
Thanks.
Is there a reason why you assert ( this != &r ) in the assignment operator? Certainly this case could be handled by just returning *this, right?
Yes. I must admit I always disliked the discussions on "assignment to *this". I never personally created code that would run into such cases. So I put the assertion there because I don't want to use cycles on this case. I think it is hypothetical.
Also, the more I think about it, we have only been looking at this as strictly for use on the stack, but nothing prevents someone from using it as a global, or for instance, as a datamember of a type that may not be instantiated on the stack, which may be beneficial as well (or at the very least, nothing prevents someone from using it in such a manner).
Right. That is mainly why I added copy-operations.
This means the function "is_on_stack" may be better named "is_stored_locally" or something similar.
Maybe, I'm not sure.
Just to throw it out there as something to consider, I could definitely see a generalization of this idea not specific to array allocation also being very useful. By this I mean, a template similar to what you have now but dealing with raw memory without a container interface and no stored type specified -- it would just let you do a raw "resize" (or "reallocate"). When the requested size is under N, accessing the data gives you a pointer to the locally stored buffer, otherwise it is to dynamically allocated memory managed by the type, much like auto_buffer. The main use-case I see for this would be as an implementation detail internal to an "any" or "function" or
Remark: boost::any desparately needs SBO.
"poly" kind of type to allow objects under a certain size to be stored directly in the type in which it is contained rather than dynamically, resorting to additional allocation only when necessary. Instantiating the template with a different value for N would in effect control how large of an object could be stored locally before having to resort to an additional allocation.
I'm not implying that you should implement this, just that it is something to think about. The implementation would be extremely similar and it even seems like the former may be able to be implemented via the latter.
I guess it is a bit like some people talked about when they referred to allocators with an embedded stack buffer. As one can see from my code, swap and copy-operations are difficult to implement. Especially swap. Therefore such an allocator will be *very* difficult to use correctly in a container. In particular, swap() sometimes only gives the basic guarantee (and no better guarantee is possible!). The partially stack-based allocator works fine if the container is used locally, but seems very problematic for general use-cases. -Thorsten