Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Changes from Version 1 of StructTupleof

Show
Ignore:
Author:
Cyborg16 (IP: 86.27.239.228)
Timestamp:
08/04/08 10:10:24 (16 years ago)
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • StructTupleof

    v0 v1  
     1= Using .tupleof = 
     2 
     3The {{{.tupleof}}} struct property can be used to deal with structs generically. 
     4 
     5== Basic usage == 
     6{{{ 
     7#!d 
     8struct S { int a,b; } 
     9S s; 
     10s.tupleof[1] = 42; 
     11}}} 
     12 
     13== Iterating == 
     14 
     15The index to .tupleof must be const, so you cannot, for instance, do: 
     16{{{ 
     17#!d 
     18struct S { ... } 
     19S s; 
     20for (size_t i = 0; i < s.tupleof.length; ++i) 
     21    Stdout (s.tupleof[i]).newline;      // error: i is not const 
     22}}} 
     23 
     24But it is possible to use foreach: 
     25{{{ 
     26#!d 
     27void 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} 
     34It 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 == 
     38The 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. 
     43static 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 */ 
     63void 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 == 
     74Using the above functions, this can be done: 
     75{{{ 
     76#!d 
     77struct S2 
     78{ 
     79    //char[] first, second, third; 
     80    uint a; 
     81    byte b; 
     82    ulong c; 
     83    float d; 
     84} 
     85 
     86void 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 ||