Is this code "D-ish" enough?
Justin Whear
justin at economicmodeling.com
Wed Aug 7 13:31:04 PDT 2013
The key problem here is that you have an unstructured range of bytes and
you want to provide a function to iteratively structure it. The
splitting and chunking functionality in Phobos doesn't fit because the
records are not of fixed size nor do they contain a usable delimiter.
Unfortunately, I can't think of anything currently in Phobos that makes
this easy.
My take on this was to define a range which induces structure over
another by consuming it with a user function; for lack of a better term I
called it "restructure". It works much like map, except instead of
passing an element to the user function, it passes the range itself and
the function is expected to consume some amount of it.
Here's the code rewritten (without your formatting map) with the
restructure function:
import std.stdio,
std.range,
std.algorithm,
std.file,
std.typecons;
import std.bitmanip : readAs = read;
void main(string[] args)
{
string readZeroTerminatedString(R)(ref R range)
{
return (cast(char[])range.until!('\0').array).idup;
}
// Read file as range of bytes
File("binsplit.bin", "rb")
.byChunk(1024 * 4)
.joiner
// Induce our record structure over that range
.restructure!(r => tuple(r.readAs!int,
r.readZeroTerminatedString))
// Sort the records by the first field (id)
.sort((a, b) => a[0] < b[0])
// Write to stdout
.copy(stdout.lockingTextWriter);
}
And here's a quick and dirty outline of the restructure function itself.
Unfortunately, it doesn't actually compile due to needing to take the
source range by ref. Also, the user function needs to take the range by
ref so that it can be consumed.
auto restructure(alias Fun, R)(ref R range)
if (isInputRange!R
//TODO test Fun: must be an unary function taking R
)
{
struct Result
{
alias F = typeof(Fun(range));
private R range;
private F _front;
bool empty() @property { return range.empty; }
F front() @property { return _front; }
void popFront()
{
_front = Fun(range);
}
}
return Result(range);
}
More information about the Digitalmars-d-learn
mailing list