## digitalmars.D - DIP Mir1 Draft: Variadic template parameters with the same time.

Ilya Yaroshenko <ilyayaroshenko gmail.com> writes:
```Problem

Most ndslice API accepts variadic list of integers.
The following code example shows how `slice` and `[a, b, c]`
can generate 64 identical functions each.

```
// (1, 1U, 1UL, 1L) x
// (2, 2U, 2UL, 2L) x
// (3, 3U, 3UL, 3L) = 4 ^^ 3 = 64 identical variants
auto cube = slice!double(1, 2, 3);

size_t i;
sizediff_t j;
int k;
uint p;
// 64 identical variants for 64-bit with i, j, k, p
auto v = cube[i, j, k];
```
------------------------

Solution

```
void foo(size_t[] Index...)(Indexes index)
{
...
}
```
```
Sep 29 2016
Ilya Yaroshenko <ilyayaroshenko gmail.com> writes:
```https://github.com/libmir/mir/wiki/Compiler-and-druntime-bugs#dips
```
Sep 29 2016
```On Thursday, 29 September 2016 at 17:24:55 UTC, Ilya Yaroshenko
wrote:
Problem

Most ndslice API accepts variadic list of integers.
The following code example shows how `slice` and `[a, b, c]`
can generate 64 identical functions each.

```
// (1, 1U, 1UL, 1L) x
// (2, 2U, 2UL, 2L) x
// (3, 3U, 3UL, 3L) = 4 ^^ 3 = 64 identical variants
auto cube = slice!double(1, 2, 3);

