www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - template/mixin magic for to! auto inferring type from variable

reply Chris Katko <ckatko gmail.com> writes:
Is there some way to do:
```D
string[3] data; //strings from some file input, some are ints, 
uints, etc.

auto into!(T)(T value){return to!???(value); } // ???

uint time = into!(data[1]); // We already know this is uint
int priority = into!(data[2]);
```

instead of:
```D
uint time = to!uint(data[1]); // specifying type twice
int priority = to!int(data[2])
```
Feb 01
parent reply Paul Backus <snarwin gmail.com> writes:
On Friday, 2 February 2024 at 07:43:09 UTC, Chris Katko wrote:
 Is there some way to do:
 ```D
 string[3] data; //strings from some file input, some are ints, 
 uints, etc.

 auto into!(T)(T value){return to!???(value); } // ???

 uint time = into!(data[1]); // We already know this is uint
 int priority = into!(data[2]);
 ```

 instead of:
 ```D
 uint time = to!uint(data[1]); // specifying type twice
 int priority = to!int(data[2])
 ```
No, D only does bottom-up type inference, not top down. If you want to avoid repeating the type, use `auto` on the left side: ```d auto time = to!uint(data[1]); auto priority = to!int(data[2]); ```
Feb 02
parent reply Chris Katko <ckatko gmail.com> writes:
On Friday, 2 February 2024 at 21:01:53 UTC, Paul Backus wrote:
 No, D only does bottom-up type inference, not top down.

 If you want to avoid repeating the type, use `auto` on the left 
 side:

 ```d
 auto time = to!uint(data[1]);
 auto priority = to!int(data[2]);
 ```
Okay thanks. It finally clicked what bottom-up/top-down type interference is. The auto solution won't work for a struct however which I'm using: ```D struct procTable{ //contains all the fields inside a file I'm parsing uint time; int priority; string name; // etc } ```
Feb 02
parent reply Paul Backus <snarwin gmail.com> writes:
On Friday, 2 February 2024 at 23:25:37 UTC, Chris Katko wrote:
 The auto solution won't work for a struct however which I'm 
 using:

 ```D
 struct procTable{ //contains all the fields inside a file I'm 
 parsing
    uint time;
    int priority;
    string name;
    // etc
    }
 ```
Maybe you can use `typeof` in that case? ```d procTable pt; pt.time = to!(typeof(pt.time))(data[1]); // etc ``` ...although I guess then you're repeating the field name, which isn't great either. You could avoid the repetition by wrapping the above pattern up in a helper function, though: ```d void convertAssign(Dest, Value)(ref Dest dest, Value value) { import std.conv; dest = to!Dest(value); } void main() { string[3] data = ["100", "-5", "foobar"]; uint time; int priority; string name; time.convertAssign(data[0]); priority.convertAssign(data[1]); name.convertAssign(data[2]); assert(time == 100); assert(priority == -5); assert(name == "foobar"); } ```
Feb 02
parent kdevel <kdevel vogtner.de> writes:
On Saturday, 3 February 2024 at 02:20:13 UTC, Paul Backus wrote:
 On Friday, 2 February 2024 at 23:25:37 UTC, Chris Katko wrote:
 The auto solution won't work for a struct however which I'm 
 using:

 ```D
 struct procTable{ //contains all the fields inside a file I'm 
 parsing
    uint time;
    int priority;
    string name;
    // etc
    }
 ```
Maybe you can use `typeof` in that case? ```d procTable pt; pt.time = to!(typeof(pt.time))(data[1]); // etc ``` ...although I guess then you're repeating the field name, which isn't great either.
```d struct ProcTable2 { uint time; int priority; string name; this (string [this.tupleof.length] initializers) { import std.conv; static foreach (i, field; this.tupleof) field = initializers [i].to!(typeof (field)); } } unittest { string [3] initializers = ["100", "-5", "foobar"]; auto pt2 = ProcTable2 (initializers); with (pt2) { assert(time == 100); assert(priority == -5); assert(name == "foobar"); } } ```
Feb 03