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