size_t i;
sizediff_t j;
int k;
uint p;
// 64 identical variants for 64-bit with i, j, k, p
auto v = cube[i, j, k];
```
------------------------

Solution

```
void foo(size_t[] Index...)(Indexes index)
{
...
}
```

This description does not tell me anything.
```
Sep 29 2016
Ilya Yaroshenko <ilyayaroshenko gmail.com> writes:
```On Thursday, 29 September 2016 at 17:56:59 UTC, Stefan Koch wrote:
Solution

```
void foo(size_t[] Index...)(Indexes index)
{
...
}
```

This description does not tell me anything.

Current template argument can be declared as `(Index...)`.
The solutions just allows to specify the type `(size_t[]
Index...)`
```
Sep 29 2016
```On Thursday, 29 September 2016 at 18:37:36 UTC, Ilya Yaroshenko
wrote:
On Thursday, 29 September 2016 at 17:56:59 UTC, Stefan Koch
wrote:
Solution

```
void foo(size_t[] Index...)(Indexes index)
{
...
}
```

This description does not tell me anything.

Current template argument can be declared as `(Index...)`.
The solutions just allows to specify the type `(size_t[]
Index...)`

What do you want to change ?
```
Sep 29 2016
Ilya Yaroshenko <ilyayaroshenko gmail.com> writes:
```On Thursday, 29 September 2016 at 18:49:45 UTC, Stefan Koch wrote:
On Thursday, 29 September 2016 at 18:37:36 UTC, Ilya Yaroshenko
wrote:
On Thursday, 29 September 2016 at 17:56:59 UTC, Stefan Koch
wrote:
Solution

```
void foo(size_t[] Index...)(Indexes index)
{
...
}
```

This description does not tell me anything.

Current template argument can be declared as `(Index...)`.
The solutions just allows to specify the type `(size_t[]
Index...)`

Only for runtime arguments.

What do you want to change ?

`(Index...)` -> `(size_t[] Index...)` // this is about template
arguments, not runtime
```
Sep 29 2016
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
```On 09/29/2016 02:53 PM, Ilya Yaroshenko wrote:
`(Index...)` -> `(size_t[] Index...)` // this is about template
arguments, not runtime

What is the drawback of taking Index... and constraining it with a
template constraint (all must be integral)? We use that in a few places
in Phobos. -- Andrei
```
Sep 29 2016
Ilya Yaroshenko <ilyayaroshenko gmail.com> writes:
```On Thursday, 29 September 2016 at 18:55:07 UTC, Andrei
Alexandrescu wrote:
On 09/29/2016 02:53 PM, Ilya Yaroshenko wrote:
`(Index...)` -> `(size_t[] Index...)` // this is about template
arguments, not runtime

What is the drawback of taking Index... and constraining it
with a template constraint (all must be integral)? We use that
in a few places in Phobos. -- Andrei

This is the same like in current ndslice code.
For 3D cube[i, j, k] 64(!) templates can be generated because
each of i, j, k can be int, uint, size_t, sizediff_t.
```
Sep 29 2016
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
```Ilya Yaroshenko <ilyayaroshenko gmail.com> wrote:
On Thursday, 29 September 2016 at 18:55:07 UTC, Andrei
Alexandrescu wrote:
On 09/29/2016 02:53 PM, Ilya Yaroshenko wrote:
`(Index...)` -> `(size_t[] Index...)` // this is about template
arguments, not runtime

What is the drawback of taking Index... and constraining it
with a template constraint (all must be integral)? We use that
in a few places in Phobos. -- Andrei

This is the same like in current ndslice code.
For 3D cube[i, j, k] 64(!) templates can be generated because
each of i, j, k can be int, uint, size_t, sizediff_t.

Yah, I remember. Can you experiment with arranging things such that all
templates forward to the same backend function that does the work?
```
Sep 29 2016
Ilya Yaroshenko <ilyayaroshenko gmail.com> writes:
```On Thursday, 29 September 2016 at 20:47:35 UTC, Andrei
Alexandrescu wrote:
Ilya Yaroshenko <ilyayaroshenko gmail.com> wrote:
On Thursday, 29 September 2016 at 18:55:07 UTC, Andrei
Alexandrescu wrote:
On 09/29/2016 02:53 PM, Ilya Yaroshenko wrote:
`(Index...)` -> `(size_t[] Index...)` // this is about
template
arguments, not runtime

What is the drawback of taking Index... and constraining it
with a template constraint (all must be integral)? We use
that in a few places in Phobos. -- Andrei

This is the same like in current ndslice code.
For 3D cube[i, j, k] 64(!) templates can be generated because
each of i, j, k can be int, uint, size_t, sizediff_t.

Yah, I remember. Can you experiment with arranging things such
that all templates forward to the same backend function that
does the work?

This already done. But anyway lot of template bloat would note
disappeared. In addition there are inlining and mapSlice
```
Sep 29 2016
Ilya Yaroshenko <ilyayaroshenko gmail.com> writes:
```On Thursday, 29 September 2016 at 20:54:12 UTC, Ilya Yaroshenko
wrote:
On Thursday, 29 September 2016 at 20:47:35 UTC, Andrei
Alexandrescu wrote:
Ilya Yaroshenko <ilyayaroshenko gmail.com> wrote:
On Thursday, 29 September 2016 at 18:55:07 UTC, Andrei
Alexandrescu wrote:
[...]

This is the same like in current ndslice code.
For 3D cube[i, j, k] 64(!) templates can be generated because
each of i, j, k can be int, uint, size_t, sizediff_t.

Yah, I remember. Can you experiment with arranging things such
that all templates forward to the same backend function that
does the work?

This already done. But anyway lot of template bloat would note
disappeared. In addition there are inlining and mapSlice

I am sorry for my terrible English (i am in a dark room now)
```
Sep 29 2016
Timothee Cour via Digitalmars-d <digitalmars-d puremagic.com> writes:
```this works:

void foo(T, size_t n)(T[n] a ...) {...}

However, see this: https://github.com/libmir/mir/issues/337

On Thu, Sep 29, 2016 at 1:57 PM, Ilya Yaroshenko via Digitalmars-d <
digitalmars-d puremagic.com> wrote:

On Thursday, 29 September 2016 at 20:54:12 UTC, Ilya Yaroshenko wrote:

On Thursday, 29 September 2016 at 20:47:35 UTC, Andrei Alexandrescu wrote:

Ilya Yaroshenko <ilyayaroshenko gmail.com> wrote:

On Thursday, 29 September 2016 at 18:55:07 UTC, Andrei Alexandrescu
wrote:

[...]

This is the same like in current ndslice code.
For 3D cube[i, j, k] 64(!) templates can be generated because
each of i, j, k can be int, uint, size_t, sizediff_t.

Yah, I remember. Can you experiment with arranging things such that all
templates forward to the same backend function that does the work?

This already done. But anyway lot of template bloat would note
disappeared. In addition there are inlining and mapSlice

I am sorry for my terrible English (i am in a dark room now)

```
Sep 29 2016
Ilya Yaroshenko <ilyayaroshenko gmail.com> writes:
```On Thursday, 29 September 2016 at 21:06:13 UTC, Timothee Cour
wrote:
this works:

void foo(T, size_t n)(T[n] a ...) {...}

However, see this: https://github.com/libmir/mir/issues/337

On Thu, Sep 29, 2016 at 1:57 PM, Ilya Yaroshenko via
Digitalmars-d < digitalmars-d puremagic.com> wrote:

On Thursday, 29 September 2016 at 20:54:12 UTC, Ilya
Yaroshenko wrote:

On Thursday, 29 September 2016 at 20:47:35 UTC, Andrei
Alexandrescu wrote:

Ilya Yaroshenko <ilyayaroshenko gmail.com> wrote:

[...]

Yah, I remember. Can you experiment with arranging things
such that all templates forward to the same backend function
that does the work?

This already done. But anyway lot of template bloat would
note disappeared. In addition there are inlining and mapSlice

I am sorry for my terrible English (i am in a dark room now)

Thanks! ag0aep6g have suggested the same. I am confused that I
did know this solution. Will open separate thread for
https://github.com/libmir/mir/issues/337.
```
Sep 29 2016
Timothee Cour via Digitalmars-d <digitalmars-d puremagic.com> writes:
```maybe remove the corresponding DIP from
https://github.com/libmir/mir/wiki/Compiler-and-druntime-bugs#dips ?

On Thu, Sep 29, 2016 at 2:19 PM, Ilya Yaroshenko via Digitalmars-d <
digitalmars-d puremagic.com> wrote:

On Thursday, 29 September 2016 at 21:06:13 UTC, Timothee Cour wrote:

this works:

void foo(T, size_t n)(T[n] a ...) {...}

However, see this: https://github.com/libmir/mir/issues/337

On Thu, Sep 29, 2016 at 1:57 PM, Ilya Yaroshenko via Digitalmars-d <
digitalmars-d puremagic.com> wrote:

On Thursday, 29 September 2016 at 20:54:12 UTC, Ilya Yaroshenko wrote:
On Thursday, 29 September 2016 at 20:47:35 UTC, Andrei Alexandrescu
wrote:

Ilya Yaroshenko <ilyayaroshenko gmail.com> wrote:
[...]

Yah, I remember. Can you experiment with arranging things such that
all templates forward to the same backend function that does the work?

This already done. But anyway lot of template bloat would note
disappeared. In addition there are inlining and mapSlice

I am sorry for my terrible English (i am in a dark room now)

Thanks! ag0aep6g have suggested the same. I am confused that I did know
this solution. Will open separate thread for
https://github.com/libmir/mir/issues/337.

```
Sep 29 2016
Ilya Yaroshenko <ilyayaroshenko gmail.com> writes:
```On Thursday, 29 September 2016 at 21:31:11 UTC, Timothee Cour
wrote:
maybe remove the corresponding DIP from
https://github.com/libmir/mir/wiki/Compiler-and-druntime-bugs#dips ?

On Thu, Sep 29, 2016 at 2:19 PM, Ilya Yaroshenko via
Digitalmars-d < digitalmars-d puremagic.com> wrote:

On Thursday, 29 September 2016 at 21:06:13 UTC, Timothee Cour
wrote:

this works:

void foo(T, size_t n)(T[n] a ...) {...}

However, see this: https://github.com/libmir/mir/issues/337

On Thu, Sep 29, 2016 at 1:57 PM, Ilya Yaroshenko via
Digitalmars-d < digitalmars-d puremagic.com> wrote:

On Thursday, 29 September 2016 at 20:54:12 UTC, Ilya
Yaroshenko wrote:
On Thursday, 29 September 2016 at 20:47:35 UTC, Andrei
Alexandrescu
[...]

I am sorry for my terrible English (i am in a dark room now)

Thanks! ag0aep6g have suggested the same. I am confused that I
did know this solution. Will open separate thread for
https://github.com/libmir/mir/issues/337.

Just found an example, where this approach does not work :-(

template transposed(Dimensions...)
if (Dimensions.length)
{
Slice!(N, Range) transposed(size_t N, Range)(auto ref
Slice!(N, Range) slice)
{
...
}
}
```
Sep 29 2016
Steven Schveighoffer <schveiguy yahoo.com> writes:
```On 9/29/16 2:49 PM, Stefan Koch wrote:
On Thursday, 29 September 2016 at 18:37:36 UTC, Ilya Yaroshenko wrote:
On Thursday, 29 September 2016 at 17:56:59 UTC, Stefan Koch wrote:
Solution

```
void foo(size_t[] Index...)(Indexes index)
{
...
}
```

This description does not tell me anything.

Current template argument can be declared as `(Index...)`.
The solutions just allows to specify the type `(size_t[] Index...)`

What do you want to change ?

typesafe variadics as runtime parameters, not compile-time parameters.

-Steve
```
Sep 29 2016
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
```On 09/29/2016 02:37 PM, Ilya Yaroshenko wrote:
On Thursday, 29 September 2016 at 17:56:59 UTC, Stefan Koch wrote:
Solution

```
void foo(size_t[] Index...)(Indexes index)
{
...
}
```

This description does not tell me anything.

Current template argument can be declared as `(Index...)`.
The solutions just allows to specify the type `(size_t[] Index...)`

This feature exists. What am I missing? -- Andrei
```
Sep 29 2016
Ilya Yaroshenko <ilyayaroshenko gmail.com> writes:
```On Thursday, 29 September 2016 at 18:53:26 UTC, Andrei
Alexandrescu wrote:
On 09/29/2016 02:37 PM, Ilya Yaroshenko wrote:
On Thursday, 29 September 2016 at 17:56:59 UTC, Stefan Koch
wrote:
Solution

```
void foo(size_t[] Index...)(Indexes index)
{
...
}
```

This description does not tell me anything.

Current template argument can be declared as `(Index...)`.
The solutions just allows to specify the type `(size_t[]
Index...)`

This feature exists. What am I missing? -- Andrei

No, it does not
---
, void foo(size_t[] I...)(I i)
{

}

void main()
{
foo(1, 2, 3);
}
---
/d812/f719.d(1): Error: found '...' when expecting ')'
/d812/f719.d(1): Error: found ')' when expecting '('
/d812/f719.d(1): Error: basic type expected, not (
/d812/f719.d(1): Error: function declaration without return type.
(Note that constructors are always named 'this')
/d812/f719.d(2): Error: found '{' when expecting ')'
/d812/f719.d(4): Error: semicolon expected following function
declaration
/d812/f719.d(4): Error: unrecognized declaration
```
Sep 29 2016
pineapple <meapineapple gmail.com> writes:
```On Thursday, 29 September 2016 at 18:56:40 UTC, Ilya Yaroshenko
wrote:
No, it does not
---
void foo(size_t[] I...)(I i)
{

}

Using phobos' allSatisfy or a similar template, this can become:

enum isIndex(T) = is(T == size_t);
void foo(I...)(I i) if(allSatisfy!(isIndex, I)){ ... }
```
Sep 29 2016
Ilya Yaroshenko <ilyayaroshenko gmail.com> writes:
```On Thursday, 29 September 2016 at 19:03:00 UTC, pineapple wrote:
On Thursday, 29 September 2016 at 18:56:40 UTC, Ilya Yaroshenko
wrote:
No, it does not
---
void foo(size_t[] I...)(I i)
{

}

Using phobos' allSatisfy or a similar template, this can become:

enum isIndex(T) = is(T == size_t);
void foo(I...)(I i) if(allSatisfy!(isIndex, I)){ ... }

would not work:
auto v = cube[1, 2, 3];
```
Sep 29 2016
Walter Bright <newshound2 digitalmars.com> writes:
```Here's one way to do it:
------
import core.stdc.stdio;

void foo(T)(T[] a ...)
{
printf("%d %d %d\n", a[0], a[1], a[2]);
}

void main()
{
foo(1, 2, 3);
}
-----
C:\cbx>foo
1 2 3
```
Sep 29 2016
Ilya Yaroshenko <ilyayaroshenko gmail.com> writes:
```On Thursday, 29 September 2016 at 20:12:44 UTC, Walter Bright
wrote:
Here's one way to do it:
------
import core.stdc.stdio;

void foo(T)(T[] a ...)
{
printf("%d %d %d\n", a[0], a[1], a[2]);
}

void main()
{
foo(1, 2, 3);
}
-----
C:\cbx>foo
1 2 3

a.length must be known at CT. 99%-100% foreach loops in ndslice
package are CT.
```
Sep 29 2016
ag0aep6g <anonymous example.com> writes:
```On 09/29/2016 10:43 PM, Ilya Yaroshenko wrote:
On Thursday, 29 September 2016 at 20:12:44 UTC, Walter Bright wrote:

[...]
void foo(T)(T[] a ...)
{
printf("%d %d %d\n", a[0], a[1], a[2]);
}

[...]
a.length must be known at CT. 99%-100% foreach loops in ndslice package
are CT.

void foo(size_t n)(size_t[n] a ...) { /* ... */ }
```
Sep 29 2016
Ilya Yaroshenko <ilyayaroshenko gmail.com> writes:
```On Thursday, 29 September 2016 at 20:57:00 UTC, ag0aep6g wrote:
On 09/29/2016 10:43 PM, Ilya Yaroshenko wrote:
On Thursday, 29 September 2016 at 20:12:44 UTC, Walter Bright
wrote:

[...]
void foo(T)(T[] a ...)
{
printf("%d %d %d\n", a[0], a[1], a[2]);
}

[...]
a.length must be known at CT. 99%-100% foreach loops in
ndslice package
are CT.

void foo(size_t n)(size_t[n] a ...) { /* ... */ }

YES! Many Thanks! This is what i need!
```
Sep 29 2016
Ilya Yaroshenko <ilyayaroshenko gmail.com> writes:
```On Thursday, 29 September 2016 at 20:57:00 UTC, ag0aep6g wrote:
On 09/29/2016 10:43 PM, Ilya Yaroshenko wrote:
On Thursday, 29 September 2016 at 20:12:44 UTC, Walter Bright
wrote:

[...]
void foo(T)(T[] a ...)
{
printf("%d %d %d\n", a[0], a[1], a[2]);
}

[...]
a.length must be known at CT. 99%-100% foreach loops in
ndslice package
are CT.

void foo(size_t n)(size_t[n] a ...) { /* ... */ }

Just found an example, where this approach does not work :-(

template transposed(Dimensions...)
if (Dimensions.length)
{
Slice!(N, Range) transposed(size_t N, Range)(auto ref
Slice!(N, Range) slice)
{
...
}
}
```
Sep 29 2016
ag0aep6g <anonymous example.com> writes:
```On 09/29/2016 11:28 PM, Ilya Yaroshenko wrote:
On Thursday, 29 September 2016 at 20:57:00 UTC, ag0aep6g wrote:

[...]
void foo(size_t n)(size_t[n] a ...) { /* ... */ }

Just found an example, where this approach does not work :-(

template transposed(Dimensions...)
if (Dimensions.length)
{
Slice!(N, Range) transposed(size_t N, Range)(auto ref Slice!(N,
Range) slice)
{
...
}
}

When the values themselves are known at compile time, we can convert
them to size_t before generating the function:

----
enum isIndex(T) = is(T == size_t); /* by pineapple */
enum asIndex(size_t value) = value;

template transposed(Dimensions...)
if (Dimensions.length)
{
import std.meta: allSatisfy, staticMap;
static if (allSatisfy!(isIndex, typeof(Dimensions)))
{
void transposed() {} /* simplified for the example */
}
else
{
alias transposed = transposed!(staticMap!(asIndex, Dimensions));
}
}

alias t1 = transposed!(1, 2, 3);
alias t2 = transposed!(1LU, 2LU, 3LU);

static assert(&t1 == &t2); /* passes */
----
```
Sep 29 2016
Ilya Yaroshenko <ilyayaroshenko gmail.com> writes:
```On Thursday, 29 September 2016 at 22:03:36 UTC, ag0aep6g wrote:
On 09/29/2016 11:28 PM, Ilya Yaroshenko wrote:
[...]

[...]
[...]

When the values themselves are known at compile time, we can
convert them to size_t before generating the function:

----
enum isIndex(T) = is(T == size_t); /* by pineapple */
enum asIndex(size_t value) = value;

template transposed(Dimensions...)
if (Dimensions.length)
{
import std.meta: allSatisfy, staticMap;
static if (allSatisfy!(isIndex, typeof(Dimensions)))
{
void transposed() {} /* simplified for the example */
}
else
{
alias transposed = transposed!(staticMap!(asIndex,
Dimensions));
}
}

alias t1 = transposed!(1, 2, 3);
alias t2 = transposed!(1LU, 2LU, 3LU);

static assert(&t1 == &t2); /* passes */
----

Thanks again!
```
Sep 29 2016