cool stuff

This commit is contained in:
Adam D. Ruppe 2020-01-09 19:46:30 -05:00
parent 07f73fec97
commit 09a6e315b1
2 changed files with 63 additions and 120 deletions

View file

@ -69,7 +69,15 @@ union N(ty) {
/// input range of ubytes...
int loadFrom(T, Range)(ref T t, auto ref Range r, bool assumeBigEndian = false) {
int bytesConsumed;
string currentItem;
import std.conv;
scope(failure)
throw new Exception(T.stringof ~ "." ~ currentItem ~ " trouble " ~ to!string(t));
ubyte next() {
if(r.empty)
throw new Exception(T.stringof ~ "." ~ currentItem ~ " trouble " ~ to!string(t));
auto bfr = r.front;
r.popFront;
bytesConsumed++;
@ -78,6 +86,7 @@ int loadFrom(T, Range)(ref T t, auto ref Range r, bool assumeBigEndian = false)
bool endianness = bigEndian!T(assumeBigEndian);
static foreach(memberName; __traits(allMembers, T)) {{
currentItem = memberName;
static if(is(typeof(__traits(getMember, T, memberName)))) {
alias f = __traits(getMember, T, memberName);
alias ty = typeof(f);
@ -115,11 +124,17 @@ int loadFrom(T, Range)(ref T t, auto ref Range r, bool assumeBigEndian = false)
auto tag = __traits(getMember, t, tagField);
// find the child of the union matching the tag...
bool found = false;
static foreach(um; __traits(allMembers, ty)) {
if(tag == getTag!(__traits(getMember, ty, um))) {
bytesConsumed += loadFrom(__traits(getMember, __traits(getMember, t, memberName), um), r, endianness);
found = true;
}
}
if(!found) {
import std.format;
throw new Exception(format("found unknown union tag %s at %s", tag, t));
}
} else static if(is(ty == E[], E)) {
static foreach(attr; __traits(getAttributes, f)) {
static if(is(attr == NumBytes!Field, alias Field))