Output range with custom string type

Moritz Maxeiner via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Aug 29 10:35:17 PDT 2017


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


More information about the Digitalmars-d-learn mailing list