Re: Virtual Classes?
On Thursday, 18 August 2016 at 03:58:00 UTC, Meta wrote: On Thursday, 18 August 2016 at 02:55:49 UTC, Basile B. wrote: On Thursday, 18 August 2016 at 02:51:48 UTC, Meta wrote: On Thursday, 18 August 2016 at 00:49:49 UTC, Engine Machine wrote: https://en.wikipedia.org/wiki/Virtual_class Can D do stuff like this naturally? Yes, D's `alias this` feature supports this. https://dlang.org/spec/class.html#alias-this No read carefully, alias this does not the same thing, particularly when the time comes to override the inner type. How doesn't it? You define a member with the same name in the outer class and it'll override the inner one. You can't call the most derived from a variable that has a lesser derived type: class Foo { Internal internal; class Internal {void stuff() {"base".writeln;}} this() {internal = new Internal;} alias internal this; } class Bar: Foo { void stuff() {"derived".writeln;} } void main(string[] args) { Foo f = new Bar; f.stuff(); // "base", not "derived". } ° From what i've read, "virtual classes" respect the OOP principles.
Re: DerelictGL3.reload with specified path question.
On Thursday, 18 August 2016 at 03:54:24 UTC, WhatMeWorry wrote: When I saw the .dll in OpenGL.dll, I immediately thought: just Windows. But does this hold true for the linux shared opengl libraries as well? Is this why DerelictGL3.reload() does not take a path argument. But then why doesDerelictGL3.load(lib)take an argument? The load method is what actually loads the shared library. On Windows, that's OpenGL32.dll. All of the platform-specific library names are configured at the top of gl3.d [1]. In addition to loading the library, it also loads the functions up to OpenGL 1.1, but no higher. This is because the availability of other functions are dependent on the version of the active OpenGL context. The reload method *does not* load the shared library, nor does it load the 1.1 functions. It loads the functions from OpenGL versions 1.2 and higher in addition to all available extensions (well, those for which support has been added to DerelictGL3). It's named reload because it should be called every time you switch contexts to make sure the functions are pointed in the right place. This is an artifact of the way OpenGL is handled on Windows. In practice, it's really only a problem there when switching between contexts that have different properties, but it simplifies the binding implementation and provides a uniform interface across platforms. I'm current working on a new version of the library that will allow you to specify which OpenGL versions and extensions you want to load and will also let you wrap everything in a struct so that you can have one instance for each context, but the distinction between load and reload will still exist. [1] https://github.com/DerelictOrg/DerelictGL3/blob/master/source/derelict/opengl3/gl3.d#L47
Re: Virtual Classes?
On Thursday, 18 August 2016 at 02:55:49 UTC, Basile B. wrote: On Thursday, 18 August 2016 at 02:51:48 UTC, Meta wrote: On Thursday, 18 August 2016 at 00:49:49 UTC, Engine Machine wrote: https://en.wikipedia.org/wiki/Virtual_class Can D do stuff like this naturally? Yes, D's `alias this` feature supports this. https://dlang.org/spec/class.html#alias-this No read carefully, alias this does not the same thing, particularly when the time comes to override the inner type. How doesn't it? You define a member with the same name in the outer class and it'll override the inner one.
Re: DerelictGL3.reload with specified path question.
On Thursday, 18 August 2016 at 03:11:17 UTC, WhatMeWorry wrote: On Wednesday, 17 August 2016 at 23:21:59 UTC, Rene Zwanenburg wrote: On Wednesday, 17 August 2016 at 22:59:31 UTC, WhatMeWorry wrote: I want to store all my shared/dynamic libraries within a special directory relative to where the application directory is. All of the derelictXX.loads(path) compiles except DerelictGL3.reload(lib); which doesn't seem to be implemented. Don't ever ship OpenGL.dll with your application: it's provided by the graphics driver. The only exception to this rule that I can think of is if you want to use a software implementation for some reason Understood. Thanks. I assume everything else is good to go. When I saw the .dll in OpenGL.dll, I immediately thought: just Windows. But does this hold true for the linux shared opengl libraries as well? Is this why DerelictGL3.reload() does not take a path argument. But then why doesDerelictGL3.load(lib)take an argument?
Re: DerelictGL3.reload with specified path question.
On Wednesday, 17 August 2016 at 23:21:59 UTC, Rene Zwanenburg wrote: On Wednesday, 17 August 2016 at 22:59:31 UTC, WhatMeWorry wrote: I want to store all my shared/dynamic libraries within a special directory relative to where the application directory is. All of the derelictXX.loads(path) compiles except DerelictGL3.reload(lib); which doesn't seem to be implemented. Don't ever ship OpenGL.dll with your application: it's provided by the graphics driver. The only exception to this rule that I can think of is if you want to use a software implementation for some reason Understood. Thanks. I assume everything else is good to go.
Re: Virtual Classes?
On Thursday, 18 August 2016 at 02:51:48 UTC, Meta wrote: On Thursday, 18 August 2016 at 00:49:49 UTC, Engine Machine wrote: https://en.wikipedia.org/wiki/Virtual_class Can D do stuff like this naturally? Yes, D's `alias this` feature supports this. https://dlang.org/spec/class.html#alias-this No read carefully, alias this does not the same thing, particularly when the time comes to override the inner type.
Re: Virtual Classes?
On Thursday, 18 August 2016 at 00:49:49 UTC, Engine Machine wrote: https://en.wikipedia.org/wiki/Virtual_class Can D do stuff like this naturally? Yes, D's `alias this` feature supports this. https://dlang.org/spec/class.html#alias-this
Re: Virtual Classes?
On Thursday, 18 August 2016 at 00:49:49 UTC, Engine Machine wrote: https://en.wikipedia.org/wiki/Virtual_class Can D do stuff like this naturally? Not naturally. The ancestor must be specified for the inner "virtual class": °°° class Foo { class Internal { void stuff() {} } } class Bar: Foo { class Internal: Foo.Internal { override void stuff() {} } } °°° However the ancestor inner class is well inherited (in the scope of a derived class Internal resolves to the parent definition or to the internal override when applicable). Note that I find the wikipedia example very bad. "Parts" doesn't define anything to override.
compile error while use `extern(C++, class)`
From spec (Interfacing to C++) https://dlang.org/spec/cpp_interface.html: ``` When mapping a D class onto a C++ struct, use extern(C++, struct) to avoid linking problems with C++ compilers (notably MSVC) that distinguish between C++'s class and struct when mangling. Conversely, use extern(C++, class) to map a D struct onto a C++ class. ``` But this compiles error. Please help, thanks.
Virtual Classes?
https://en.wikipedia.org/wiki/Virtual_class Can D do stuff like this naturally?
Re: DerelictGL3.reload with specified path question.
On Wednesday, 17 August 2016 at 22:59:31 UTC, WhatMeWorry wrote: I want to store all my shared/dynamic libraries within a special directory relative to where the application directory is. All of the derelictXX.loads(path) compiles except DerelictGL3.reload(lib); which doesn't seem to be implemented. Don't ever ship OpenGL.dll with your application: it's provided by the graphics driver. The only exception to this rule that I can think of is if you want to use a software implementation for some reason.
DerelictGL3.reload with specified path question.
I want to store all my shared/dynamic libraries within a special directory relative to where the application directory is. All of the derelictXX.loads(path) compiles except DerelictGL3.reload(lib); which doesn't seem to be implemented. All the reloads in github are either empty or use the version specification which I don't believe accomplishes what I want to achieve here. Is there a different approach or some workaround? Thanks in advance. import derelict.glfw3.glfw3; // windowing (1) import derelict.opengl3.gl3; // graphics (2a) (2b) import derelict.freeimage.freeimage; // images (3) import derelict.openal.al;// sound (4) import derelict.freetype.ft; // text fonts (5) auto loadLibraries() { version (Windows) string lib = "../libraries/windows/"; else version (linux) string lib = "../libraries/linux/"; else version (POSIX) string lib = "../libraries/apple/"; else throw new Exception("version not found"); DerelictGLFW3.load(lib); // (1) if (glfwInit() == 0) throw new Exception("Loading GLFW3 failed"); DerelictGL3.load(lib); // (2a) loads only the functions for OpenGL 1.0 and 1.1 glfwSetErrorCallback(&error_callback); // Set all the required options for GLFW glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); // this window is created because context is required for DerelictGL3.reload() auto win = glfwCreateWindow(0, 0, "context", null, null); if (!win) throw new Exception("GLFW failed to creation a window."); glfwMakeContextCurrent(win); DerelictGL3.reload(lib); // (2b) load OpenGL versions 1.2+ and ARB and EXT extens // == ABOVE LINE FAILS TO COMPILE HERE DerelictFI.missingSymbolCallback = &myMissingSymbolCallBack; DerelictFI.load(lib); // (3) Load the FreeImage library DerelictAL.load(lib); // (4) Load the OpenAL library called. DerelictFT.load(lib); // (5) Load the FreeType library return win; }
Re: Sequence separation
On 08/17/2016 09:21 PM, Lodovico Giaretta wrote: import std.traits: TemplateOf; static if (__traits(isSame, TemplateOf!(x.args[2]), MySequence)) { ... } std.traits.TemplateOf extracts the symbol representing the uninstantiated template. __traits(isSame, symbol1, symbol2) evaluates at compile time to true if and only if the two symbols represent the same thing (be it a type, an uninstantiated template, an instantiated one or whatever else). Look at that! Much better. TemplateOf is implemented with a template specialization, which can handle other things than types, unlike `is(...)`. Using that directly, without going to std.traits, isMySequence could be done like this: enum isMySequence(alias thing : MySequence!args, args ...) = true; enum isMySequence(alias thing) = false; That's just me toying around with the language, of course. The isSame+TemplateOf version is perfectly fine.
Re: Sequence separation
On Wednesday, 17 August 2016 at 19:15:48 UTC, ag0aep6g wrote: On 08/17/2016 08:38 PM, Engine Machine wrote: [...] [...] [...] With MySequence being a type, you can do this: static if (is(x.args[2] == MySequence!Args, Args ...)) { ... } It works! Nifty that you can do that with is. Aside from this check, there is probably not much use for MySequence being a type. So I'm be tempted to find a way to do the check with a raw template MySequence. As you said, another enum alone doesn't cut it. The faker can just add the same enum. But a private enum of a private type might do it: template MySequence(Args ...) { /* ... length and args ... */ private enum id = Id(); } private struct Id {} enum isMySequence(alias seq) = is(typeof(seq.id) == Id); Other modules can't use the Id type directly, because it's private. And they can't use typeof(MySequence!foo.id), because the id member is private, too. However, I wouldn't be surprised if this can be circumvented too. Well, the is does work and that probably is the best solution. I don't mind the extra type at this point. Of course, a library solution for this type of stuff would be nice. I'd rather not have to even use a type but rather use arrays: [a,b,[c,d]].
Re: Sequence separation
On Wednesday, 17 August 2016 at 19:21:57 UTC, Lodovico Giaretta wrote: On Wednesday, 17 August 2016 at 19:15:48 UTC, ag0aep6g wrote: [...] import std.traits: TemplateOf; static if (__traits(isSame, TemplateOf!(x.args[2]), MySequence)) { ... } std.traits.TemplateOf extracts the symbol representing the uninstantiated template. __traits(isSame, symbol1, symbol2) evaluates at compile time to true if and only if the two symbols represent the same thing (be it a type, an uninstantiated template, an instantiated one or whatever else). Thanks! To note, it error's if there is no match ;/
Re: Sequence separation
On Wednesday, 17 August 2016 at 18:38:48 UTC, Engine Machine wrote: On Wednesday, 17 August 2016 at 08:37:32 UTC, Lodovico Giaretta wrote: On Tuesday, 16 August 2016 at 23:18:28 UTC, Adam D. Ruppe wrote: [...] You mean something like: struct MySequence(Args...) { enum length = Args.length; alias args = Args; } alias x = MySequence!(a, b, MySequence!(c, d)); static assert(x.length == 3) static assert(x.args[2].length == 2); Thanks, basically works. How can I test, though, if a argument uses a MySequence? I can't do if (Args[0] == MySequence) because MySequence is templated. While I could test for a length, that doesn't work because some types have a length. I could add another enum to MySequence, but again, not safe. I could do some string tests, but that doesn't work. in your exmaple, if (x.args[2] == MySequence) ?? I simply need to differentiate between a parameter/arg being a MySequence and not. I guess I'll go with something like static if ((a.Args[2]).stringof[0..11] == "MySequence!") Doesn't feel entirely safe but probably will work without issue. Maybe there is a better way?
Re: Sequence separation
On Wednesday, 17 August 2016 at 19:15:48 UTC, ag0aep6g wrote: On 08/17/2016 08:38 PM, Engine Machine wrote: On Wednesday, 17 August 2016 at 08:37:32 UTC, Lodovico Giaretta wrote: [...] You mean something like: struct MySequence(Args...) { enum length = Args.length; alias args = Args; } alias x = MySequence!(a, b, MySequence!(c, d)); static assert(x.length == 3) static assert(x.args[2].length == 2); Thanks, basically works. How can I test, though, if a argument uses a MySequence? I can't do if (Args[0] == MySequence) because MySequence is templated. While I could test for a length, that doesn't work because some types have a length. I could add another enum to MySequence, but again, not safe. I could do some string tests, but that doesn't work. in your exmaple, if (x.args[2] == MySequence) ?? I simply need to differentiate between a parameter/arg being a MySequence and not. With MySequence being a type, you can do this: static if (is(x.args[2] == MySequence!Args, Args ...)) { ... } Aside from this check, there is probably not much use for MySequence being a type. So I'm be tempted to find a way to do the check with a raw template MySequence. import std.traits: TemplateOf; static if (__traits(isSame, TemplateOf!(x.args[2]), MySequence)) { ... } std.traits.TemplateOf extracts the symbol representing the uninstantiated template. __traits(isSame, symbol1, symbol2) evaluates at compile time to true if and only if the two symbols represent the same thing (be it a type, an uninstantiated template, an instantiated one or whatever else).
Re: Sequence separation
On 08/17/2016 08:38 PM, Engine Machine wrote: On Wednesday, 17 August 2016 at 08:37:32 UTC, Lodovico Giaretta wrote: [...] You mean something like: struct MySequence(Args...) { enum length = Args.length; alias args = Args; } alias x = MySequence!(a, b, MySequence!(c, d)); static assert(x.length == 3) static assert(x.args[2].length == 2); Thanks, basically works. How can I test, though, if a argument uses a MySequence? I can't do if (Args[0] == MySequence) because MySequence is templated. While I could test for a length, that doesn't work because some types have a length. I could add another enum to MySequence, but again, not safe. I could do some string tests, but that doesn't work. in your exmaple, if (x.args[2] == MySequence) ?? I simply need to differentiate between a parameter/arg being a MySequence and not. With MySequence being a type, you can do this: static if (is(x.args[2] == MySequence!Args, Args ...)) { ... } Aside from this check, there is probably not much use for MySequence being a type. So I'm be tempted to find a way to do the check with a raw template MySequence. As you said, another enum alone doesn't cut it. The faker can just add the same enum. But a private enum of a private type might do it: template MySequence(Args ...) { /* ... length and args ... */ private enum id = Id(); } private struct Id {} enum isMySequence(alias seq) = is(typeof(seq.id) == Id); Other modules can't use the Id type directly, because it's private. And they can't use typeof(MySequence!foo.id), because the id member is private, too. However, I wouldn't be surprised if this can be circumvented too.
Re: Sequence separation
On Wednesday, 17 August 2016 at 08:37:32 UTC, Lodovico Giaretta wrote: On Tuesday, 16 August 2016 at 23:18:28 UTC, Adam D. Ruppe wrote: On Tuesday, 16 August 2016 at 19:17:27 UTC, Engine Machine wrote: alias x = AliasSeq!(a, b, AliasSeq!(c, d)); results in a flat sequence. I would like to be able to keep them separate so I can have sub sequences. wrap them in a struct. You mean something like: struct MySequence(Args...) { enum length = Args.length; alias args = Args; } alias x = MySequence!(a, b, MySequence!(c, d)); static assert(x.length == 3) static assert(x.args[2].length == 2); Thanks, basically works. How can I test, though, if a argument uses a MySequence? I can't do if (Args[0] == MySequence) because MySequence is templated. While I could test for a length, that doesn't work because some types have a length. I could add another enum to MySequence, but again, not safe. I could do some string tests, but that doesn't work. in your exmaple, if (x.args[2] == MySequence) ?? I simply need to differentiate between a parameter/arg being a MySequence and not.
Re: having a trivial anonymous function call in template prevents compilation?
On Wednesday, 17 August 2016 at 13:33:26 UTC, Steven Schveighoffer wrote: I think the OP's case is a bug. Please file. Thanks, I've filed it. Just wanted to get a second opinion before concluding that it's a bug.
Re: having a trivial anonymous function call in template prevents compilation?
On 8/17/16 9:23 AM, Lodovico Giaretta wrote: On Wednesday, 17 August 2016 at 13:21:16 UTC, Cauterite wrote: On Wednesday, 17 August 2016 at 13:18:06 UTC, Adam D. Ruppe wrote: Best you can do is use them in an alias argument directly, but you cannot use them in an enum argument. I think you missed the point; it works perfectly fine without having this `({return 0;})()` in the template body (which, as far as I can see, doesn't appear to interact at all with the template argument). I think he meant that ({ return 0;})() cannot be executed at compile time and assigned to an enum. That's why the instantiation is failing. Yes, it can: https://dpaste.dzfl.pl/fca15065a4cf I think the OP's case is a bug. Please file. -Steve
Re: having a trivial anonymous function call in template prevents compilation?
On Wednesday, 17 August 2016 at 13:21:16 UTC, Cauterite wrote: On Wednesday, 17 August 2016 at 13:18:06 UTC, Adam D. Ruppe wrote: Best you can do is use them in an alias argument directly, but you cannot use them in an enum argument. I think you missed the point; it works perfectly fine without having this `({return 0;})()` in the template body (which, as far as I can see, doesn't appear to interact at all with the template argument). I think he meant that ({ return 0;})() cannot be executed at compile time and assigned to an enum. That's why the instantiation is failing.
Re: having a trivial anonymous function call in template prevents compilation?
On Wednesday, 17 August 2016 at 13:18:06 UTC, Adam D. Ruppe wrote: Best you can do is use them in an alias argument directly, but you cannot use them in an enum argument. I think you missed the point; it works perfectly fine without having this `({return 0;})()` in the template body (which, as far as I can see, doesn't appear to interact at all with the template argument).
Re: having a trivial anonymous function call in template prevents compilation?
On Wednesday, 17 August 2016 at 13:09:40 UTC, Cauterite wrote: Just by having a random `({return 0;})()` in the template body, suddenly the template rejects its arguments. I'm so confused, is this a bug? Or am I missing something? Function pointers and delegates are not valid compile time variables. Best you can do is use them in an alias argument directly, but you cannot use them in an enum argument.
having a trivial anonymous function call in template prevents compilation?
// -- Example: -- template A(alias Arg) { enum A = Arg; enum Unrelated = ({return 0;})(); // this line prevent compilation }; void main() { enum FnPtr = &asdf; enum _ = A!FnPtr; }; void asdf() {}; // ( https://dpaste.dzfl.pl/79301f12e5fc ) Just by having a random `({return 0;})()` in the template body, suddenly the template rejects its arguments. I'm so confused, is this a bug? Or am I missing something?
Re: typeof.stringof wrong type
On Wednesday, 17 August 2016 at 12:39:18 UTC, ag0aep6g wrote: On 08/17/2016 02:08 PM, Eugene Wissner wrote: I have a problem, that .stringof doesn't return what I'm expecting. Consider the following: template A(string T) { enum A : bool { yes = true, } } void main() { A!"asdf" a1; typeof(a1) a2; mixin(typeof(a1).stringof ~ " a3;"); } I get an error: some.d-mixin-13|13 error| Error: template some.A(string T) is used as a type Why the second line in main() works but the third one not? typeof(a1).stringof seems to ignore the string template parameter T. pragma(msg, typeof(a1).stringof) would return just "A". Is it a bug? Not exactly a bug. .stringof gives you a simple, readable name. It's not meant to be used in code generation. You can use std.traits.fullyQualifiedName instead: import std.traits: fullyQualifiedName; mixin(fullyQualifiedName!(typeof(a1)) ~ " a3;"); What I find strange is that if A isn't a enum, but a class the .stringof returns the full type name, therefore I would expect it behave the same in the code above. I will test later fullyQualifiedName, the example above is very simplified version of the code I had problem with. Thanks anyway
Re: typeof.stringof wrong type
On 08/17/2016 02:08 PM, Eugene Wissner wrote: I have a problem, that .stringof doesn't return what I'm expecting. Consider the following: template A(string T) { enum A : bool { yes = true, } } void main() { A!"asdf" a1; typeof(a1) a2; mixin(typeof(a1).stringof ~ " a3;"); } I get an error: some.d-mixin-13|13 error| Error: template some.A(string T) is used as a type Why the second line in main() works but the third one not? typeof(a1).stringof seems to ignore the string template parameter T. pragma(msg, typeof(a1).stringof) would return just "A". Is it a bug? Not exactly a bug. .stringof gives you a simple, readable name. It's not meant to be used in code generation. You can use std.traits.fullyQualifiedName instead: import std.traits: fullyQualifiedName; mixin(fullyQualifiedName!(typeof(a1)) ~ " a3;");
typeof.stringof wrong type
I have a problem, that .stringof doesn't return what I'm expecting. Consider the following: template A(string T) { enum A : bool { yes = true, } } void main() { A!"asdf" a1; typeof(a1) a2; mixin(typeof(a1).stringof ~ " a3;"); } I get an error: some.d-mixin-13|13 error| Error: template some.A(string T) is used as a type Why the second line in main() works but the third one not? typeof(a1).stringof seems to ignore the string template parameter T. pragma(msg, typeof(a1).stringof) would return just "A". Is it a bug?
Re: Log in an @nogc function
On Wednesday, 17 August 2016 at 10:47:54 UTC, Guillaume Piolat wrote: On Wednesday, 17 August 2016 at 10:45:01 UTC, Saurabh Das wrote: Is there any way I can log to a terminal or a file from inside an @nogc function? Thanks, Saurabh import core.stdc.stdio; printf("am logging C-style\n"); Damn I should have tried that. I feel stupid now :( Thank you!! :) SD
Re: ARSD PNG memory usage
On Tuesday, 16 August 2016 at 16:40:30 UTC, Adam D. Ruppe wrote: On Tuesday, 16 August 2016 at 16:29:18 UTC, Guillaume Piolat wrote: Hey, I also stumbled upon this with imageformats decoding PNG. Image loading makes 10x the garbage it should. Let's see what this threads unveils... leet me know how it is now Reverted back to a stb_image translation to avoid the problem altogether (though it's a bit slower now). Rewriting offending allocations in std.zlib was harder than expected.
Re: Log in an @nogc function
On Wednesday, 17 August 2016 at 10:45:01 UTC, Saurabh Das wrote: Is there any way I can log to a terminal or a file from inside an @nogc function? Thanks, Saurabh import core.stdc.stdio; printf("am logging C-style\n");
Log in an @nogc function
Is there any way I can log to a terminal or a file from inside an @nogc function? Thanks, Saurabh
Re: Sequence separation
On Tuesday, 16 August 2016 at 23:18:28 UTC, Adam D. Ruppe wrote: On Tuesday, 16 August 2016 at 19:17:27 UTC, Engine Machine wrote: alias x = AliasSeq!(a, b, AliasSeq!(c, d)); results in a flat sequence. I would like to be able to keep them separate so I can have sub sequences. wrap them in a struct. You mean something like: struct MySequence(Args...) { enum length = Args.length; alias args = Args; } alias x = MySequence!(a, b, MySequence!(c, d)); static assert(x.length == 3) static assert(x.args[2].length == 2);