Thread overview
template/mixin magic for to! auto inferring type from variable
Feb 03
kdevel
February 02

Is there some way to do:

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:

uint time = to!uint(data[1]); // specifying type twice
int priority = to!int(data[2])
February 02

On Friday, 2 February 2024 at 07:43:09 UTC, Chris Katko wrote:

>

Is there some way to do:

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:

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:

auto time = to!uint(data[1]);
auto priority = to!int(data[2]);
February 02

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:

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:

struct procTable{ //contains all the fields inside a file I'm parsing
   uint time;
   int priority;
   string name;
   // etc
   }
February 03

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:

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?

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:

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");
}
February 03

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:

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?

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.

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");
   }
}