Re: Using private constructor with std.experimental.allocater:make
On Monday, 2 May 2016 at 04:19:48 UTC, earthfront wrote: On Sunday, 1 May 2016 at 19:18:38 UTC, Basile B wrote: CT make(CT, Alloc, A...)(auto ref Alloc al, A a) This works. Thank you. Good point about __ctor alone not being sufficient. auto memory = al.allocate(size); ... GC.addRange(memory.ptr, size, typeid(CT)); Nit: "GC.addRange..." -- this attempts to clean memory allocated manually. The problem is that the template make and emplace() are **elsewhere** so they cannot see A.this() (== A.__ctor). A common way to fix this kind of problem is to make a template mixin with the template that has the visibility and to mix it in the current scope I guess this is the best workaround at the moment. There's a discontinuity between the GC and std.allocators. "new A(1)" works, because the GC has implicit private access to classes. I would love to see allocators in wider use. Workarounds are an obstacle to this. Possible solutions: * Emulate c++'s "friend" keyword somehow. D's rationale eschew's this. * Somehow designate friendship via [selective] module import? * Secret upcoming solution from Walter/Andrei. Weren't they discussing some sort of built in ref counting system? Other solution: give "super powers" to the __traits()... used to inspect, like suggested in this bugzilla ticket: https://issues.dlang.org/show_bug.cgi?id=15371. The worst with this problem is that it's extremely easy to fix in the compiler source code. But it's extremely hard to make people understand that this is a real problem.
Re: Can't use std.algorithm.remove on a char[]?
On 02.05.2016 01:51, TheGag96 wrote: That's a shame. I'd really like to be able to remove a character from a character array... I supplier I just have to get used to casting to ubyte[] or maybe just using dchar[] instead. Instead of casting you can also use `representation`[1] and `assumeUTF`[2] to convert to ubyte[] and back: char[] thing = ['a', 'b', 'c']; thing = thing.representation.remove(1).assumeUTF; [1] https://dlang.org/phobos/std_string.html#.representation [2] https://dlang.org/phobos/std_string.html#.assumeUTF
Re: Using private constructor with std.experimental.allocater:make
On Sunday, 1 May 2016 at 19:18:38 UTC, Basile B wrote: CT make(CT, Alloc, A...)(auto ref Alloc al, A a) This works. Thank you. Good point about __ctor alone not being sufficient. auto memory = al.allocate(size); ... GC.addRange(memory.ptr, size, typeid(CT)); Nit: "GC.addRange..." -- this attempts to clean memory allocated manually. The problem is that the template make and emplace() are **elsewhere** so they cannot see A.this() (== A.__ctor). A common way to fix this kind of problem is to make a template mixin with the template that has the visibility and to mix it in the current scope I guess this is the best workaround at the moment. There's a discontinuity between the GC and std.allocators. "new A(1)" works, because the GC has implicit private access to classes. I would love to see allocators in wider use. Workarounds are an obstacle to this. Possible solutions: * Emulate c++'s "friend" keyword somehow. D's rationale eschew's this. * Somehow designate friendship via [selective] module import? * Secret upcoming solution from Walter/Andrei. Weren't they discussing some sort of built in ref counting system?
Re: Using private constructor with std.experimental.allocater:make
On Sun, 01 May 2016 18:27:51 + Lass Safin via Digitalmars-d-learn wrote: > On Sunday, 1 May 2016 at 11:17:27 UTC, earthfront wrote: > > Hello! > > [...] > > class A > >{ int b; private this(int a){b=a;} } > > [...] > > I don't think classes are supposed to be able to have a private > constructor... There's no reason why you shouldn't be able to. Other, public constructors could call it, and other code within the module could call it. You can even have entire classes which are private. So, private constructors need to be possible. Now, whether that will ever work with something like emplace or the allocators, I don't know, since they're going to have access to the constructor to do their thing, but they're in different modules, which wouldn't normally have access to any constructors which aren't private (including protected and package, not just private). - Jonathan M Davis
simple idea for error messages
when it cannot match a prototype eg: module foo; enum Foo { foo } void bar(Foo foo) { } module bar; enum Foo { foo } void fooBar(Foo foo) { bar(foo); } rather than complain the type X does not match the type X - an unhelpful message - could the compiler not check to see if the type descriptions are identical, and if so print a clarifying message about which modules they come from. it's easy the second time, but another source of friction in learning the language in the beginning.
Re: Can't use std.algorithm.remove on a char[]?
On Sunday, 1 May 2016 at 09:11:22 UTC, ag0aep6g wrote: It's because of auto-decoding. char[] is an array of chars, but it's been made a range of dchars. Calling front on a char[] decodes up to four chars into one dchar. Obviously you can't take the address of the dchar, because it's just a return value. You can't assign through front, because the number of chars could be different from what's currently there. The whole array would have to be re-arranged then, which would be unexpectedly costly for the user. The auto-decoding behavior was chosen to make dealing with char[] less bug-prone. With auto-decoding you don't have to worry about cutting a multibyte sequence in half (can still cut a grapheme cluster in half, though). However, as you see, it creates other headaches, and it's considered a mistake by many. Getting rid of it now would be a major breaking change. Could be worthwhile, though. That's a shame. I'd really like to be able to remove a character from a character array... I supplier I just have to get used to casting to ubyte[] or maybe just using dchar[] instead. I'm honestly surprised I haven't encountered this behavior sooner. It's interesting - as I keep coding in D and learning about how amazing it is to use, I always find these weird quirks here and there to remind me that it isn't flawless... I guess it can't be perfect, haha.
Re: Setting a list of values
On Sunday, 1 May 2016 at 05:42:00 UTC, Ali Çehreli wrote: On 04/30/2016 10:05 PM, Joel wrote: > This has no effect: > _bars.each!(a => { a._plots.fillColor = Color(255, 180, 0); }); This is a common issue especially for people who know lambdas from other languages. :) Your lambda does not do any work. Rather, your lambda returns another lambda, which is promptly ignored: Those are some discrete semantics. I know D pretty well and even I didn't see the problem initially. Anybody else think it's worth adding a warning to the compiler for this specific case? If this is the user's intended behavior, then they can rewrite it like this to be explicit and disable the warning: _bars.each!(a => (){ a._plots.fillColor = Color(255, 180, 0); }); // ^^ add empty parenthesis before the curly brace
Re: Using private constructor with std.experimental.allocater:make
On Sunday, 1 May 2016 at 11:17:27 UTC, earthfront wrote: Hello! This code fails: - void main(){ class A { int b; private this(int a){b=a;} } //{ int b; this(int a){b=a;} } import std.conv:emplace; import std.experimental.allocator.mallocator:Mallocator; import std.experimental.allocator:make; { auto ptr = make!A(Mallocator.instance, 42); assert (ptr.b == 42); } } --- with error message: "/usr/include/dmd/phobos/std/conv.d(4115): Error: static assert "Don't know how to initialize an object of type A with arguments (int)" /usr/include/dmd/phobos/std/experimental/allocator/package.d(456): instantiated from here: emplace!(A, int) ./helloworld.d(25):instantiated from here: make!(A, shared(Mallocator), int)" If I make the constructor public, no problem. It seems that emplace (specialized for classes) doesn't work if the class has a private constructor. I added the following snippet to confirm: -- { auto ptr = Mallocator.instance.allocate(__traits(classInstanceSize, A)); auto aPtr = emplace(ptr,34); assert( aPtr.b == 34 ); } -- And I get the same error message. Google gave me: http://forum.dlang.org/post/kot0t1$uls$1...@digitalmars.com That guy's ultimate fix was explicitly calling the class's __ctor method, instead of emplace. The __ctor method is undocumented, as far as I can tell. Is there a better solution now? More widespread use of allocators will likely result in more of this problem. __ctor is not enough, the "static layout" must be copied to get the status of the initialized variables. Also there is not always a __ctor. Anyway you can put this in the module where is located the class with a private ctor: import std.traits; CT make(CT, Alloc, A...)(auto ref Alloc al, A a) if (is(CT == class) && !isAbstractClass!CT) { auto size = typeid(CT).init.length; auto memory = al.allocate(size); memory[0 .. size] = typeid(CT).init[]; static if (__traits(hasMember, CT, "__ctor")) (cast(CT) (memory.ptr)).__ctor(a); import core.memory: GC; GC.addRange(memory.ptr, size, typeid(CT)); return cast(CT) memory.ptr; } void main(string[] args) { class A {int b; private this(int a){b=a;} } import std.experimental.allocator.mallocator; auto ptr = make!A(Mallocator.instance, 42); assert (ptr.b == 42); } The problem is that the template make and emplace() are **elsewhere** so they cannot see A.this() (== A.__ctor). A common way to fix this kind of problem is to make a template mixin with the template that has the visibility and to mix it in the current scope: module stuff - mixin template fixProtection() { import std.traits; CT make(CT, Alloc, A...)(auto ref Alloc al, A a) if (is(CT == class) && !isAbstractClass!CT) { auto size = typeid(CT).init.length; auto memory = al.allocate(size); memory[0 .. size] = typeid(CT).init[]; static if (__traits(hasMember, CT, "__ctor")) (cast(CT) (memory.ptr)).__ctor(a); import core.memory: GC; GC.addRange(memory.ptr, size, typeid(CT)); return cast(CT) memory.ptr; } } - - module other stuff - mixin fixProtection; void main(string[] args) { class A {int b; private this(int a){b=a;} } import std.experimental.allocator.mallocator; auto ptr = make!A(Mallocator.instance, 42); assert (ptr.b == 42); } - Many things related to __traits are affected (getMember, getOverload, ...).
Re: Using private constructor with std.experimental.allocater:make
On Sunday, 1 May 2016 at 11:17:27 UTC, earthfront wrote: Hello! [...] class A { int b; private this(int a){b=a;} } [...] I don't think classes are supposed to be able to have a private constructor...
Re: Using a string generated at compile-time in a @nogc function
On Sunday, 1 May 2016 at 13:22:27 UTC, Mithun Hunsur wrote: On Sunday, 1 May 2016 at 10:37:23 UTC, Anonymouse wrote: On Sunday, 1 May 2016 at 05:28:36 UTC, Mithun Hunsur wrote: Hi all, I'm working on removing the string mixins from my code, but have run into an issue: http://dpaste.dzfl.pl/ecd7eb53947e As far as I can tell, this should work; the enum should force compile-time execution (which it does, as evidenced by the pragma). [...] That does seem buggy but I don't know enough to say for certain. I'd suggest filing a bug report anyway; the worst thing that can happen is that it gets closed. Unreported bugs can only be fixed by accident. Tacking an .idup after .toLower seems to make it work, at least on dpaste (http://dpaste.dzfl.pl/8abed3d3ec6c). I would have thought both toLower and idup returned a normal string, but unsure. enum loweredName = member.to!string.toLower.idup; pragma(msg, loweredName); if (member == test) return loweredName; Yup - that works. How odd! Along the same lines is enum loweredName = "" ~ member.to!string.toLower; which also works without issues. This makes me think that the result of `member.to!string.toLower` isn't being treated as a string, despite being typed as one - and by using `idup` or concatenating to it, we essentially retype it as a string. Another solution: import std.traits; import std.conv; import std.uni; import std.stdio; enum Test { A, B, C } auto enumToString(Test test) @nogc nothrow { @property string function() result = {return "";}; foreach (member; EnumMembers!Test) { if (member == test) { result = {return member.to!string.toLower;}; break; } } return result; } void main() { enumToString(Test.A)().writeln; } returns a delegate, although the call is quite unfriendly, despite of the @property.
Re: Method doesn't compile when defined in a mixin, but is fine without?
On Sunday, 1 May 2016 at 13:46:14 UTC, ag0aep6g wrote: On 01.05.2016 15:32, pineapple wrote: static string vectorpropertymixin(string name, string SDL_getter, string SDL_setter){ [...] mixin(vectorpropertymixin( "minsize", "SDL_GetWindowMinimumSize", "SDL_GetWindowMinimumSize" )); Should the second one be "SDL_SetWindowMinimumSize" here? ("Set" instead of "Get".) See, of course it was going to be something stupid like that. Would be nice if compile errors were kinder to mixins, might've realized where the error actually was. Any tips on that?
Re: Method doesn't compile when defined in a mixin, but is fine without?
On 01.05.2016 15:32, pineapple wrote: static string vectorpropertymixin(string name, string SDL_getter, string SDL_setter){ [...] mixin(vectorpropertymixin( "minsize", "SDL_GetWindowMinimumSize", "SDL_GetWindowMinimumSize" )); Should the second one be "SDL_SetWindowMinimumSize" here? ("Set" instead of "Get".)
Re: Method doesn't compile when defined in a mixin, but is fine without?
Strangely, though I'm getting this error when wrapping SDL_GetWindowMinimumSize and SDL_GetWindowMaximumSize, I don't get any compilation errors wrapping the identically-signatured SDL_GetWindowSize and SDL_GetWindowPosition using the same mixin.
Method doesn't compile when defined in a mixin, but is fine without?
I'm working on an SDL wrapper based on the derelict sdl2 and opengl3 bindings and so I've got a method like this I wrote: @property Vector2!int minsize(){ int x, y; SDL_GetWindowMinimumSize(this.window, &x, &y); return Vector2!int(x, y); } I've got several almost identical methods for maximum size, and window size, and window position, and so I thought I'd make a mixin to cut down on the redundancy. So I made my mixin, which looks like this - having definitions for both the getter above and also setters that seem to work fine: static string vectorpropertymixin(string name, string SDL_getter, string SDL_setter){ return " @property Vector2!int " ~ name ~ "(){ int x, y; " ~ SDL_getter ~ "(this.window, &x, &y); return Vector2!int(x, y); } @property void " ~ name ~ "(in Vector2!int vector){ this.set" ~ name ~ "(vector.x, vector.y); } void set" ~ name ~ "(in int x, in int y){ " ~ SDL_setter ~ "(this.window, x, y); } "; } And then I put this in the class body, replacing the non-mixin getters that compiled without incident: mixin(vectorpropertymixin( "minsize", "SDL_GetWindowMinimumSize", "SDL_GetWindowMinimumSize" )); And using the mixin I get this error when attempting to compile: E:\Dropbox\Projects\d\mach\sdl\window.d-mixin-285(295): Error: function pointer SDL_GetWindowMinimumSize (SDL_Window*, int*, int*) is not callable using argument types (SDL_Window*, const(int), const(int)) What's going on here? I feel like I must be making a really stupid obvious oversight.
Re: Using a string generated at compile-time in a @nogc function
On Sunday, 1 May 2016 at 10:37:23 UTC, Anonymouse wrote: On Sunday, 1 May 2016 at 05:28:36 UTC, Mithun Hunsur wrote: Hi all, I'm working on removing the string mixins from my code, but have run into an issue: http://dpaste.dzfl.pl/ecd7eb53947e As far as I can tell, this should work; the enum should force compile-time execution (which it does, as evidenced by the pragma). [...] That does seem buggy but I don't know enough to say for certain. I'd suggest filing a bug report anyway; the worst thing that can happen is that it gets closed. Unreported bugs can only be fixed by accident. Tacking an .idup after .toLower seems to make it work, at least on dpaste (http://dpaste.dzfl.pl/8abed3d3ec6c). I would have thought both toLower and idup returned a normal string, but unsure. enum loweredName = member.to!string.toLower.idup; pragma(msg, loweredName); if (member == test) return loweredName; Yup - that works. How odd! Along the same lines is enum loweredName = "" ~ member.to!string.toLower; which also works without issues. This makes me think that the result of `member.to!string.toLower` isn't being treated as a string, despite being typed as one - and by using `idup` or concatenating to it, we essentially retype it as a string.
Cannot link daimos glfw using x64
I am failing to link statically to glfw library with deimos glfw. The repo includes an example for glfw2. I downloaded the latest glfw2.lib and tried build the example with -m64 and got these errors: C:\ ... \deimos-glfw>dmd GLFW.lib examples/glfw2/openwindow/openwindow.d -m64 MSVCRT.lib(MSVCR120.dll) : error LNK2005: free already defined in LIBCMT.lib(free.obj) MSVCRT.lib(MSVCR120.dll) : error LNK2005: strchr already defined in LIBCMT.lib(strchr.obj) MSVCRT.lib(MSVCR120.dll) : error LNK2005: malloc already defined in LIBCMT.lib(malloc.obj) MSVCRT.lib(MSVCR120.dll) : error LNK2005: __iob_func already defined in LIBCMT.lib(_file.obj) MSVCRT.lib(MSVCR120.dll) : error LNK2005: fprintf already defined in LIBCMT.lib(fprintf.obj) LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library Next I tried to build the library myself with the /NODEFAULTLIB option set but still getting the same errors. What am I doing wrong?
Using private constructor with std.experimental.allocater:make
Hello! This code fails: - void main(){ class A { int b; private this(int a){b=a;} } //{ int b; this(int a){b=a;} } import std.conv:emplace; import std.experimental.allocator.mallocator:Mallocator; import std.experimental.allocator:make; { auto ptr = make!A(Mallocator.instance, 42); assert (ptr.b == 42); } } --- with error message: "/usr/include/dmd/phobos/std/conv.d(4115): Error: static assert "Don't know how to initialize an object of type A with arguments (int)" /usr/include/dmd/phobos/std/experimental/allocator/package.d(456): instantiated from here: emplace!(A, int) ./helloworld.d(25):instantiated from here: make!(A, shared(Mallocator), int)" If I make the constructor public, no problem. It seems that emplace (specialized for classes) doesn't work if the class has a private constructor. I added the following snippet to confirm: -- { auto ptr = Mallocator.instance.allocate(__traits(classInstanceSize, A)); auto aPtr = emplace(ptr,34); assert( aPtr.b == 34 ); } -- And I get the same error message. Google gave me: http://forum.dlang.org/post/kot0t1$uls$1...@digitalmars.com That guy's ultimate fix was explicitly calling the class's __ctor method, instead of emplace. The __ctor method is undocumented, as far as I can tell. Is there a better solution now? More widespread use of allocators will likely result in more of this problem.
Re: Setting a list of values
On Sunday, 1 May 2016 at 05:42:00 UTC, Ali Çehreli wrote: On 04/30/2016 10:05 PM, Joel wrote: > This has no effect: > _bars.each!(a => { a._plots.fillColor = Color(255, 180, 0); }); This is a common issue especially for people who know lambdas from other languages. :) Your lambda does not do any work. Rather, your lambda returns another lambda, which is promptly ignored: import std.stdio; import std.algorithm; void main() { auto arr = [ 1, 2 ]; arr.each!(a => { writeln(a); }); // returns lambda for each a } The lambda that 'each' takes above is "given a, produce this lambda". . To do the intended work, you need to remove the curly braces (and the semicolon): arr.each!(a => writeln(a)); Or, you could insert empty () to call the returned lambda but that would completely be extra work in this case: arr.each!(a => { writeln(a); }()); Or, remove the arrow: arr.each!((a) { writeln(a); });
Re: Getting all struct members and values with introspection avoiding string mixins
On Sunday, 1 May 2016 at 10:13:47 UTC, H. S. Teoh wrote: On Sun, May 01, 2016 at 09:42:37AM +, ParticlePeter via Digitalmars-d-learn wrote: I am logging arbitrary POD struct types with member names and data: void printStructInfo( T )( T info ) { foreach( i, A; typeof( T.tupleof )) { enum attribName = T.tupleof[i].stringof; writefln( "%s : %s", attribName, mixin( "info." ~ attribName )); } } Is there is some other way to evaluate info.attribName without using string mixins? [...] Using typeof(T.tupleof) seems a bit circuitous. Here's how I'd do it: void printStructInfo( T )( T info ) { import std.stdio : writefln; foreach (memb; __traits(allMembers, T)) { writefln("%s: %s", memb, __traits(getMember, info, memb)); } } (For structs that have members other than data fields, you'll need a static if to filter out non-value members, but this should get you started.) T Thanks, I was searching for that! The given example is a simplification of my code. I do examine each member separately and treat accordingly, but eventually used the mixin version to get the build-in type values.
Re: Using a string generated at compile-time in a @nogc function
On Sunday, 1 May 2016 at 05:28:36 UTC, Mithun Hunsur wrote: Hi all, I'm working on removing the string mixins from my code, but have run into an issue: http://dpaste.dzfl.pl/ecd7eb53947e As far as I can tell, this should work; the enum should force compile-time execution (which it does, as evidenced by the pragma). [...] That does seem buggy but I don't know enough to say for certain. I'd suggest filing a bug report anyway; the worst thing that can happen is that it gets closed. Unreported bugs can only be fixed by accident. Tacking an .idup after .toLower seems to make it work, at least on dpaste (http://dpaste.dzfl.pl/8abed3d3ec6c). I would have thought both toLower and idup returned a normal string, but unsure. enum loweredName = member.to!string.toLower.idup; pragma(msg, loweredName); if (member == test) return loweredName;
Re: Using a string generated at compile-time in a @nogc function
On Sunday, 1 May 2016 at 08:14:43 UTC, Nicholas Wilson wrote: On Sunday, 1 May 2016 at 05:28:36 UTC, Mithun Hunsur wrote: Hi all, I'm working on removing the string mixins from my code, but have run into an issue: http://dpaste.dzfl.pl/ecd7eb53947e As far as I can tell, this should work; the enum should force compile-time execution (which it does, as evidenced by the pragma). I've worked around this by employing a string mixin, but it's not as clean: http://dpaste.dzfl.pl/021c4a849b32 Any insight would be appreciated :) Have you tried using a static (as in inside the function) static array of strings? I considered it briefly, but opted against it because it adds unnecessary overhead (both time and space) - while minor, I'm not going to concede that quickly :P
Re: Getting all struct members and values with introspection avoiding string mixins
On Sun, May 01, 2016 at 09:42:37AM +, ParticlePeter via Digitalmars-d-learn wrote: > I am logging arbitrary POD struct types with member names and data: > > void printStructInfo( T )( T info ) { > foreach( i, A; typeof( T.tupleof )) { > enum attribName = T.tupleof[i].stringof; > writefln( "%s : %s", attribName, mixin( "info." ~ attribName )); > } > } > > Is there is some other way to evaluate info.attribName without using > string mixins? [...] Using typeof(T.tupleof) seems a bit circuitous. Here's how I'd do it: void printStructInfo( T )( T info ) { import std.stdio : writefln; foreach (memb; __traits(allMembers, T)) { writefln("%s: %s", memb, __traits(getMember, info, memb)); } } (For structs that have members other than data fields, you'll need a static if to filter out non-value members, but this should get you started.) T -- 2+2=4. 2*2=4. 2^2=4. Therefore, +, *, and ^ are the same operation.
Getting all struct members and values with introspection avoiding string mixins
I am logging arbitrary POD struct types with member names and data: void printStructInfo( T )( T info ) { foreach( i, A; typeof( T.tupleof )) { enum attribName = T.tupleof[i].stringof; writefln( "%s : %s", attribName, mixin( "info." ~ attribName )); } } Is there is some other way to evaluate info.attribName without using string mixins? Cheers, PP
Re: Can't use std.algorithm.remove on a char[]?
On 01.05.2016 07:29, TheGag96 wrote: Why exactly is it like this? I would understand why strings (immutable character arrays) behave like this, but I feel like plain old character arrays should work the same as an array of ubytes when treated as a range... Or is there some other string-related behavior that would get broken by this? It's because of auto-decoding. char[] is an array of chars, but it's been made a range of dchars. Calling front on a char[] decodes up to four chars into one dchar. Obviously you can't take the address of the dchar, because it's just a return value. You can't assign through front, because the number of chars could be different from what's currently there. The whole array would have to be re-arranged then, which would be unexpectedly costly for the user. The auto-decoding behavior was chosen to make dealing with char[] less bug-prone. With auto-decoding you don't have to worry about cutting a multibyte sequence in half (can still cut a grapheme cluster in half, though). However, as you see, it creates other headaches, and it's considered a mistake by many. Getting rid of it now would be a major breaking change. Could be worthwhile, though.
Re: Using a string generated at compile-time in a @nogc function
On Sunday, 1 May 2016 at 05:28:36 UTC, Mithun Hunsur wrote: Hi all, I'm working on removing the string mixins from my code, but have run into an issue: http://dpaste.dzfl.pl/ecd7eb53947e As far as I can tell, this should work; the enum should force compile-time execution (which it does, as evidenced by the pragma). I've worked around this by employing a string mixin, but it's not as clean: http://dpaste.dzfl.pl/021c4a849b32 Any insight would be appreciated :) Have you tried using a static (as in inside the function) static array of strings?