Thread overview | |||||
---|---|---|---|---|---|
|
January 07, 2016 Bug or am I getting things wrong | ||||
---|---|---|---|---|
| ||||
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? |
January 07, 2016 Re: Bug or am I getting things wrong | ||||
---|---|---|---|---|
| ||||
Posted in reply to Q. Schroll | 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;
}
}
|
January 07, 2016 Re: Bug or am I getting things wrong | ||||
---|---|---|---|---|
| ||||
Posted in reply to Q. Schroll | 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 |
Copyright © 1999-2021 by the D Language Foundation