digitalmars.D.learn - Tuple [] operator
- Christian Manning (17/17) Aug 08 2011 Hi,
- Philippe Sigaud (6/14) Aug 08 2011 The index need to be a compile-time constant, you cannot index a tuple
- Christian Manning (6/26) Aug 08 2011 Ah I didn't know this, thanks. That makes a tuple pretty useless for wha...
- Steven Schveighoffer (25/51) Aug 08 2011 You still can do it, but you have to do it by still using compile-time
- Ali =?iso-8859-1?q?=C7ehreli?= (8/37) Aug 08 2011 Those assignments are now bound at compile time.
- Ali =?iso-8859-1?q?=C7ehreli?= (4/23) Aug 08 2011 I correct myself before Steve does: I missed the "lvalue" above. Steve
- Philippe Sigaud (35/51) Aug 08 2011 Christian, I think Steven even suggested in an article some months ago
- Christian Manning (5/69) Aug 08 2011 I haven't used string mixins before so I suppose this is a good time to
- Steven Schveighoffer (5/57) Aug 08 2011 Sorry, wasn't me...
- Andrej Mitrovic (3/5) Aug 08 2011 Allow me to +1 on that, I've had a need for this (but now I can't
- Philippe Sigaud (5/7) Aug 08 2011 ready.
- Steven Schveighoffer (8/14) Aug 09 2011 Maybe Nick's (something about efficiency vs. flexibility?), mine was abo...
- Philippe Sigaud (5/8) Aug 09 2011 Yes, that was Nick's:
- Dmitry Olshansky (7/23) Aug 08 2011 Your case seems simple, it means you can't index tuple with variable as
Hi, I'm receiving this error with dmd 2.054: "tmp.d(7): Error: no [] operator overload for type Tuple!(int,short)" for the following test case import std.typecons; void main() { auto x = 1; Tuple!(int,short) a; a[0] = 1; a[x] = 2; } If I use a value instead of a variable ie. a[1] = 2; it compiles fine. A search turned up http://d.puremagic.com/issues/show_bug.cgi?id=6273 and http://d.puremagic.com/issues/show_bug.cgi?id=6342 though they specifically mention the use of pure functions which I'm not using. Is this the same problem anyway? Chris
Aug 08 2011
Hi Chris,import std.typecons; void main() { auto x = 1; Tuple!(int,short) a; a[0] = 1; a[x] = 2; } If I use a value instead of a variable ie. a[1] = 2; it compiles fine.The index need to be a compile-time constant, you cannot index a tuple with a runtime value. Try using enum x = 1; Philippe
Aug 08 2011
Philippe Sigaud wrote:Hi Chris,Ah I didn't know this, thanks. That makes a tuple pretty useless for what I was doing now as I was reading the "index" in from a file. Guess I'll find another way round it. Thanks Chrisimport std.typecons; void main() { auto x = 1; Tuple!(int,short) a; a[0] = 1; a[x] = 2; } If I use a value instead of a variable ie. a[1] = 2; it compiles fine.The index need to be a compile-time constant, you cannot index a tuple with a runtime value. Try using enum x = 1; Philippe
Aug 08 2011
On Mon, 08 Aug 2011 15:47:36 -0400, Christian Manning <cmanning999 gmail.com> wrote:Philippe Sigaud wrote:You still can do it, but you have to do it by still using compile-time constants as indexes: auto x = 1; Tuple!(int, short) a; a[0] = 1; switch(x) { case 0: a[0] = 2; break; case 1: a[1] = 2; break; default: assert(0, "does not compute!"); } the point is, the compiler has no idea what the lvalue expression's type should be when you do: a[x] = 1; is it short or int? so the compiler must *know* what type x is at compile time in order for this to be valid. -SteveHi Chris,Ah I didn't know this, thanks. That makes a tuple pretty useless for what I was doing now as I was reading the "index" in from a file. Guess I'll find another way round it.import std.typecons; void main() { auto x = 1; Tuple!(int,short) a; a[0] = 1; a[x] = 2; } If I use a value instead of a variable ie. a[1] = 2; it compiles fine.The index need to be a compile-time constant, you cannot index a tuple with a runtime value. Try using enum x = 1; Philippe
Aug 08 2011
On Mon, 08 Aug 2011 15:55:38 -0400, Steven Schveighoffer wrote:On Mon, 08 Aug 2011 15:47:36 -0400, Christian Manning <cmanning999 gmail.com> wrote:[...]auto x = 1; Tuple!(int, short) a; a[0] = 1; switch(x) { case 0: a[0] = 2; break; case 1: a[1] = 2;Those assignments are now bound at compile time.break; default: assert(0, "does not compute!"); } the point is, the compiler has no idea what the lvalue expression's type should be when you do: a[x] = 1; is it short or int? so the compiler must *know* what type x is at compile time in order for this to be valid.I think it's more import for the compiler to know what type a[x] is. The assignment operators of different types are different. On the other hand, I don't think a short vs int would make a difference when it comes to indexing (it shouldn't anyway).-SteveAli
Aug 08 2011
On Mon, 08 Aug 2011 20:32:03 +0000, Ali Çehreli wrote:I correct myself before Steve does: I missed the "lvalue" above. Steve meant a[x] anyway. Alithe point is, the compiler has no idea what the lvalue expression's type should be when you do: a[x] = 1; is it short or int? so the compiler must *know* what type x is at compile time in order for this to be valid.I think it's more import for the compiler to know what type a[x] is. The assignment operators of different types are different. On the other hand, I don't think a short vs int would make a difference when it comes to indexing (it shouldn't anyway).-SteveAli
Aug 08 2011
On Mon, Aug 8, 2011 at 21:55, Steven Schveighoffer <schveiguy yahoo.com> wr= ote:You still can do it, but you have to do it by still using compile-time constants as indexes: auto x =3D 1; Tuple!(int, short) a; a[0] =3D 1; switch(x) { case 0: =C2=A0 a[0] =3D 2; =C2=A0 break; case 1: =C2=A0 a[1] =3D 2; =C2=A0 break; default: =C2=A0 assert(0, "does not compute!"); }Christian, I think Steven even suggested in an article some months ago that this big switch could be generated at compile time. Steven, do you have a link somewhere? I mean, the tuple length is known as C-T. It's easy to loop on it and build a string of cases. If you wrap it in a function, it becomes a runtime switcher. Proof of concept: import std.typecons; string generateSwitches(T...)() { string result =3D "switch(x) {\n"; foreach(i,Type; T) { result ~=3D "case " ~ to!string(i) ~ ":\n" ~ "fun(tup[" ~ to!string(i) ~ "]);\n" ~ "break;\n"; } return result ~ "default:\n" ~ "assert(0, q{Bad index: } ~ to!string(x));\n}"; } void actOnTuple(alias fun, T...)(int x, ref Tuple!T tup) { mixin(generateSwitches!(T)); } void foo(T)(ref T t) { writeln(t); t =3D T.init;} void main() { auto tup =3D tuple(1, 3.14, "abc"); auto x =3D 1; actOnTuple!foo(x, tup); writeln(tup); } Philippe
Aug 08 2011
Philippe Sigaud wrote:On Mon, Aug 8, 2011 at 21:55, Steven Schveighoffer <schveiguy yahoo.com> wrote:I haven't used string mixins before so I suppose this is a good time to learn! Thanks for the help, Steven and Philippe. ChrisYou still can do it, but you have to do it by still using compile-time constants as indexes: auto x = 1; Tuple!(int, short) a; a[0] = 1; switch(x) { case 0: a[0] = 2; break; case 1: a[1] = 2; break; default: assert(0, "does not compute!"); }Christian, I think Steven even suggested in an article some months ago that this big switch could be generated at compile time. Steven, do you have a link somewhere? I mean, the tuple length is known as C-T. It's easy to loop on it and build a string of cases. If you wrap it in a function, it becomes a runtime switcher. Proof of concept: import std.typecons; string generateSwitches(T...)() { string result = "switch(x) {\n"; foreach(i,Type; T) { result ~= "case " ~ to!string(i) ~ ":\n" ~ "fun(tup[" ~ to!string(i) ~ "]);\n" ~ "break;\n"; } return result ~ "default:\n" ~ "assert(0, q{Bad index: } ~ to!string(x));\n}"; } void actOnTuple(alias fun, T...)(int x, ref Tuple!T tup) { mixin(generateSwitches!(T)); } void foo(T)(ref T t) { writeln(t); t = T.init;} void main() { auto tup = tuple(1, 3.14, "abc"); auto x = 1; actOnTuple!foo(x, tup); writeln(tup); } Philippe
Aug 08 2011
On Mon, 08 Aug 2011 16:50:48 -0400, Philippe Sigaud <philippe.sigaud gmail.com> wrote:On Mon, Aug 8, 2011 at 21:55, Steven Schveighoffer <schveiguy yahoo.com> wrote:Sorry, wasn't me...You still can do it, but you have to do it by still using compile-time constants as indexes: auto x = 1; Tuple!(int, short) a; a[0] = 1; switch(x) { case 0: a[0] = 2; break; case 1: a[1] = 2; break; default: assert(0, "does not compute!"); }Christian, I think Steven even suggested in an article some months ago that this big switch could be generated at compile time. Steven, do you have a link somewhere?I mean, the tuple length is known as C-T. It's easy to loop on it and build a string of cases. If you wrap it in a function, it becomes a runtime switcher. Proof of concept: import std.typecons; string generateSwitches(T...)() { string result = "switch(x) {\n"; foreach(i,Type; T) { result ~= "case " ~ to!string(i) ~ ":\n" ~ "fun(tup[" ~ to!string(i) ~ "]);\n" ~ "break;\n"; } return result ~ "default:\n" ~ "assert(0, q{Bad index: } ~ to!string(x));\n}"; } void actOnTuple(alias fun, T...)(int x, ref Tuple!T tup) { mixin(generateSwitches!(T)); } void foo(T)(ref T t) { writeln(t); t = T.init;} void main() { auto tup = tuple(1, 3.14, "abc"); auto x = 1; actOnTuple!foo(x, tup); writeln(tup); }I like this idea. I think it belongs in phobos somewhere, if not already. -Steve
Aug 08 2011
On 8/8/11, Steven Schveighoffer <schveiguy yahoo.com> wrote:I like this idea. I think it belongs in phobos somewhere, if not already. -SteveAllow me to +1 on that, I've had a need for this (but now I can't remember why, hah!).
Aug 08 2011
Sorry, wasn't me...Oops, sorry.I like this idea. =C2=A0I think it belongs in phobos somewhere, if not al=ready. I remember getting the idea in one of the articles written to win an iPad2 a few months ago. Philippe
Aug 08 2011
On Tue, 09 Aug 2011 01:34:34 -0400, Philippe Sigaud <philippe.sigaud gmail.com> wrote:Maybe Nick's (something about efficiency vs. flexibility?), mine was about array appending, David's and Robert's were about concurrency/parallelism, and Jonathan's was about migrating to std.datetime from std.date. There were also a couple that were suggested but did not officially enter, could have been one of those? -SteveSorry, wasn't me...Oops, sorry.I like this idea. I think it belongs in phobos somewhere, if not already.I remember getting the idea in one of the articles written to win an iPad2 a few months ago.
Aug 09 2011
On Tue, Aug 9, 2011 at 17:43, Steven Schveighoffer <schveiguy yahoo.com> wrote:Maybe Nick's (something about efficiency vs. flexibility?), mine was about array appending, David's and Robert's were about concurrency/parallelism, and Jonathan's was about migrating to std.datetime from std.date.Yes, that was Nick's: [5] Have Your Efficiency, and Flexibility Too by Nick SAbalausky http://www.semitwist.com/articles/EfficientAndFlexible/SinglePage/#part6-3 (Converting a Runtime Value to Compile-Time)
Aug 09 2011
On 08.08.2011 23:27, Christian Manning wrote:Hi, I'm receiving this error with dmd 2.054: "tmp.d(7): Error: no [] operator overload for type Tuple!(int,short)" for the following test case import std.typecons; void main() { auto x = 1; Tuple!(int,short) a; a[0] = 1; a[x] = 2; } If I use a value instead of a variable ie. a[1] = 2; it compiles fine. A search turned up http://d.puremagic.com/issues/show_bug.cgi?id=6273 and http://d.puremagic.com/issues/show_bug.cgi?id=6342 though they specifically mention the use of pure functions which I'm not using. Is this the same problem anyway?Your case seems simple, it means you can't index tuple with variable as index, only with something known at compile time. Replace auto with enum and you are fine, you can even call a function using CTFE to get an index. -- Dmitry Olshansky
Aug 08 2011