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