| 1 |
template Tpl(Tp...){alias Tp Tpl;} |
|---|
| 2 |
|
|---|
| 3 |
template ArrayOf(T...) |
|---|
| 4 |
{ |
|---|
| 5 |
static assert(T.length > 0); |
|---|
| 6 |
static assert(is(T[0])); |
|---|
| 7 |
|
|---|
| 8 |
static if (T.length == 1) alias T[0][] ArrayOf; |
|---|
| 9 |
else alias Tpl!(T[0][], ArrayOf!(T[1..$])) ArrayOf; |
|---|
| 10 |
} |
|---|
| 11 |
|
|---|
| 12 |
char[] AfterLast(char[] s, char c) |
|---|
| 13 |
{ |
|---|
| 14 |
foreach_reverse(int i, char d; s) if(c==d) return s[i+1..$]; |
|---|
| 15 |
return s; |
|---|
| 16 |
} |
|---|
| 17 |
|
|---|
| 18 |
template BuildArrayAccess(U,uint j ) |
|---|
| 19 |
{ |
|---|
| 20 |
static if(U.tupleof.length <= j) const char[] BuildArrayAccess = ""; |
|---|
| 21 |
else |
|---|
| 22 |
const char[] BuildArrayAccess = |
|---|
| 23 |
typeof(U.tupleof)[j].stringof ~ "[] " ~ AfterLast(U.tupleof[j].stringof,'.') ~ "(){return members["~j.stringof~"];}\n" ~ BuildArrayAccess!(U,j+1); |
|---|
| 24 |
} |
|---|
| 25 |
|
|---|
| 26 |
template BuildItemAccess(U,uint j ) |
|---|
| 27 |
{ |
|---|
| 28 |
static if(U.tupleof.length <= j) const char[] BuildItemAccess = ""; |
|---|
| 29 |
else |
|---|
| 30 |
const char[] BuildItemAccess = |
|---|
| 31 |
typeof(U.tupleof)[j].stringof ~ " " ~ AfterLast(U.tupleof[j].stringof,'.') ~ "(){return __base.members["~j.stringof~"][__i];}\n" ~ |
|---|
| 32 |
typeof(U.tupleof)[j].stringof ~ " " ~ AfterLast(U.tupleof[j].stringof,'.') ~ "("~typeof(U.tupleof)[j].stringof~" v){return __base.members["~j.stringof~"][__i] = v;}\n" ~ |
|---|
| 33 |
BuildItemAccess!(U,j+1); |
|---|
| 34 |
} |
|---|
| 35 |
|
|---|
| 36 |
struct Columns(T) |
|---|
| 37 |
{ |
|---|
| 38 |
|
|---|
| 39 |
static assert(is(T == struct)); |
|---|
| 40 |
//pragma(msg, typeof(T.tupleof).stringof); |
|---|
| 41 |
//pragma(msg, ArrayOf!(typeof(T.tupleof)).stringof); |
|---|
| 42 |
|
|---|
| 43 |
private ArrayOf!(typeof(T.tupleof)) members; |
|---|
| 44 |
|
|---|
| 45 |
|
|---|
| 46 |
struct At |
|---|
| 47 |
{ |
|---|
| 48 |
Columns!(T)* __base; |
|---|
| 49 |
int __i; |
|---|
| 50 |
|
|---|
| 51 |
T FullItem() |
|---|
| 52 |
{ |
|---|
| 53 |
T ret; |
|---|
| 54 |
foreach(i,_;typeof(T.tupleof)) ret.tupleof[i] = __base.members[i][__i]; |
|---|
| 55 |
return ret; |
|---|
| 56 |
} |
|---|
| 57 |
|
|---|
| 58 |
//pragma(msg,">"~BuildItemAccess!(T,0)~"<"); |
|---|
| 59 |
mixin(BuildItemAccess!(T,0)); |
|---|
| 60 |
} |
|---|
| 61 |
|
|---|
| 62 |
//pragma(msg,">"~BuildArrayAccess!(T,0)~"<"); |
|---|
| 63 |
mixin(BuildArrayAccess!(T,0)); |
|---|
| 64 |
At opIndex(uint i) { return At(this,i); } |
|---|
| 65 |
|
|---|
| 66 |
T opIndexAssign(T inp,int i) |
|---|
| 67 |
{ |
|---|
| 68 |
foreach(j,_;typeof(T.tupleof)) members[j][i] = inp.tupleof[j]; |
|---|
| 69 |
return inp; |
|---|
| 70 |
} |
|---|
| 71 |
|
|---|
| 72 |
|
|---|
| 73 |
int length(){ return members[0].length; } |
|---|
| 74 |
void length(int L) { foreach(i,_;members) members[i].length = L; } |
|---|
| 75 |
} |
|---|
| 76 |
|
|---|
| 77 |
|
|---|
| 78 |
|
|---|
| 79 |
|
|---|
| 80 |
import std.stdio; |
|---|
| 81 |
unittest |
|---|
| 82 |
{ |
|---|
| 83 |
struct Foo |
|---|
| 84 |
{ |
|---|
| 85 |
float k; |
|---|
| 86 |
int i; |
|---|
| 87 |
uint j; |
|---|
| 88 |
void print(){writef("%s, %s, %s\n", k, i, j);} |
|---|
| 89 |
} |
|---|
| 90 |
|
|---|
| 91 |
Foo foo; |
|---|
| 92 |
Columns!(Foo) FooCol; |
|---|
| 93 |
|
|---|
| 94 |
|
|---|
| 95 |
FooCol.length = 10; |
|---|
| 96 |
for(int i = 0; i < 10; i++) |
|---|
| 97 |
{ |
|---|
| 98 |
foo.k = 3.14 * i; |
|---|
| 99 |
foo.i = -3 - i; |
|---|
| 100 |
foo.j = 5 + i; |
|---|
| 101 |
FooCol[i] = foo; |
|---|
| 102 |
} |
|---|
| 103 |
foreach(float f; FooCol.k) writef("%s ", f); writef(\n); |
|---|
| 104 |
foreach(int i; FooCol.i) writef("%s ", i); writef(\n); |
|---|
| 105 |
foreach(uint u; FooCol.j) writef("%s ", u); writef(\n); |
|---|
| 106 |
FooCol[3].FullItem.print(); |
|---|
| 107 |
|
|---|
| 108 |
} |
|---|