Jeremie Pelletier wrote: > Andrei Alexandrescu wrote: >> Chris Nicholson-Sauls wrote: >>> downs wrote: >>>> >>>> Here is a funny consequence of this amusing fact: >>>> >>>> if you overload opAssign in a struct with lazy T[] dgs..., you can >>>> achieve the following syntax >>>> >>>> >>>>> WithFlag(GL_BLEND, true) = WithDepthMask(false) = tex.With = >>>>> Quads = { >>>>> foreach (i, q; qa) { >>>>> float f = 1f*i / qa.length; Color(1f-f, f, 1f); >>>>> TexCoord(0f, 0f); Vertex(q.points[0]); >>>>> TexCoord(1f, 0f); Vertex(q.points[1]); >>>>> TexCoord(1f, 1f); Vertex(q.points[3]); >>>>> TexCoord(0f, 1f); Vertex(q.points[2]); >>>>> } >>>>> }; >>> >>> That's... just beautiful... >>> >>> -- Chris Nicholson-Sauls >> >> Not getting it... could someone please explain? >> >> Andrei > > From what I get, he has something like this: > > struct WithFlag(int OP, bool enable) { > static void opAssign(T)(lazy T next) { > static if(enable) glEnable(OP); > else glDisable(OP); > next(); > } > } > > struct WithDepthMask(bool enable) { > static void opAssign(T)(lazy T next) { > glDepthMask(enable); > next(); > } > } > > struct Tex { > void opAssign(T)(lazy T next) { > glBindTexture(_tex); > next(); > } > } > > struct Quads { > static void opAssign(T)(lazy T commands) { > glBegin(GL_QUADS); > commands(); > glEnd(); > } > } > > I don't know if thats his exact code, but from what I can remember of gl > from memory it should look like this. > > Jeremie
Very close. There's another workaround required to enable the = {} syntax. The T in question can either be a void, in which case we're assigning a function call, or a void delegate(), in which case we're assigning a subscope. Because the parameter is lazy, in the case of void delegate() we actually have to call it doubly nestedly! This leads to the following code. > const string LazyCall=" > static if (is(T==void)) t(); > else static if (is(T==void delegate())) t()(); > else static assert(false, T.stringof); > "; ... > template PrimitiveScope(string NAME, string WHICH) { > const string PrimitiveScope="struct "~NAME~" { > static void opAssign(T)(lazy T t) { > glBegin("~WHICH~"); scope(exit) glEnd(); > "~LazyCall~" > } > }"; > } ... > mixin(Concat!(MAP!(PrimitiveScope, 2, > "Points", "GL_POINTS", "Lines", "GL_LINES", > "LineLoop", "GL_LINE_LOOP", "LineStrip", "GL_LINE_STRIP", > "Triangles", "GL_TRIANGLES", "TriangleStrip", "GL_TRIANGLE_STRIP", > "TriangleFan", "GL_TRIANGLE_FAN", "Quads", "GL_QUADS", > "QuadStrip", "GL_QUAD_STRIP", "Polygon", "GL_POLYGON" > ))); :deranged grin: I love templates!