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!
Looking at the source it seems you can use your own allocator which is then used by the internal stream (internal_streambuf_t
) of boost::format
. Would that be good enough for your case?
For example you could use something like the libstdc++ array_allocator
Unfortunately boost::format
also uses a couple of std::vector
which do not use the custom allocator which may be a problem in your case?
boost::format
worksI looked into the source of boost::format
and this is how it works (described below is str()
, <<
calls either str()
or uses standard std::ostream
stuff) :
str()
is called it creates a new std::string
and 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 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.
str()
or <<
and copy the result into your fixed buffer stream_buffer
to '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):
#include <iostream>
#include <boost/format.hpp>
#include <boost/iostreams/stream.hpp>
int main()
{
char buffer[100];
boost::iostreams::stream<boost::iostreams::array_sink>
stream(buffer, sizeof(buffer));
stream << (boost::format("arg1 = %1%") % 12.5);
stream << '\0'; // make sure buffer contains 0-terminated string
std::cout << buffer << std::endl;
}