Re: Generic C++ templates/library for FreeBSD base
Date: Fri, 14 Mar 2025 14:45:13 UTC
On 3/14/25 09:50, Dimitry Andric wrote: > On 14 Mar 2025, at 14:36, John Baldwin <jhb@FreeBSD.org> wrote: >> >> On 3/14/25 00:19, Gleb Popov wrote: >>> On Thu, Mar 13, 2025 at 11:53 PM John Baldwin <jhb@freebsd.org> wrote: >>>> >>>> One is a stringf() function that accepts printf() style format string and >>>> arguments and returns a std::string. I know C++23 adds <format>, but we >>>> can't assume that yet, and this function is probably more useful when >>>> adapting existing C code. Compared to some other solutions, I chose to >>>> wrap asprintf() and do an extra copy at the end into a std::string rather >>>> than calling vsnprintf() twice. It seems less ugly than the vsnprintf() >>>> solutions also: >>>> >>>> https://github.com/freebsd/freebsd-src/commit/01bd3d89ddf9ccbf884e52fe7289e8a9278e2d63 >>> I wonder why std::string always copies the data passed into the constructor. >>> It is possible to avoid extra alloc by returning a std::string_view, >>> but this would force the caller into freeing the memory manually. >>> Maybe derive from it and extend the destructor, but this just brings >>> me to the initial question. >> >> What you would want is something where you could do std::move() of the pointer >> returned by asprintf(), into the std::string object, but that assumes that >> new/delete are always using malloc/free (which is probably true in practice). > > The ideal solution would be to define an "inserter" that can be called > from the guts of __vfprintf() (or wherever the "real" implementation of > printf lives), whenever it wants to emit a character into the output > buffer. And there you would simply do string::push_back(), which is > amortized constant time. That you could do with funopen() where the write method called string::push_back(). This is actually how asprintf (and open_memstream) works internally. Maybe I will just fix my implementation to do that. -- John Baldwin