Output range with custom string type
Jacob Carlborg via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Tue Aug 29 23:38:27 PDT 2017
On 2017-08-29 19:35, Moritz Maxeiner wrote:
> On Tuesday, 29 August 2017 at 09:59:30 UTC, Jacob Carlborg wrote:
>> [...]
>>
>> 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.
>
> Certainly, that's what dynamic arrays (aka vectors, e.g. std::vector in
> C++ STL) are for:
>
> ---
> import core.exception;
>
> import std.stdio;
> import std.experimental.allocator;
> import std.algorithm;
>
> struct PoorMansVector(T)
> {
> private:
> T[] store;
> size_t length;
> IAllocator alloc;
> public:
> @disable this(this);
> this(IAllocator alloc)
> {
> this.alloc = alloc;
> }
> ~this()
> {
> if (store)
> {
> alloc.dispose(store);
> store = null;
> }
> }
> void put(T t)
> {
> if (!store)
> {
> // Allocate only once for "small" vectors
> store = alloc.makeArray!T(8);
> if (!store) onOutOfMemoryError();
> }
> else if (length == store.length)
> {
> // Growth factor of 1.5
> auto expanded = alloc.expandArray!char(store, store.length
> / 2);
> if (!expanded) onOutOfMemoryError();
> }
> assert (length < store.length);
> moveEmplace(t, store[length++]);
> }
> char[] release()
> {
> auto elements = store[0..length];
> store = null;
> return elements;
> }
> }
>
> char[] sanitize(string value, IAllocator alloc)
> {
> import std.format : formattedWrite, sformat;
>
> auto r = PoorMansVector!char(alloc);
> (&r).formattedWrite!"'%s'"(value); // do not copy the range
> return r.release();
> }
>
> void main()
> {
> auto s = sanitize("foo", theAllocator);
> scope (exit) theAllocator.dispose(s);
> writeln(s);
> }
> ---
>
> Do be aware that the above vector is named "poor man's vector" for a
> reason, that's a hasty write down from memory and is sure to contain bugs.
> For better vector implementations you can use at collection libraries
> such as EMSI containers; my own attempt at a DbI vector container can be
> found here [1]
>
> [1]
> https://github.com/Calrama/libds/blob/6a1fc347e1f742b8f67513e25a9fdbf79f007417/src/ds/vector.d
>
Thanks.
--
/Jacob Carlborg
More information about the Digitalmars-d-learn
mailing list