Output range with custom string type
Jacob Carlborg via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Tue Aug 29 02:59:30 PDT 2017
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
More information about the Digitalmars-d-learn
mailing list