Re: Printing Tuple!(...)[] using for loop?

2021-07-02 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/2/21 12:21 AM, Kirill wrote:
I have a `Tuple!(string, ..., string)[] data` that I would like to print 
out:

`a   b   c`
`1   2   3`
`4   5   6`

     Furthermore, I want to be able to print any N rows and M columns of 
that table. For instance:

     `b   c`
     `2   3`
     or
     `1   2   3`
     `4   5   6`

I am using for loops for that:

     // inside some function(rows, cols):
     immutable startFromRow = ...;
     immutable endWithRow = ...;
     immutable startFromCol = ...;
     immutable endWithCol = ...;

     // print data
     for(size_t i = startFromRow; i < endWithRow; i++) {
     for(size_t j = startFromCol; j < endWithCol; j++) {
     writef("%s", data[i][j]);
     }
     writef("\n");
     }

And the compiler puts out the following:
`Error: variable 'j' cannot be read at compile time`

I tried `data[i].expand[j]`, but the same error occurs anyway.

I have two questions:
1. How do I print the contents of a Tuple using for loops? Or any other 
method?

2. What am I missing? How does it actually work under the hood?


So a tuple is really like an unnamed group of variables.

A `Tuple!(int, int, int)` is really like three ints that are all 
separate variables. It's just that they are named via the group. It is 
NOT like an array, it's more like a struct with fields that have indexes 
instead of names.


In order to print them in a loop, based on *runtime* data, you need to 
bridge the gap between runtime and compile time. Why? Because a Tuple 
does not necessarily contain the same types for every value, so `tup[0]` 
might have a different type than `tup[1]`. Because D is strongly-typed, 
you need to access these with *compile-time* indexes, so it knows what 
type you are using.


Imagine you have a struct, and you want to use a runtime string to 
access a given field. This is essentially the same, except it's an index 
and not a name.


A typical way to bridge the gap is to use a switch to validate the 
runtime variable, and then use the compile-time equivalalent to actually 
get the data.


For example, you could write a function like:

```d
void printItem(Tuple!(...) vals, size_t index)
{
theswitch:
final switch(index)
{
   static foreach(ctIdx; 0 .. vals.length) {
case ctIdx: writeln(vals[ctIdx]);
break theswitch;
   }
}
}
```

Now, if you want to just print them in order, without any runtime 
details, you can just use foreach on a tuple and it works (the foreach 
variables are compile-time determined).


-Steve


Re: Printing Tuple!(...)[] using for loop?

2021-07-02 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 2 July 2021 at 04:21:24 UTC, Kirill wrote:

I have a `Tuple!(string, ..., string)[] data`


If there are only strings in the tuple, it could be simplified by 
making it a static array of strings instead. The compile-time 
index issue would go away.


—Bastiaan


Re: Printing Tuple!(...)[] using for loop?

2021-07-02 Thread Alexandru Ermicioi via Digitalmars-d-learn

On Friday, 2 July 2021 at 04:21:24 UTC, Kirill wrote:

...


1. use static foreach for tuple loop.
2. start column and end column should be known at compile time. 
Either make them immutable, or as enum constant, or pass them as 
an template argument.


Tuple is basically a wrapper over built in tuple support from D. 
Check it's insides to se how it is done. So to index a field in a 
tuple you need to know which field you want to access at compile 
time since, each field in a tuple has different size, and cannot 
be indexed at runtime easily.


Best regards,
Alexandru.


Printing Tuple!(...)[] using for loop?

2021-07-01 Thread Kirill via Digitalmars-d-learn
I have a `Tuple!(string, ..., string)[] data` that I would like 
to print out:

`a   b   c`
`1   2   3`
`4   5   6`

Furthermore, I want to be able to print any N rows and M 
columns of that table. For instance:

`b   c`
`2   3`
or
`1   2   3`
`4   5   6`

I am using for loops for that:

// inside some function(rows, cols):
immutable startFromRow = ...;
immutable endWithRow = ...;
immutable startFromCol = ...;
immutable endWithCol = ...;

// print data
for(size_t i = startFromRow; i < endWithRow; i++) {
for(size_t j = startFromCol; j < endWithCol; j++) {
writef("%s", data[i][j]);
}
writef("\n");
}

And the compiler puts out the following:
`Error: variable 'j' cannot be read at compile time`

I tried `data[i].expand[j]`, but the same error occurs anyway.

I have two questions:
1. How do I print the contents of a Tuple using for loops? Or any 
other method?

2. What am I missing? How does it actually work under the hood?

Thanks in advance. Any help is greatly appreciated.