[Boost.AutoBuffer] discussion
I recall some "detail" code in Boost that does exactly what I want: allocate a probably-good-enough size on the stack but switch to heap if needed. But I can't remember where I saw it.
Looking around, I came across mentions of Boost.AutoBuffer by Thorsten Ottosen, but all links are dead.
I have been a bit busy, but I plan to get it going soon.
It seems that there is an unofficial version in
boost/signals2/auto_buffer.hpp
regards
-Thorsten Thanks. I found that copy, and it had your name on it too, so I figure it must be the same code.
I like the feature of making an "uninitialized" expansion, too. In particular, for
dealing with "out" parameters of OS API calls or legacy code, I want to naturally give my
buffer as a vector.data(). But it is annoying to me that it needs to zero out the whole
buffer just to pass it to code that is expecting uninitialized area for output, anyway.
Making "uninitialized" part of this class is natural since the hopefull stack space is
used in the same context. And being your own brand new class, it doesn't fiddle with any
standard library code to achieve it. <g>.
However, I think the existing public API could be improved a little in this manner. Here
is what I ended up doing:
auto_buffer
On 06-05-2013 09:22, John M. Dlugosz wrote:
I recall some "detail" code in Boost that does exactly what I want: allocate a probably-good-enough size on the stack but switch to heap if needed. But I can't remember where I saw it.
Looking around, I came across mentions of Boost.AutoBuffer by Thorsten Ottosen, but all links are dead.
I have been a bit busy, but I plan to get it going soon.
It seems that there is an unofficial version in
boost/signals2/auto_buffer.hpp
regards
-Thorsten Thanks. I found that copy, and it had your name on it too, so I figure it must be the same code.
However, I think the existing public API could be improved a little in this manner. Here is what I ended up doing: auto_buffer
buf; buf.uninitialized_grow (buf.capacity()); // start out with as much as fits on the stack (256 elements). int result= ::GetWindowTextW(hWnd,buf.data(),buf.size()); I had to figure out that capacity was the correct way to get the stack-based size, but that's a documentation thing. I called uninitialized_grow rather than uninitialized_resize because I know it was originally zero; the passing of the delta which looks like the new size too bothers me a little. But my real point is that I can't command an uninitialized size on the constructor. The normal constructor arguments work the same as vector, and can take an initial size and a value that defaults to T(). It would be much clearer and simpler for this use case to say what I want directly on the constructor. I think it would be natural to give a special flag where the value would normally go: auto_buffer
buf1 (500 /*count*/, L' ' /* value */); // same as std::vector auto_buffer buf2 (500, non_initialized); // looks like a "value", but overloaded ctor. and it would be unambiguous to give the non_initialized flag alone, taking the maximum pre-allocated size. auto_buffer buf3 (non_initialized);
My newer version has more explicit control of the initial constructed object.
Meanwhile, should the class support uninitialized sizing ONLY for types that support it? That is, PODs, primitives, classes without destructors, and in general those that are marked as such via a metaprogramming type trait.
No, uninitialized grow/shrink/resize is needed for efficient in-memory serialization of arbitrary types. It's tempting to ban this, but it rules out good use cases. -Thorsten
participants (2)
-
John M. Dlugosz
-
Thorsten Ottosen