Derelict2 openGL3 issues
David suggested I start a new thread rather than asking on an old existing one (probably wants to get rid of me). So what I have done is created the most parred back, hello world type program that could run under the GL3 enforcement policies dictated by Derelict2. Fixed function pipeline is out. The vertex positions fit within clip space so there is no need to be sending projection, view or model matricies to the vertex shader, nor any need therein to be altering the vertex positions; they simply get set to gl_Position. The fragment shader assigns red to gl_FragColor. I have read somewhere that vaos are required for GL3 and that vbos hang pointlessly without the chaperone of a vao, regardless, the code can draw either vao or vbo depending on which draw function is not commented out in the loop. The problem is, however, that neither function draws anything. Yet all the initializations are returning true; the SDL window pops up and gets cleared to black. Is there a problem with Derelict2? import std.stdio; import std.string; import std.conv; import derelict.sdl2.sdl; import derelict.opengl3.gl3; pragma(lib, "DerelictUtil.lib"); pragma(lib, "DerelictSDL2.lib"); pragma(lib, "DerelictGL3.lib"); SDL_Window *win; SDL_GLContext context; int w=800, h=600; bool running=true; int shader = 0; uint vao=0, vbo=0; bool loadLibs(){ try{ DerelictSDL2.load(); }catch(Exception e){ writeln("Error loading SDL2 lib"); return false; } try{ DerelictGL3.load(); }catch(Exception e){ writeln("Error loading GL3 lib"); return false; } return true; } bool initSDL(){ if(SDL_Init(SDL_INIT_VIDEO) < 0){ writefln("Error initializing SDL"); return false; } SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); win=SDL_CreateWindow("3Doodle", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, w, h, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN); if(!win){ writefln("Error creating SDL window"); SDL_Quit(); return false; } context=SDL_GL_CreateContext(win); SDL_GL_SetSwapInterval(1); DerelictGL3.reload(); return true; } bool initGL(){ glClearColor(0.0, 0.0, 0.0, 1.0); glViewport(0, 0, w, h); return true; } bool initShaders(){ const string vshader=" #version 330 layout(location = 0) in vec4 pos; void main(void) { gl_Position = pos; } "; const string fshader=" #version 330 void main(void) { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); } "; shader=glCreateProgram(); if(shader == 0){ writeln("Error: GL did not assigh main shader program id"); return false; } int vshad=glCreateShader(GL_VERTEX_SHADER); const char *vptr=toStringz(vshader); glShaderSource(vshad, 1, &vptr, null); glCompileShader(vshad); int status, len; glGetShaderiv(vshad, GL_COMPILE_STATUS, &status); if(status==GL_FALSE){ glGetShaderiv(vshad, GL_INFO_LOG_LENGTH, &len); char[] error=new char[len]; glGetShaderInfoLog(vshad, len, null, cast(char*)error); writeln(error); return false; } int fshad=glCreateShader(GL_FRAGMENT_SHADER); const char *fptr=toStringz(fshader); glShaderSource(fshad, 1, &fptr, null); glCompileShader(fshad); glGetShaderiv(vshad, GL_COMPILE_STATUS, &status); if(status==GL_FALSE){ glGetShaderiv(fshad, GL_INFO_LOG_LENGTH, &len); char[] error=new char[len]; glGetShaderInfoLog(fshad, len, null, cast(char*)error); writeln(error); return false; } glAttachShader(shader, vshad); glAttachShader(shader, fshad); glLinkProgram(shader); glGetShaderiv(shader, GL_LINK_STATUS, &status); if(status==GL_FALSE){ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len); char[] error=new char[len]; glGetShaderInfoLog(shader, len, null, cast(char*)error); writeln(error); return false; } return true; } bool initVAO(){ const float[] v = [ 0.75f, 0.75f, 0.0f, 1.0f, 0.75f, -0.75f, 0.0f, 1.0f, -0.75f, -0.75f, 0.0f, 1.0f]; glGenVertexArrays(1, &vao); if(vao<1){ writeln("Error: GL failed to assign vao id"); return false; } glBindVertexArray(vao); glGenBuffers(1, &vbo);
Re: Formatting dates in std.datetime?
On Friday, April 20, 2012 13:29:34 H. S. Teoh wrote: > Is there a way to format std.datetime.Date objects with a custom format > string? In particular, I'd like to reuse month short names defined in > std.datetime, but it appears that the names are private. I'd really > rather not duplicate them by hand, if there's a way to get them. > > Alternatively, if there's a date formatting function that lets you use > strftime-like format strings, that would work too. Such functionality does not currently exist. It was too much to design it on top of everything else when std.datetime was initially put up for review. There was a lot to it already. There has been some discussion on how to design the format strings ( http://forum.dlang.org/thread/mailman.1806.1324525352.24802.digitalmars- d...@puremagic.com ), but nothing has been actually added to std.datetime yet. My proposed format is very good, I think, but the examples that I chose were nasty enough that a number of people weren't all that happy with it. Stewart's proposal is more user-friendly for the basic stuff, but I don't think that it does as well with the more complicated stuff. I haven't decided what I'm going to do about it yet. It's on my TODO list. As for the month names, they're private and will stay that way. Really, they're an internationalization issue, and having them in the first place was already debatable (they're there primarily because of toSimpleString, which came from Boost and they almost didn't end up in there at all). Once the custom format string stuff has been sorted out, it will end up with a way to indicate that you want either the English abbreviations (which std.datetime currently uses) or the locale-specific ones, but that's the closest that you're ever going to get to have access to them without copying them yourself. - Jonathan M Davis
Formatting dates in std.datetime?
Is there a way to format std.datetime.Date objects with a custom format string? In particular, I'd like to reuse month short names defined in std.datetime, but it appears that the names are private. I'd really rather not duplicate them by hand, if there's a way to get them. Alternatively, if there's a date formatting function that lets you use strftime-like format strings, that would work too. T -- Век живи - век учись. А дураком помрёшь.
Re: Operator overloading
On 20.04.2012 23:33, Xan wrote: Yes, you're wright. So in. But what fails? I reveice these errors and I have no idea what fails! Sorry, the errors are: $ gdmd-4.6 algorisme.d algorisme.d:35: Error: 'this' is only defined in non-static member functions, not __funcliteral1 Easy - _this_ inside of function (T t) { return this.funcio(alg.funcio(t)); } Is not going to fly because there is no way to "store" _this_ in function, use delegates (this is a context and it has to be "copied" -> use delegates). But then you'd have to change to delegate everywhere. (and there is toDelegate function in std.functional, that converts function to delegate) algorisme.d:35: Error: function algorisme.Algorisme!(int,int).Algorisme.opBinary!("*",int).opBinary.__funcliteral1 cannot access frame of function algorisme.Algorisme!(int,int).Algorisme.opBinary!("*",int).opBinary algorisme.d:35: Error: function algorisme.Algorisme!(int,int).Algorisme.opBinary!("*",int).opBinary.__funcliteral1 cannot access frame of function algorisme.Algorisme!(int,int).Algorisme.opBinary!("*",int).opBinary algorisme.d:35: Error: function algorisme.Algorisme!(int,int).Algorisme.opBinary!("*",int).opBinary.__funcliteral1 cannot access frame of function algorisme.Algorisme!(int,int).Algorisme.opBinary!("*",int).opBinary algorisme.d:35: Error: constructor algorisme.Algorisme!(int,int).Algorisme.this (string nom, uint versio, int function(int) funcio) is not callable using argument types (string,int,_error_ function(int t) nothrow @system) algorisme.d:35: Error: cannot implicitly convert expression (__funcliteral1) of type _error_ function(int t) nothrow @system to int function(int) algorisme.d:52: Error: template instance algorisme.Algorisme!(int,int).Algorisme.opBinary!("*",int) error instantiating I update the gist: https://gist.github.com/2429005 -- Dmitry Olshansky
Re: Operator overloading
On Friday, 20 April 2012 at 18:47:14 UTC, Dmitry Olshansky wrote: On 20.04.2012 19:14, Xan wrote: On Friday, 20 April 2012 at 14:18:37 UTC, Dmitry Olshansky wrote: On 20.04.2012 18:10, Xan wrote: What fails if I want to define this: Algorisme!(T,V) opBinary(string op)(Algorisme!(T,U) alg) { Algorisme!(T,V) opBinary(string op, T)(Algorisme!(T,U) alg) { You need to name what T is and that is *sometype*. Anyway I suggest getting a decent book (TDPL). if (op=="*") { static if is conceptually and technically better here. Thanks, Dmitry, for your suggestions, but it does not work too: $ gdmd-4.6 algorisme algorisme.d:54: Error: 'alg' is not of arithmetic type, it is a algorisme.Algorisme!(int,int).Algorisme algorisme.d:54: Error: 'alg2' is not of arithmetic type, it is a algorisme.Algorisme!(int,int).Algorisme I update de gist: https://gist.github.com/2429005 By the other hand, is there any way to put the definition of operator * in the class (not out like I have now)? it should be inside the class. Why would you put it outside and hope it work? What 'this' can refer to in free function? Yes, you're wright. So in. But what fails? I reveice these errors and I have no idea what fails! Please read spec at the very least. http://dlang.org/operatoroverloading.html I read it. It served me as guide. But not I'm in trouble Can you help me fixing the bug! Regards, Xan. Thanks, Xan.
Re: Operator overloading
Yes, you're wright. So in. But what fails? I reveice these errors and I have no idea what fails! Sorry, the errors are: $ gdmd-4.6 algorisme.d algorisme.d:35: Error: 'this' is only defined in non-static member functions, not __funcliteral1 algorisme.d:35: Error: function algorisme.Algorisme!(int,int).Algorisme.opBinary!("*",int).opBinary.__funcliteral1 cannot access frame of function algorisme.Algorisme!(int,int).Algorisme.opBinary!("*",int).opBinary algorisme.d:35: Error: function algorisme.Algorisme!(int,int).Algorisme.opBinary!("*",int).opBinary.__funcliteral1 cannot access frame of function algorisme.Algorisme!(int,int).Algorisme.opBinary!("*",int).opBinary algorisme.d:35: Error: function algorisme.Algorisme!(int,int).Algorisme.opBinary!("*",int).opBinary.__funcliteral1 cannot access frame of function algorisme.Algorisme!(int,int).Algorisme.opBinary!("*",int).opBinary algorisme.d:35: Error: constructor algorisme.Algorisme!(int,int).Algorisme.this (string nom, uint versio, int function(int) funcio) is not callable using argument types (string,int,_error_ function(int t) nothrow @system) algorisme.d:35: Error: cannot implicitly convert expression (__funcliteral1) of type _error_ function(int t) nothrow @system to int function(int) algorisme.d:52: Error: template instance algorisme.Algorisme!(int,int).Algorisme.opBinary!("*",int) error instantiating I update the gist: https://gist.github.com/2429005
Re: Operator overloading
On 20.04.2012 19:14, Xan wrote: On Friday, 20 April 2012 at 14:18:37 UTC, Dmitry Olshansky wrote: On 20.04.2012 18:10, Xan wrote: What fails if I want to define this: Algorisme!(T,V) opBinary(string op)(Algorisme!(T,U) alg) { Algorisme!(T,V) opBinary(string op, T)(Algorisme!(T,U) alg) { You need to name what T is and that is *sometype*. Anyway I suggest getting a decent book (TDPL). if (op=="*") { static if is conceptually and technically better here. Thanks, Dmitry, for your suggestions, but it does not work too: $ gdmd-4.6 algorisme algorisme.d:54: Error: 'alg' is not of arithmetic type, it is a algorisme.Algorisme!(int,int).Algorisme algorisme.d:54: Error: 'alg2' is not of arithmetic type, it is a algorisme.Algorisme!(int,int).Algorisme I update de gist: https://gist.github.com/2429005 By the other hand, is there any way to put the definition of operator * in the class (not out like I have now)? it should be inside the class. Why would you put it outside and hope it work? What 'this' can refer to in free function? Please read spec at the very least. http://dlang.org/operatoroverloading.html Thanks, Xan. -- Dmitry Olshansky
Re: primitive type operator overload
On Fri, Apr 20, 2012 at 07:12:41PM +0200, Mafi wrote: > Am 20.04.2012 18:41, schrieb bearophile: > >Dominic Jones: > > > >>I want to overload a primitive type operator so that I can do > >>something like > >> > >>double a; > >>myStruct b; > >>writeln(a + b); > > > >You can't overload the operator of a primitive, but binary operators > >come in left and right versions: > ... > > > >Bye, > >bearophile > > Shouldn't a consequence of UFCS be that you can overload binary > operators for primitives, as should global overloads (like in C++). UFCS only kicks in if no matching method is found for the given type. So UFCS can be used to provide "default" implementations for when an operator is not defined for a given type, but the operator defined by the type takes precedence over UFCS. T -- "How are you doing?" "Doing what?"
Re: Operator overloading
On Friday, April 20, 2012 15:37:57 Xan wrote: > Thanks, Jonathan. I suppose with 'if' (dynamic), it generates > Exception if we call with other operator than '*', isn't? Exception? No. You get a compilation error. You should read http://dlang.org/template.html#Constraint http://dlang.org/version.html#staticif Template constraints are used to indicate what will and won't compile with a template and can be used to overload templates. For instance, with auto opBinary(string op)(MyType mt) if(op == "+" || op == "-") {...} auto opBinary(string op)(MyType mt) if(op == "*" || op == "/") {...} the first function would work with + and -, whereas the second would work with * and /, and those are the only overloads for opBinary, and you tried to compile with another binary operator, you'd get a compilation error. It's quite typical to do stuff like auto MyType(string op)(MyType mt) if(op == "+" || op == "-' || op == "*" || op == "/") { return MyType(mixin("this.value " ~ op ~ " mt.value")); } You use static if when you want a section of code to be different based on some condition. So, you could do something like auto MyType(string op)(MyType mt) if(op == "+" || op == "-' || op == "*" || op == "/") { static if(op == "/") enforce(mt.value != 0, "Error: Division by zero!"); return MyType(mixin("this.value " ~ op ~ " mt.value")); } The problem with your example Algorisme!(U,V) opBinary(string op)(Algorisme!(U,V) alg) { static if (op=="*") return new Algorisme!(U,V)("composició", this.versio+alg.versio, this.funcio); } what happens when you try and compile with an operator other than *. When it's *, you end up with a function looking like Algorisme!(U,V) opBinary(string op)(Algorisme!(U,V) alg) { return new Algorisme!(U,V)("composició", this.versio+alg.versio, this.funcio); } but when it's anything else, you get a function looking like Algorisme!(U,V) opBinary(string op)(Algorisme!(U,V) alg) { } It has no return value and won't compile, giving you an error about returning void or something similar. If at all possible, you should always have a template constraint on a template which restricts it to arguments which will work with that template. You can then further specialize sections of it using static if, but if you use static if only, then you get nasty compilation errors when you misuse the template. Also, you can't overload templates based on static if, so if you need to have mulitple overloads of a template, you _need_ to use template constraints. - Jonathan M Davis
Re: primitive type operator overload
Am 20.04.2012 18:41, schrieb bearophile: Dominic Jones: I want to overload a primitive type operator so that I can do something like double a; myStruct b; writeln(a + b); You can't overload the operator of a primitive, but binary operators come in left and right versions: ... Bye, bearophile Shouldn't a consequence of UFCS be that you can overload binary operators for primitives, as should global overloads (like in C++).
Re: variadic mixin templates and other stuff
On Friday, 20 April 2012 at 14:57:03 UTC, Martin Drasar wrote: On 20.4.2012 16:09, Timon Gehr wrote: I tried but it still refuses to compile: string interfaceGuid(string ifaceName) { return ifaceName ~ "Guid"; } mixin template EXPOSE_INTERFACES(T...)(T args) Try this: mixin template EXPOSE_INTERFACES(T...) { void QueryInterface(ref IComponent comp, string guid) { foreach (arg; args) and this: foreach (arg; T) { if (mixin(interfaceGuid(arg)) == guid) {} } } } component.d(6): members of template declaration expected component.d(6): Declaration expected, not '(' component.d(10): no identifier for declarator args component.d(10): semicolon expected, not ')' component.d(10): Declaration expected, not ')' I am compiling it with dmd v2.058. Martin John
Re: primitive type operator overload
Dominic Jones: I want to overload a primitive type operator so that I can do something like double a; myStruct b; writeln(a + b); You can't overload the operator of a primitive, but binary operators come in left and right versions: http://dlang.org/operatoroverloading.html#Binary a.opBinary!("op")(b) b.opBinaryRight!("op")(a) so adding an inverse "+" operator inside myStruct is possible. Bye, bearophile
primitive type operator overload
Hello, I want to overload a primitive type operator so that I can do something like double a; myStruct b; writeln(a + b); but have no idea how to do it. Something similar(?) is already implemented in the language, i.e. double x; double[] y; writeln(x + y); but after searching the dmd2/src, what I found didn't offer any help. -Dominic Jones
Re: Operator overloading
On Friday, 20 April 2012 at 14:18:37 UTC, Dmitry Olshansky wrote: On 20.04.2012 18:10, Xan wrote: What fails if I want to define this: Algorisme!(T,V) opBinary(string op)(Algorisme!(T,U) alg) { Algorisme!(T,V) opBinary(string op, T)(Algorisme!(T,U) alg) { You need to name what T is and that is *sometype*. Anyway I suggest getting a decent book (TDPL). if (op=="*") { static if is conceptually and technically better here. Thanks, Dmitry, for your suggestions, but it does not work too: $ gdmd-4.6 algorisme algorisme.d:54: Error: 'alg' is not of arithmetic type, it is a algorisme.Algorisme!(int,int).Algorisme algorisme.d:54: Error: 'alg2' is not of arithmetic type, it is a algorisme.Algorisme!(int,int).Algorisme I update de gist: https://gist.github.com/2429005 By the other hand, is there any way to put the definition of operator * in the class (not out like I have now)? Thanks, Xan.
Re: variadic mixin templates and other stuff
On 20.4.2012 16:09, Timon Gehr wrote: Thanks Timon for the answer. >> My questions are following: >> - can mixin templates be used this way? > > They can only mixin declarations. > >> - why are they complaining? > > Because if is a statement and not a declaration. Ok. >> - is there a better way to do this other than reproducing C macros? >> > > Inline EXPOSE_INTERFACE into EXPOSE_INTERFACES and it'll work. I tried but it still refuses to compile: string interfaceGuid(string ifaceName) { return ifaceName ~ "Guid"; } mixin template EXPOSE_INTERFACES(T...)(T args) { void QueryInterface(ref IComponent comp, string guid) { foreach (arg; args) { if (mixin(interfaceGuid(arg)) == guid) {} } } } component.d(6): members of template declaration expected component.d(6): Declaration expected, not '(' component.d(10): no identifier for declarator args component.d(10): semicolon expected, not ')' component.d(10): Declaration expected, not ')' I am compiling it with dmd v2.058. Martin
Re: Operator overloading
On Friday, 20 April 2012 at 14:10:31 UTC, Xan wrote: What fails if I want to define this: Algorisme!(T,V) opBinary(string op)(Algorisme!(T,U) alg) { if (op=="*") { //fer la funció composicio return new Algorisme!(T,V)("Composició de "~this.nom ~ " i " ~ alg.nom, 1, function(T t) { return this.funcio(alg.funcio(t)); } ); } } } within my class Algorisme(U,V) { string nom; uint versio; alias V function (U) Funcio; Funcio funcio; ... } ? I want to combine Algorisme(U,V) and Algorisme(T,V) with operator. Is it possible? The errors I get are: gdmd-4.6 algorisme algorisme.d:32: Error: undefined identifier T, did you mean variable E? algorisme.d:51: Error: 'alg' is not of arithmetic type, it is a algorisme.Algorisme!(int,int).Algorisme algorisme.d:51: Error: 'alg2' is not of arithmetic type, it is a algorisme.Algorisme!(int,int).Algorisme Thanks in advance, Xan. The full code is here: https://gist.github.com/2429005 (I put the code out of the class and I drop one error)
Re: Operator overloading
On 20.04.2012 18:10, Xan wrote: What fails if I want to define this: Algorisme!(T,V) opBinary(string op)(Algorisme!(T,U) alg) { Algorisme!(T,V) opBinary(string op, T)(Algorisme!(T,U) alg) { You need to name what T is and that is *sometype*. Anyway I suggest getting a decent book (TDPL). if (op=="*") { static if is conceptually and technically better here. -- Dmitry Olshansky
Re: Operator overloading
What fails if I want to define this: Algorisme!(T,V) opBinary(string op)(Algorisme!(T,U) alg) { if (op=="*") { //fer la funció composicio return new Algorisme!(T,V)("Composició de "~this.nom ~ " i " ~ alg.nom, 1, function(T t) { return this.funcio(alg.funcio(t)); } ); } } } within my class Algorisme(U,V) { string nom; uint versio; alias V function (U) Funcio; Funcio funcio; ... } ? I want to combine Algorisme(U,V) and Algorisme(T,V) with operator. Is it possible? The errors I get are: gdmd-4.6 algorisme algorisme.d:32: Error: undefined identifier T, did you mean variable E? algorisme.d:51: Error: 'alg' is not of arithmetic type, it is a algorisme.Algorisme!(int,int).Algorisme algorisme.d:51: Error: 'alg2' is not of arithmetic type, it is a algorisme.Algorisme!(int,int).Algorisme Thanks in advance, Xan.
Re: variadic mixin templates and other stuff
On 04/20/2012 03:23 PM, Martin Drasar wrote: Hi, I am migrating a C++ project to D and I have hit a roadblock that I hope you might help me with. My code is heavily inspired by the COM architecture, so I have naturally take a look at std/c/windows/com.d, just to find out that it does not contain all I need. In the C++ code I have several interfaces and a class. The class inherits from these interfaces, exposes some of them and it is possible to get one interface from another using the QueryInterface function by supplying correct GUID: class C : IA, IB, IC { EXPOSE_INTERFACE(IA, IC); ... } where EXPOSE_INTERFACE is macro that expands to something like this: void QueryInterface (IComponent** comp, GUID* guid) { ... if (guid == IAGuid) *comp = ...some casting if (guid == IBGuid) *comp = ...some casting ... } So I was thinking that in D I could use mixin templates with variadic arguments, so I tried something like that: string interfaceGuid(string ifaceName) { return ifaceName ~ "Guid"; } mixin template EXPOSE_INTERFACE(string ifaceName) { if (mixin(interfaceGuid(ifaceName)) == guid) { ... some casting } } mixin template EXPOSE_INTERFACES(T...)(T args) { void QueryInterface(ref IComponent comp, string guid) { foreach (arg; args) { mixin EXPOSE_INTERFACE!arg; } } } But I got this: component.d(8): Declaration expected, not 'if' component.d(15): no identifier for declarator args component.d(15): semicolon expected, not ')' component.d(15): Declaration expected, not ')' component.d(19): unrecognized declaration Then I got confused and realized that my D is as sharp as is my German - studied it for some time, but still has a problem to order a bread in a store... My questions are following: - can mixin templates be used this way? They can only mixin declarations. - why are they complaining? Because if is a statement and not a declaration. - is there a better way to do this other than reproducing C macros? Inline EXPOSE_INTERFACE into EXPOSE_INTERFACES and it'll work.
Re: Operator overloading
On Thursday, 19 April 2012 at 20:59:05 UTC, Jonathan M Davis wrote: On Thursday, April 19, 2012 21:14:43 Xan wrote: Hi, I read http://dlang.org/operatoroverloading.html but in my code it does not work. I tried to overload '*' binary operator in my class Algorisme: [...] class Algorisme(U,V) { string nom; uint versio; alias V function (U) Funcio; Funcio funcio; this(string nom, uint versio, Funcio funcio) { try { this.nom = nom; this.versio = versio; this.funcio = funcio; } catch { writeln("Error"); } } string toString() { return format("%s (versió %s): %s -> %s", nom, versio, typeid(U), typeid(V)); } Algorisme(U, V) opBinary(string op) (Algorisme(U, V) alg) { static if (op == '*') return new Algorisme(U,V)("composició", this.versio+alg.versio, this.funcio); } } [...] but I receive these errors: $ gdmd-4.6 algorisme.d algorisme.d:31: function declaration without return type. (Note that constructors are always named 'this') algorisme.d:31: no identifier for declarator Algorisme(U, V) algorisme.d:31: semicolon expected following function declaration algorisme.d:31: function declaration without return type. (Note that constructors are always named 'this') algorisme.d:31: function declaration without return type. (Note that constructors are always named 'this') algorisme.d:31: found 'alg' when expecting ')' algorisme.d:31: no identifier for declarator opBinary(Algorisme(U, V)) algorisme.d:31: semicolon expected following function declaration algorisme.d:31: Declaration expected, not ')' algorisme.d:35: unrecognized declaration Why it fails? Anyone could help me? Use a template constraint rather than a static if. As it stands, any operator other than "*" will result in a function with no return statement. Algorisme opBinary(string op)(Algorisme alg) if(op == "*") { return new Algorisme("composició", this.versio+alg.versio, this.funcio); } - Jonathan M Davis Thanks, Jonathan. I suppose with 'if' (dynamic), it generates Exception if we call with other operator than '*', isn't? Thanks, Xan.
Re: Allow empty field function arguments for default?
ixid: fun( , 4, ); //Modifies b fun( , , 5); //Modifies c for when you want to call fun with other fields not being default? This would seem more flexible and pretty clear what is intended. I think that for the programmer's eye it's easy to miss one or more of those commas, when reading code. So to me something like this seems significantly less bug-prone: fun(void, 4, void); // Modifies b fun(void, void, 5); // Modifies c Bye, bearophile
variadic mixin templates and other stuff
Hi, I am migrating a C++ project to D and I have hit a roadblock that I hope you might help me with. My code is heavily inspired by the COM architecture, so I have naturally take a look at std/c/windows/com.d, just to find out that it does not contain all I need. In the C++ code I have several interfaces and a class. The class inherits from these interfaces, exposes some of them and it is possible to get one interface from another using the QueryInterface function by supplying correct GUID: class C : IA, IB, IC { EXPOSE_INTERFACE(IA, IC); ... } where EXPOSE_INTERFACE is macro that expands to something like this: void QueryInterface (IComponent** comp, GUID* guid) { ... if (guid == IAGuid) *comp = ...some casting if (guid == IBGuid) *comp = ...some casting ... } So I was thinking that in D I could use mixin templates with variadic arguments, so I tried something like that: string interfaceGuid(string ifaceName) { return ifaceName ~ "Guid"; } mixin template EXPOSE_INTERFACE(string ifaceName) { if (mixin(interfaceGuid(ifaceName)) == guid) { ... some casting } } mixin template EXPOSE_INTERFACES(T...)(T args) { void QueryInterface(ref IComponent comp, string guid) { foreach (arg; args) { mixin EXPOSE_INTERFACE!arg; } } } But I got this: component.d(8): Declaration expected, not 'if' component.d(15): no identifier for declarator args component.d(15): semicolon expected, not ')' component.d(15): Declaration expected, not ')' component.d(19): unrecognized declaration Then I got confused and realized that my D is as sharp as is my German - studied it for some time, but still has a problem to order a bread in a store... My questions are following: - can mixin templates be used this way? - why are they complaining? - is there a better way to do this other than reproducing C macros? Thanks, Martin
Re: D, Derelict2, and OpenGL
Am 20.04.2012 00:34, schrieb Stephen Jones: In the same vein, I have getting nothing on the screen when there should be rendered a red triangle. The vertex positions are those used by McKeeson http://www.arcsynthesis.org/gltut/, being in ndc fall within the frustum. The code for setting up vao and shaders is: module ShaderHub; import std.stdio; import std.string; import derelict.opengl3.gl3; class ShaderHub{ private bool ok=true; private GLuint shad=0, vshad=0, fshad=0; private int voff=0; private GLuint vbo=0, vao=0; const float[] v = [ 0.75f, 0.75f, 0.0f, 1.0f, 0.75f, -0.75f, 0.0f, 1.0f, -0.75f, -0.75f, 0.0f, 1.0f]; public this(){ immutable string vshader = ` #version 330 layout(location = 1) in vec4 pos; void main(void) { gl_Position = pos; } `; immutable string fshader = ` #version 330 void main(void) { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); } `; shad=glCreateProgram(); if(shad==0){ writeln("Error: GL did not assigh main shader program id"); ok=false; } vshad=glCreateShader(GL_VERTEX_SHADER); const char *vptr=toStringz(vshader); glShaderSource(vshad, 1, &vptr, null); glCompileShader(vshad); int status, len; glGetShaderiv(vshad, GL_COMPILE_STATUS, &status); if(status==GL_FALSE){ glGetShaderiv(vshad, GL_INFO_LOG_LENGTH, &len); char[] error=new char[len]; glGetShaderInfoLog(vshad, len, null, cast(char*)error); writeln(error); ok=false; } fshad=glCreateShader(GL_FRAGMENT_SHADER); const char *fptr=toStringz(fshader); glShaderSource(fshad, 1, &fptr, null); glCompileShader(fshad); glGetShaderiv(vshad, GL_COMPILE_STATUS, &status); if(status==GL_FALSE){ glGetShaderiv(fshad, GL_INFO_LOG_LENGTH, &len); char[] error=new char[len]; glGetShaderInfoLog(fshad, len, null, cast(char*)error); writeln(error); ok=false; } glAttachShader(shad, vshad); glAttachShader(shad, fshad); glLinkProgram(shad); glGetShaderiv(shad, GL_LINK_STATUS, &status); if(status==GL_FALSE){ glGetShaderiv(shad, GL_INFO_LOG_LENGTH, &len); char[] error=new char[len]; glGetShaderInfoLog(shad, len, null, cast(char*)error); writeln(error); ok=false; } glGenVertexArrays(1, &vao); if(vao<1){ writeln("Error: GL failed to assign vao id"); ok=false; } glBindVertexArray(vao); glGenBuffers(1, &vbo); if(vbo<1){ writeln("Error: GL failed to assign vbo id"); ok=false; } glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, v.length * GL_FLOAT.sizeof, &v[0], GL_STATIC_DRAW); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, cast(void*)voff); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); } public void draw(){ glUseProgram(shad); writeln(glGetAttribLocation(shad, "pos"));//prints 1 glBindVertexArray(vao); glDrawArrays(GL_TRIANGLES, 0, 6); glBindVertexArray(0); glUseProgram(0); } } //__ the code for setting up openGL3 is: import std.stdio; import derelict.sdl2.sdl; import derelict.opengl3.gl3; import EventHub; import ExposeApp; pragma(lib, "DerelictUtil.lib"); pragma(lib, "DerelictSDL2.lib"); pragma(lib, "DerelictGL3.lib"); class App{ private ExposeApp funcPtrs; private EventHub ehub; private SDL_Window *win; private SDL_GLContext context; private int w=600, h=480, fov=55; private bool running=true; public this(){ if(!initSDL()){ writeln("Error initializing SDL"); SDL_Quit(); } initGL(); funcPtrs=new ExposeApp(); funcPtrs.stop=&stopLoop; funcPtrs.grabMouse=&grabMouse; funcPtrs.releaseMouse=&releaseMouse; ehub=new EventHub(funcPtrs); while(running){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); ehub.tick(); SDL_GL_SwapWindow(win); } SDL_GL_DeleteContext(context); SDL_DestroyWindow(win); SDL_Quit(); } private void stopLoop(){ running=false; } private void grabMouse(){ SDL_ShowCursor(SDL_DISABLE); SDL_SetWindowGrab(win, SDL_TRUE); } private void releaseMouse(){ SDL_ShowCursor(SDL_ENABLE); SDL_SetWindowGrab(win, SDL_FALSE); } private bool initSDL(){ if(SDL_Init(SDL_INIT_VIDEO)< 0){ writefln("Error initializing SDL"); SDL_Quit(); return false; } SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); win=SDL_CreateWindow("3Doodle", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, w, h, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN); if(!win){ writefln("Error creating SDL window"); SDL_Quit(); return false; } context=SDL_GL_CreateContext(win); SDL_GL_SetSwapInterval(1); DerelictGL3.reload(); return true; } private void initGL(){ resize(w, h); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glDepthFunc(GL_LEQUAL); glClearColor(0.0, 0.0, 0.0, 1.0); glClearDepth(1.0); glCullFace(GL_BACK); glFrontFace(GL_CCW); } private void resize(int w, int h){ //this will contain the makings of the projection matrix, which we go into next tut glViewport(0, 0, w, h); } } void main(){ try{ DerelictSDL2.load(); }catch(Exception e){ writeln("Error loading SDL2 lib"); } try{ DerelictGL3.load();
Re: Allow empty field function arguments for default?
On Friday, 20 April 2012 at 11:09:30 UTC, Jacob Carlborg wrote: On 2012-04-20 11:17, Christophe wrote: "Jakob Ovrum" , dans le message (digitalmars.D.learn:34948), a écrit : On Thursday, 19 April 2012 at 18:34:41 UTC, Jacob Carlborg wrote: Named arguments would probably be better for this. fun(c = 5); Maybe so, but `fun(c = 5);` is not an additive change, while the OP's suggestion actually is. How about int c; fun(c = 5); ? I don't know. Default arguments would probably take precedence perhaps. That is exactly the problem though, it can silently change the behaviour of existing code. It is the worst kind of breaking change, hence I don't think it will ever be in D in this form, much less the current iteration of the language.
Re: Allow empty field function arguments for default?
On Friday, 20 April 2012 at 09:17:18 UTC, trav...@phare.normalesup.org (Christophe) wrote: "Jakob Ovrum" , dans le message (digitalmars.D.learn:34948), a écrit : On Thursday, 19 April 2012 at 18:34:41 UTC, Jacob Carlborg wrote: Named arguments would probably be better for this. fun(c = 5); Maybe so, but `fun(c = 5);` is not an additive change, while the OP's suggestion actually is. How about int c; fun(c = 5); ? That is what I was talking about. (did you mean to quote the post I quoted, perhaps?)
Re: pure functions/methods
Namespace: So only GDC optimized "pure" functions at all? I've seen DMD performs some optimizations with "strongly pure" functions that return integral values. If you have code like: int sqr(in int x) pure nothrow { return x * x; } int y = ... auto r = sqr(y) + sqr(y); I think DMD replaces that with this, even when inlining is disabled: int y = ... auto r = sqr(y) * 2; Bye, bearophile
Re: Allow empty field function arguments for default?
On 2012-04-20 11:17, Christophe wrote: "Jakob Ovrum" , dans le message (digitalmars.D.learn:34948), a écrit : On Thursday, 19 April 2012 at 18:34:41 UTC, Jacob Carlborg wrote: Named arguments would probably be better for this. fun(c = 5); Maybe so, but `fun(c = 5);` is not an additive change, while the OP's suggestion actually is. How about int c; fun(c = 5); ? I don't know. Default arguments would probably take precedence perhaps. -- /Jacob Carlborg
Re: pure functions/methods
On Friday, 20 April 2012 at 09:55:28 UTC, Timon Gehr wrote: On 04/20/2012 10:06 AM, Namespace wrote: The sense of pure functions isn't clear to me. What is the advantage of pure functions / methods? 1. It enables stateless reasoning about program parts. 2. It enables certain compiler optimizations. I inform the compiler with "const" that this method does not change the current object, and therefore he can optimize (at least in C++) this method. const on a method does not give any guarantees in C++. A C++ compiler cannot perform optimizations based on a const method. How and what optimized the compiler if i have "pure" or "const pure" functions / methods? DMD does not do a lot there currently. This article seems to discuss what GCC does with pure functions: http://lwn.net/Articles/285332/ So only GDC optimized "pure" functions at all?
Re: pure functions/methods
On 04/20/2012 10:06 AM, Namespace wrote: The sense of pure functions isn't clear to me. What is the advantage of pure functions / methods? 1. It enables stateless reasoning about program parts. 2. It enables certain compiler optimizations. I inform the compiler with "const" that this method does not change the current object, and therefore he can optimize (at least in C++) this method. const on a method does not give any guarantees in C++. A C++ compiler cannot perform optimizations based on a const method. How and what optimized the compiler if i have "pure" or "const pure" functions / methods? DMD does not do a lot there currently. This article seems to discuss what GCC does with pure functions: http://lwn.net/Articles/285332/
Re: Allow empty field function arguments for default?
"Jakob Ovrum" , dans le message (digitalmars.D.learn:34948), a écrit : > On Thursday, 19 April 2012 at 18:34:41 UTC, Jacob Carlborg wrote: >> >> Named arguments would probably be better for this. >> >> fun(c = 5); > > Maybe so, but `fun(c = 5);` is not an additive change, while the > OP's suggestion actually is. How about int c; fun(c = 5); ? -- Christophe
Re: pure functions/methods
On 4/20/2012 3:06 AM, Namespace wrote: The sense of pure functions isn't clear to me. What is the advantage of pure functions / methods? I inform the compiler with "const" that this method does not change the current object, and therefore he can optimize (at least in C++) this method. How and what optimized the compiler if i have "pure" or "const pure" functions / methods? Simplest explanation I can think of is: a const function of a class can't modify its own classes data a pure function can't modify any data, or call other functions that are not also pure (though there are exceptions)
Re: pure functions/methods
On 4/20/12 4:06 PM, Namespace wrote: The sense of pure functions isn't clear to me. What is the advantage of pure functions / methods? I inform the compiler with "const" that this method does not change the current object, and therefore he can optimize (at least in C++) this method. How and what optimized the compiler if i have "pure" or "const pure" functions / methods? As far as I know pure functions always return the same results given the same arguments. They also don't cause any side effect. http://en.wikipedia.org/wiki/Pure_function Many invocations of a pure function can be executed in parallel because they don't have side effects. There's also a chance of caching their result since it only depends on the value of their arguments (though I doubt what rule the compiler can use to decide to do it). I don't think any of the following benefits are implemented in DMD.
pure functions/methods
The sense of pure functions isn't clear to me. What is the advantage of pure functions / methods? I inform the compiler with "const" that this method does not change the current object, and therefore he can optimize (at least in C++) this method. How and what optimized the compiler if i have "pure" or "const pure" functions / methods?