digitalmars.D.learn - Bug or am I getting things wrong
- Q. Schroll (34/34) Jan 06 2016 In the listing below the commented line should do exactly the
- John Colvin (47/81) Jan 07 2016 Wow, that's a new reason to hate the comma operator even more
- =?UTF-8?Q?Ali_=c3=87ehreli?= (37/66) Jan 07 2016 I don't see any difference with dmd v2.069.2. Both lines print the
In the listing below the commented line should do exactly the
same thing as the one above.
/// DimArr!(i, T) ==> T[][]...[] i times.
template DimArr(size_t i, T)
{
static if (i == 0) alias DimArr = T;
else alias DimArr = DimArr!(i - 1, T)[];
}
struct Array(T, size_t rk)
if (rk > 1)
{
private size_t[rk] dims;
/+ ... +/
auto toNestedArray() const
{
import std.range : iota;
import std.format : format;
enum dimsIndexed = `%(dims[%d]%|,
%)`.format(dims.length.iota);
auto result = mixin(`new DimArr!(rk, T)(` ~ dimsIndexed ~
`)`);
// auto result = new DimArr!(rk, T)(mixin(dimsIndexed)));
/+ ... +/
return result;
}
}
The one above does exactly what I want, but the lower one only
uses the last dimension for some reason. I found out by using
these pragmas
pragma(msg, "'", dimsIndexed, "'");
pragma(msg, ( new DimArr!(rk, T) ( mixin(dimsIndexed) )
).stringof);
Can someone please tell me what I'm getting wrong here, or is
this a bug?
Jan 06 2016
On Thursday, 7 January 2016 at 07:51:05 UTC, Q. Schroll wrote:
In the listing below the commented line should do exactly the
same thing as the one above.
/// DimArr!(i, T) ==> T[][]...[] i times.
template DimArr(size_t i, T)
{
static if (i == 0) alias DimArr = T;
else alias DimArr = DimArr!(i - 1, T)[];
}
struct Array(T, size_t rk)
if (rk > 1)
{
private size_t[rk] dims;
/+ ... +/
auto toNestedArray() const
{
import std.range : iota;
import std.format : format;
enum dimsIndexed = `%(dims[%d]%|,
%)`.format(dims.length.iota);
auto result = mixin(`new DimArr!(rk, T)(` ~ dimsIndexed
~ `)`);
// auto result = new DimArr!(rk, T)(mixin(dimsIndexed)));
/+ ... +/
return result;
}
}
The one above does exactly what I want, but the lower one only
uses the last dimension for some reason. I found out by using
these pragmas
pragma(msg, "'", dimsIndexed, "'");
pragma(msg, ( new DimArr!(rk, T) ( mixin(dimsIndexed) )
).stringof);
Can someone please tell me what I'm getting wrong here, or is
this a bug?
Wow, that's a new reason to hate the comma operator even more
than I did before!
The expression that you are mixing in is actually a sequence of
sub-expressions seperated by the comma operator, which means each
expression is evaluated and the last one is returned. Remember,
mixins are not textual substitution like C macros. Normally
speaking you get error messages if you forget that, and that's
ok, but here the evil comma operator made a mess of things.
Here's one way to achieve what you want:
/// DimArr!(i, T) ==> T[][]...[] i times.
template DimArr(size_t i, T)
{
static if (i == 0)
alias DimArr = T;
else
alias DimArr = DimArr!(i - 1, T)[];
}
template Repeat(T, size_t N)
{
import std.meta : AliasSeq;
static if (N == 0)
alias Repeat = AliasSeq!();
else
alias Repeat = AliasSeq!(T, Repeat!(T, N-1));
}
auto toTuple(T, size_t N)(T[N] arr)
{
import std.typecons : Tuple;
import std.traits : Unqual;
Tuple!(Repeat!(Unqual!T, N)) tup;
foreach(i, _; tup)
tup[i] = arr[i];
return tup;
}
struct Array(T, size_t rk)
if (rk > 1)
{
private size_t[rk] dims;
/+ ... +/
auto toNestedArray() const
{
auto result = new DimArr!(rk, T)(dims.toTuple.expand);
/+ ... +/
return result;
}
}
Jan 07 2016
On 01/06/2016 11:51 PM, Q. Schroll wrote:
In the listing below the commented line should do exactly the same thing
as the one above.
/// DimArr!(i, T) ==> T[][]...[] i times.
template DimArr(size_t i, T)
{
static if (i == 0) alias DimArr = T;
else alias DimArr = DimArr!(i - 1, T)[];
}
struct Array(T, size_t rk)
if (rk > 1)
{
private size_t[rk] dims;
/+ ... +/
auto toNestedArray() const
{
import std.range : iota;
import std.format : format;
enum dimsIndexed = `%(dims[%d]%|, %)`.format(dims.length.iota);
auto result = mixin(`new DimArr!(rk, T)(` ~ dimsIndexed ~ `)`);
// auto result = new DimArr!(rk, T)(mixin(dimsIndexed)));
/+ ... +/
return result;
}
}
The one above does exactly what I want, but the lower one only uses the
last dimension for some reason. I found out by using these pragmas
pragma(msg, "'", dimsIndexed, "'");
pragma(msg, ( new DimArr!(rk, T) ( mixin(dimsIndexed) ) ).stringof);
Can someone please tell me what I'm getting wrong here, or is this a bug?
I don't see any difference with dmd v2.069.2. Both lines print the
following:
'dims[0], dims[1], dims[2], dims[3], dims[4], dims[5], dims[6], dims[7],
dims[8], dims[9]'
new int[][][][][][][][][][](this.dims[9])
Here is the program:
/// DimArr!(i, T) ==> T[][]...[] i times.
template DimArr(size_t i, T)
{
static if (i == 0) alias DimArr = T;
else alias DimArr = DimArr!(i - 1, T)[];
}
struct Array(T, size_t rk)
if (rk > 1)
{
private size_t[rk] dims;
/+ ... +/
auto toNestedArray() const
{
import std.range : iota;
import std.format : format;
enum dimsIndexed = `%(dims[%d]%|, %)`.format(dims.length.iota);
auto result = mixin(`new DimArr!(rk, T)(` ~ dimsIndexed ~ `)`);
// auto result = new DimArr!(rk, T)(mixin(dimsIndexed));
/+ ... +/
pragma(msg, "'", dimsIndexed, "'");
pragma(msg, ( new DimArr!(rk, T) ( mixin(dimsIndexed) ) ).stringof);
return result;
}
}
void main() {
auto a = Array!(int, 10)();
import std.stdio;
writeln(a.toNestedArray());
}
Ali
Jan 07 2016









John Colvin <john.loughran.colvin gmail.com> 