I was wondering whether Boost.Format does support using a fixed-width / preallocated buffer as output instead of a dynamic buffer managed by the lib itself?
That is, normally you’d do:
boost::format myfmt("arg1: %1% / arg2: %2%");
// e.g.:
cout << (myfmt % 3.14 % 42);
// or
string s = boost::str( myfmt % "hey!" % "there!");
so the Boost:Format lib will automatically take care of allocating enough space and managing the “output buffer” for you.
I was wondering if there’s any way to use a predefine non-dynamic buffer with Boost.Format, that is, something like:
const size_t buf_sz = 512;
char big_enough[buf_sz];
boost::format myfmt("arg1: %1% / arg2: %2%");
myfmt.attach_buffer(big_enough, buf_sz);
myfmt % "hey!" % "there!"
// big_enough buffer now contains the result string
I know I could just sift through the examples, the docs and the source, but apart from lacking time atm. (and the very possibility of missing something) it would be interesting to know:
If it is not possible, it would be great if someone could explain why (if there is/are specific whys) — was it deliberate? doesn’t it match the API well? …?
Disclaimer: This question is not about performance!
Initial Idea
Looking at the source it seems you can use your own allocator which is then used by the internal stream (
internal_streambuf_t) ofboost::format. Would that be good enough for your case?For example you could use something like the libstdc++ array_allocator
Unfortunately
boost::formatalso uses a couple ofstd::vectorwhich do not use the custom allocator which may be a problem in your case?How
boost::formatworksI looked into the source of
boost::formatand this is how it works (described below isstr(),<<calls eitherstr()or uses standardstd::ostreamstuff) :str()is called it creates a newstd::stringand makes it large enough for the result using the custom allocatorSo, the final result string is not stored inside the format class but created when needed.
So even if you can find the location of the result string when using a custom allocator, it is only available after/during a call to
str().This should explain why it is not possible: the formatted result is never stored inside an “output buffer” in the class.
Why it works like this
Why they did it this way I do not know. I think it is because you can only build the result after all arguments are known, it wastes space to store the result and you probably only need the result just once for a given format/argument combination. So creating it when needed does not result in extra work since typically
str()is only called once.Solutions
str()or<<and copy the result into your fixed bufferstream_bufferto ‘stream’ the string into the buffer (see example below)str()function which stores the result in a fixed buffer.Possible solution using boost::iostreams (tested):