| 1 | = Using .tupleof = |
---|
| 2 | |
---|
| 3 | The {{{.tupleof}}} struct property can be used to deal with structs generically. |
---|
| 4 | |
---|
| 5 | == Basic usage == |
---|
| 6 | {{{ |
---|
| 7 | #!d |
---|
| 8 | struct S { int a,b; } |
---|
| 9 | S s; |
---|
| 10 | s.tupleof[1] = 42; |
---|
| 11 | }}} |
---|
| 12 | |
---|
| 13 | == Iterating == |
---|
| 14 | |
---|
| 15 | The index to .tupleof must be const, so you cannot, for instance, do: |
---|
| 16 | {{{ |
---|
| 17 | #!d |
---|
| 18 | struct S { ... } |
---|
| 19 | S s; |
---|
| 20 | for (size_t i = 0; i < s.tupleof.length; ++i) |
---|
| 21 | Stdout (s.tupleof[i]).newline; // error: i is not const |
---|
| 22 | }}} |
---|
| 23 | |
---|
| 24 | But it is possible to use foreach: |
---|
| 25 | {{{ |
---|
| 26 | #!d |
---|
| 27 | void printStruct(T) (T s) |
---|
| 28 | { |
---|
| 29 | static assert (is(T == struct), "Only to be used with structs."); |
---|
| 30 | |
---|
| 31 | foreach (x,y; s.tupleof) |
---|
| 32 | Stdout.format ("Element: {}:{}", x,y).newline; |
---|
| 33 | } |
---|
| 34 | It doesn't seem to be possible to set the elements of a struct using foreach, however (correct me if I'm wrong; I couldn't make it work). |
---|
| 35 | }}} |
---|
| 36 | |
---|
| 37 | == Setting the elements == |
---|
| 38 | The following is a function I wrote to set all elements of a struct from a static array, to get around the difficulty of setting elements while iterating over the tuple. (It could easily be converted to read from a dynamic array.) |
---|
| 39 | {{{ |
---|
| 40 | #!d |
---|
| 41 | // only used for error reporting: |
---|
| 42 | // Int-to-string converter, which may not be efficient but will run at compile time. |
---|
| 43 | static char[] int2str (uint i) { |
---|
| 44 | char[] ret; |
---|
| 45 | const digits = "0123456789"; |
---|
| 46 | if (i == 0) ret = "0"; |
---|
| 47 | else for (; i > 0; i /= 10) ret = digits[i%10] ~ ret; |
---|
| 48 | return ret; |
---|
| 49 | } |
---|
| 50 | |
---|
| 51 | /** Set a struct's elements from an array, where all elements in the struct have the same type (or |
---|
| 52 | * can be implicitly converted to from the same type). |
---|
| 53 | * |
---|
| 54 | * --- |
---|
| 55 | * struct S { int a,b,c; } |
---|
| 56 | * S s; |
---|
| 57 | * int[3] v = [1,2,3]; |
---|
| 58 | * setStruct (s,v); |
---|
| 59 | * --- |
---|
| 60 | * |
---|
| 61 | * It works fine. I'm not sure about the efficiency (do the recursive calls get inlined?). |
---|
| 62 | */ |
---|
| 63 | void setStruct(S, T, size_t N, size_t i = 0) (ref S s, T[N] src) { |
---|
| 64 | static assert (is(S == struct), "Only to be used with structs."); |
---|
| 65 | static assert (N == S.tupleof.length, "src.length == "~int2str(N)~"; should equal "~int2str(S.tupleof.length)); |
---|
| 66 | static if (i < N) { |
---|
| 67 | s.tupleof[i] = src[i]; |
---|
| 68 | setStruct!(S, T, N, i+1) (s, src); |
---|
| 69 | } |
---|
| 70 | } |
---|
| 71 | }}} |
---|
| 72 | |
---|
| 73 | == Example == |
---|
| 74 | Using the above functions, this can be done: |
---|
| 75 | {{{ |
---|
| 76 | #!d |
---|
| 77 | struct S2 |
---|
| 78 | { |
---|
| 79 | //char[] first, second, third; |
---|
| 80 | uint a; |
---|
| 81 | byte b; |
---|
| 82 | ulong c; |
---|
| 83 | float d; |
---|
| 84 | } |
---|
| 85 | |
---|
| 86 | void main() { |
---|
| 87 | S2 v; |
---|
| 88 | //char[][3] vals = ["One"[], "Two", "Three"]; |
---|
| 89 | long[4] vals = [-1L,-100,10000000000, 2]; |
---|
| 90 | setStruct(v, vals); |
---|
| 91 | printStruct(v); |
---|
| 92 | } |
---|
| 93 | }}} |
---|
| 94 | |
---|
| 95 | |
---|
| 96 | = Source = |
---|
| 97 | || Posted by || Cyborg16 || |
---|
| 98 | || Date || August 4, 2008 || |