Thread overview
Confusing stuff with arrays
May 11, 2006
Deewiant
May 11, 2006
Deewiant
May 12, 2006
Tom S
May 12, 2006
Deewiant
May 11, 2006
What I was originally trying to do was make an array of type char[][2][][char[]]. However, I needed to initialise it, which is a major pain without array literals. A makeArray template essentially did the trick, but I had to change the array to the type char[][][][char[]], since it seems that arrays of static arrays don't work as they should, at least in this case.

The code (demonstrating a bunch of different issues, I think) below explains it best. Am I just confused, or does it warrant a bug report or two?

(Aside from the array literals feature request, obviously <g>)

---

private import std.stdio;

// cheers to http://www.wikiservice.at/d/wiki.cgi?DocComments/Arrays
template makeArray(T){
	T[] makeArray(T[] newArray...){
		return newArray.dup;
	}
}


void main() {
	// this is fine
	char[][2] foo = makeArray!(char[])("foo", "oof");
	writefln(foo);

	// adding a cast to the above makes it not work, strangely enough
	// "e2ir: cannot cast from char[][] to char[][2]"
	//char[][2] quuux = cast(char[][2])makeArray!(char[])("foo", "oof");
	//writefln(quuux);

	// "cannot assign to static array (__arrayArg2)[0]"

	//char[2][] bar = makeArray!(char[2])("bar", "rab");
	//writefln(bar);

	// this is fine
	char[][][] baz = makeArray!(char[][])(makeArray!(char[])("I want", "array
literals"), makeArray!(char[])("arrr", "ghhh"));
	writefln(baz);

	// "cannot assign to static array (__arrayArg7)[0]"
	// "cannot assign to static array (__arrayArg7)[1]"
	//char[][2][] zot = makeArray!(char[][2])(cast(char[][2])makeArray!(char[])("I
want", "array literals"), cast(char[][2])makeArray!(char[])("arrr", "ghhh"));
	//writefln(zot);

	// sort of works, but usage requires cast(char[][][]), defeating the whole point
	char[][2][] qux =
cast(char[][2][])makeArray!(char[][])(makeArray!(char[])("Array", "literals
today"), makeArray!(char[])("pretty", "please?"));
	// at runtime "Error: std.format formatArg"
	// writefln(qux);
	// outputs garbage
	writefln(qux[0]);
	// these work
	writefln(cast(char[][][])qux);
	writefln((cast(char[][][])qux)[0]);

	// an interesting animal...
	// at runtime "Error: array cast misalignment"
	// why did this work in the above case?
	// it seems that having only one array passed to the outer makeArray causes this
	// is the error here, in the above, or just in all this messing about with evil
casting?
	char[][2][] quux = cast(char[][2][])makeArray!(char[][])(makeArray!(char[])("I
want", "array literals"));
	writefln(quux);
}
May 11, 2006
Of course I managed to forget the most important question for me: is there a reasonable way of doing what I'm trying to do?

I.e. is there a template or whatever which would allow me to properly initialise an array of type char[][2][] with, say, [["Foo", "bar"], ["Bar", "foo"]] inline?
May 12, 2006
Deewiant wrote:
> Of course I managed to forget the most important question for me: is there a
> reasonable way of doing what I'm trying to do?
> 
> I.e. is there a template or whatever which would allow me to properly initialise
> an array of type char[][2][] with, say, [["Foo", "bar"], ["Bar", "foo"]] inline?

Yeah, static arrays are quite nasty to work with, but maybe the following code will be enough for your needs ?


import std.stdio;


char[][] str2(char[] a, char[] b) {
    char[][] s;
    s ~= a;
    s ~= b;
    return s;
}


char[][2][] arrstr2(char[][][] items ...) {
    char[][2][] res;

    foreach (char[][] x; items) {
        assert (2 == x.length);

        char[][2] x2;
        x2[0] = x[0].dup;
        x2[1] = x[1].dup;
        res ~= x2;
    }

    return res;
}


void main() {
    char[][2][] myArr = arrstr2(str2("Foo", "bar"), str2("Bar", "foo"));

    foreach (char[][2] a; myArr) {
        writef("[ ");
        foreach (char[] x; a) {
            writef(x, ' ');
        }
        writefln(']');
    }
}



-- 
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GCS/M d-pu s+: a-->----- C+++$>++++ UL P+ L+ E--- W++ N++ o? K? w++ !O !M V? PS- PE- Y PGP t 5 X? R tv-- b DI- D+ G e>+++ h>++ !r !y
------END GEEK CODE BLOCK------

Tomasz Stachowiak  /+ a.k.a. h3r3tic +/
May 12, 2006
Tom S wrote:
> Deewiant wrote:
>> Of course I managed to forget the most important question for me: is
>> there a
>> reasonable way of doing what I'm trying to do?
>>
>> I.e. is there a template or whatever which would allow me to properly
>> initialise
>> an array of type char[][2][] with, say, [["Foo", "bar"], ["Bar",
>> "foo"]] inline?

Yes, here's the Tom's array logic with some simple template magic (might not be fully optimized, though):

import std.stdio;

template dynamicA(T){
  T[] dynamicA(T[] newArray...){
  	return newArray.dup;
  }
}

template staticA(T, int l) {
	T[l][] staticA(T[][] items...) {
		T[l][] tmp = new T[l][items.length];

		foreach(int i, T[] x; items) {
			assert (l == x.length);
			foreach(int j, T y; x) {
				tmp[j][i] = y.dup;
			}
		}

		return tmp;
	}
}

void main() {
    auto t = staticA!(char[], 2)(dynamicA!(char[])("Foo", "bar"),
dynamicA!(char[])("Bar", "foo"));

    foreach (a; t) {
        writef("[ ");
        foreach (x; a) {
            writef(x, ' ');
        }
        writefln(']');
    }
}

-- 
Jari-Matti
May 12, 2006
Jari-Matti Mäkelä wrote:
> Yes, here's the Tom's array logic with some simple template magic (might not be fully optimized, though):

Kiitokset - thanks, that does the trick.

One small typo was in the template, however: you use tmp[j][i] where it should say tmp[i][j].