On 2017-08-28 23:45, Moritz Maxeiner wrote:
If you want the caller to be just in charge of allocation, that's what
std.experimental.allocator provides. In this case, I would polish up the
old "format once to get the length, allocate, format second time into
allocated buffer" method used with snprintf for D:
--- test.d ---
import std.stdio;
import std.experimental.allocator;
struct CountingOutputRange
{
private:
size_t _count;
public:
size_t count() { return _count; }
void put(char c) { _count++; }
}
char[] sanitize(string value, IAllocator alloc)
{
import std.format : formattedWrite, sformat;
CountingOutputRange r;
(&r).formattedWrite!"'%s'"(value); // do not copy the range
auto s = alloc.makeArray!char(r.count);
scope (failure) alloc.dispose(s);
// This should only throw if the user provided allocator
returned less
// memory than was requested
return s.sformat!"'%s'"(value);
}
void main()
{
auto s = sanitize("foo", theAllocator);
scope (exit) theAllocator.dispose(s);
writeln(s);
}
--------------
I guess that would work.
But if I keep the range internal, can't I just do the allocation inside
the range and only use "formattedWrite"? Instead of using both
formattedWrite and sformat and go through the data twice. Then of course
the final size is not known before allocating.
--
/Jacob Carlborg