Re: ggplotd - curve colour
Is this correct usage? auto gg = GGPlotD().put( geomLine( Aes!(typeof(xs), "x", typeof(ysfit), "y", string, "colour")( xs, ysfit, "red") ) ); The output is a blank png file. Full source: import ggplotd.ggplotd; import ggplotd.geom; import ggplotd.aes; import ggplotd.axes; void main() { import std.array : array; import std.algorithm : map; import std.range : iota; import ggplotd.colour; auto f = (double x) { return x; }; auto xs = iota(-5, 5, 0.1 ).array; auto ysfit = xs.map!((x) => f(x)).array; auto gg = GGPlotD().put( geomLine( Aes!(typeof(xs), "x", typeof(ysfit), "y", string, "colour")( xs, ysfit, "red") ) ); gg.put( xaxisOffset( 0) ).put( yaxisOffset( 0) ); gg.save( "axes.png", 500, 300 ); }
Re: Compiler silently ignores some method overloads
On Sunday, 8 May 2016 at 13:28:47 UTC, pineapple wrote: [...] I get a compiler error like so: E:\Dropbox\Projects\d\mach\sdl\surface.d(434): Error: none of the overloads of 'opIndexAssign' are callable using argument types (GLColor!float, int, int), candidates are: E:\Dropbox\Projects\d\mach\sdl\surface.d(406): mach.sdl.surface.Surface.opIndexAssign(const(uint) value, const(int) x, const(int) y) Meaning the overloads using GLColor are apparently silently ignored? No they are not ignored, otherwise the following would not compile: struct GLColor(T){T t0,t1,t2;} struct Thing { void opIndexAssign(T)(in GLColor!T color, in int x, in int y){} void opIndexAssign(T1, T2)(in GLColor!T1 color, in Vector2!T2 vector){} void opIndexAssign(in uint value, in int x, in int y){} } void main(string[] args) { Thing thing; thing[2,2] = GLColor!float(1, 1, 1); } Can you show your GLColor struct ? Maybe it contains an alias this or something else that mess the overload resolution.
Re: parameter pack to inputRange
On Sunday, 8 May 2016 at 23:49:40 UTC, Ali Çehreli wrote: On 05/08/2016 04:48 PM, Erik Smith wrote: On Sunday, 8 May 2016 at 22:37:44 UTC, Dicebot wrote: On Sunday, 8 May 2016 at 14:11:31 UTC, Ali Çehreli wrote: E front() { final switch (index) { /* static */ foreach (i, arg; Args) { case i: return arg; } } } AFAIK, this will do funny things with referencing stack if arguments are variables and not literals. Thanks! The static array version works for me too. It would be good to understand more about what is going on. It looks like the cost of the static array is an extra copy for each element. Maybe there is still a way to avoid that. I had to change one line of your test code. Dicebot's code work with it: auto toInputRange (T...) (T args) @nogc { import std.traits : CommonType; alias E = CommonType!T; struct Range { E[T.length] args; size_t index; E front () { return args[index]; } void popFront () { ++index; } bool empty () { return index >= args.length; } } Range range; foreach (i, ref arg; args) range.args[i] = arg; return range; } static void foo(Args...)(Args args) { import std.container.array; auto array = Array!int(toInputRange(args)); // <-- HERE foreach(a; array) { import std.stdio : writeln; writeln("e: ", a); } } void main ( ) { import std.stdio; writeln(toInputRange(1, 2, 3)); foo(1,2,3); } It used to be toInputRange!(args) Ali I did notice that but forgot to mention it - thanks for clarifying. Again it definitely works but it would be nice to find a non-copy solution. I tried to form a static array of pointers to the args (see below). It compiled but the output was bad. I would expect that taking the address of the arguments should be safe as long as you are in the called function. auto toInputRange (T...) (T args) @nogc { import std.traits : CommonType; alias E = CommonType!T; struct Range { alias P = E*; P[T.length] args; size_t index; E front () { return *args[index]; } void popFront () { ++index; } bool empty () { return index >= args.length; } } Range range; foreach (i, ref arg; args) range.args[i] = return range; }
Re: parameter pack to inputRange
On 05/08/2016 04:48 PM, Erik Smith wrote: On Sunday, 8 May 2016 at 22:37:44 UTC, Dicebot wrote: On Sunday, 8 May 2016 at 14:11:31 UTC, Ali Çehreli wrote: E front() { final switch (index) { /* static */ foreach (i, arg; Args) { case i: return arg; } } } AFAIK, this will do funny things with referencing stack if arguments are variables and not literals. Thanks! The static array version works for me too. It would be good to understand more about what is going on. It looks like the cost of the static array is an extra copy for each element. Maybe there is still a way to avoid that. I had to change one line of your test code. Dicebot's code work with it: auto toInputRange (T...) (T args) @nogc { import std.traits : CommonType; alias E = CommonType!T; struct Range { E[T.length] args; size_t index; E front () { return args[index]; } void popFront () { ++index; } bool empty () { return index >= args.length; } } Range range; foreach (i, ref arg; args) range.args[i] = arg; return range; } static void foo(Args...)(Args args) { import std.container.array; auto array = Array!int(toInputRange(args)); // <-- HERE foreach(a; array) { import std.stdio : writeln; writeln("e: ", a); } } void main ( ) { import std.stdio; writeln(toInputRange(1, 2, 3)); foo(1,2,3); } It used to be toInputRange!(args) Ali
Re: parameter pack to inputRange
On Sunday, 8 May 2016 at 22:37:44 UTC, Dicebot wrote: On Sunday, 8 May 2016 at 14:11:31 UTC, Ali Çehreli wrote: E front() { final switch (index) { /* static */ foreach (i, arg; Args) { case i: return arg; } } } AFAIK, this will do funny things with referencing stack if arguments are variables and not literals. Thanks! The static array version works for me too. It would be good to understand more about what is going on. It looks like the cost of the static array is an extra copy for each element. Maybe there is still a way to avoid that.
Re: parameter pack to inputRange
On Sunday, 8 May 2016 at 14:11:31 UTC, Ali Çehreli wrote: E front() { final switch (index) { /* static */ foreach (i, arg; Args) { case i: return arg; } } } AFAIK, this will do funny things with referencing stack if arguments are variables and not literals.
Re: parameter pack to inputRange
On Sunday, 8 May 2016 at 14:11:31 UTC, Ali Çehreli wrote: On 05/05/2016 11:08 PM, Dicebot wrote: > Unless parameter list is very (very!) long, I'd suggest to simply copy > it into a stack struct. Something like this: > > auto toInputRange (T...) (T args) > { > struct Range > { > T args; > size_t index; > > T[0] front () { return args[index]; } > void popFront () { ++index; } > bool empty () { return index >= args.length; } > } > > return Range(args, 0); > } I wanted this syntax to work but when I tested I saw that T It does (and it must). I have just tested it and noticed another issue though, one I have not foreseen initially. When accessing variadic variable list, one must use compile-time known index because variables are not guaranteed to be of same size. It can be fixed by using static array (and CommonType is a right call of course): auto toInputRange (T...) (T args) @nogc { import std.traits : CommonType; alias E = CommonType!T; struct Range { E[T.length] args; size_t index; E front () { return args[index]; } void popFront () { ++index; } bool empty () { return index >= args.length; } } Range range; foreach (i, ref arg; args) range.args[i] = arg; return range; } void main ( ) { import std.stdio; writeln(toInputRange(1, 2, 3)); } This version is checked to work on my machine.
Re: parameter pack to inputRange
On Sunday, 8 May 2016 at 14:11:31 UTC, Ali Çehreli wrote: On 05/05/2016 11:08 PM, Dicebot wrote: > Unless parameter list is very (very!) long, I'd suggest to simply copy > it into a stack struct. Something like this: > > auto toInputRange (T...) (T args) > { > struct Range > { > T args; > size_t index; > > T[0] front () { return args[index]; } > void popFront () { ++index; } > bool empty () { return index >= args.length; } > } > > return Range(args, 0); > } I wanted this syntax to work but when I tested I saw that T does not expand to struct members. I like Alex Parrill's only() solution but it allocates a dynamic array as well by doing the equivalent of [args] in the guts of its implementation. As Dicebot said, unless there are tons of arguments, I think the following is the best as it is @nogc. It executes a switch statement for each front() call though. And I like the CommonType!T idea there. import std.stdio; import std.string; /* Support empty Args? */ @nogc pure nothrow auto toInputRange(Args...)() { struct Range { size_t index; bool empty() { return index >= Args.length; } void popFront() { ++index; } import std.traits : CommonType; alias E = CommonType!Args; E front() { final switch (index) { /* static */ foreach (i, arg; Args) { case i: return arg; } } } } return Range(); } unittest { import std.traits; import std.range; static assert(isInputRange!(ReturnType!(toInputRange!(1; } void main() { auto r = toInputRange!(1, 2.5, 3); writeln(r); } Ali I like this solution and it's exactly what I was looking for. However, I'm having an issue when I try to apply it with an actual variadic function. This seems like a DMD bug. static void foo(Args...)(Args args) { import std.container.array; auto array = Array!int(toInputRange!(args)); foreach(a; array) { writeln("e: ", a); } } foo(1,2,3); e:1431827808 e:32767 e:1254116144
Re: Small C wrapper in your DUB package?
Well, just messing with it myself, the solution seems to be to make a .a library, link with /lib/libc.a since unlike .o, .a breaks shared linkage, and then refer to it in libs as "$PACKAGE_DIR/libmywrapper.a" ... "preBuildCommands": ["make -C $PACKAGE_DIR"], "libs": ["$PACKAGE_DIR/libmymagick.a","ImageMagick","/lib/libc.a"] ... basically. Then it doesn't work, because when ImageMagick calls dlopen, dmd somehow switches the string "RegisterGIFImage" with "gif_LTX_RegisterGIFImage" in the resulting executable. But the wrapper works fine at least.
Small C wrapper in your DUB package?
I'm tiring of making extern (C) signatures for a million library calls and counting out the offset of members of C structures, to produce analagous D structures. Couldn't I just make a .c file that had my own specialized, opaque, D friendly interface? I don't really know how to do that. Especially with DUB. Do I put it under "libs"? That seems like the only place you can put external stuff. Do I have to link my wrapper into a PIC shared library, or can I just make a .a static library? Or can I just use .o files? How do I specify that it look for the C wrapper in my package directory, rather than systemwide? Just "libs": ["./helpers/libchelper.a"]? I sure don't want to make a whole separate revision controlled project installed in /usr/lib just for a chintzy little wrapper for accessing a C library. I can build any C wrapper binaries in preBuildCommands with just a Makefile, so that's no problem. But I'm not sure how to use them in my program.
Re: parameter pack to inputRange
On 05/05/2016 11:08 PM, Dicebot wrote: > Unless parameter list is very (very!) long, I'd suggest to simply copy > it into a stack struct. Something like this: > > auto toInputRange (T...) (T args) > { > struct Range > { > T args; > size_t index; > > T[0] front () { return args[index]; } > void popFront () { ++index; } > bool empty () { return index >= args.length; } > } > > return Range(args, 0); > } I wanted this syntax to work but when I tested I saw that T does not expand to struct members. I like Alex Parrill's only() solution but it allocates a dynamic array as well by doing the equivalent of [args] in the guts of its implementation. As Dicebot said, unless there are tons of arguments, I think the following is the best as it is @nogc. It executes a switch statement for each front() call though. And I like the CommonType!T idea there. import std.stdio; import std.string; /* Support empty Args? */ @nogc pure nothrow auto toInputRange(Args...)() { struct Range { size_t index; bool empty() { return index >= Args.length; } void popFront() { ++index; } import std.traits : CommonType; alias E = CommonType!Args; E front() { final switch (index) { /* static */ foreach (i, arg; Args) { case i: return arg; } } } } return Range(); } unittest { import std.traits; import std.range; static assert(isInputRange!(ReturnType!(toInputRange!(1; } void main() { auto r = toInputRange!(1, 2.5, 3); writeln(r); } Ali
Compiler silently ignores some method overloads
In my struct I have some methods with these signatures: void opIndexAssign(T)(in GLColor!T color, in int x, in int y) void opIndexAssign(T1, T2)(in GLColor!T1 color, in Vector2!T2 vector) void opIndexAssign(in uint value, in int x, in int y) And when I try to do this: thing[2, 2] = GLColor!float(1, 1, 1); I get a compiler error like so: E:\Dropbox\Projects\d\mach\sdl\surface.d(434): Error: none of the overloads of 'opIndexAssign' are callable using argument types (GLColor!float, int, int), candidates are: E:\Dropbox\Projects\d\mach\sdl\surface.d(406): mach.sdl.surface.Surface.opIndexAssign(const(uint) value, const(int) x, const(int) y) Meaning the overloads using GLColor are apparently silently ignored? I had the same problem with another method. Here are my overloads: void fill(in uint color) void fill(T)(in GLColor!T color) void fill(in ubyte r, in ubyte g, in ubyte b, in ubyte a = 255) void fill(in Box!int box, in uint color) void fill(T)(in Box!int box, in GLColor!T color) void fill(in Box!int box, in ubyte r, in ubyte g, in ubyte b, in ubyte a = 255) void fill(in SDL_Rect* rect, in uint color) And when I try to do this: thing.fill(GLColor!float(1, 1, 1)); I get another compiler error: E:\Dropbox\Projects\d\mach\sdl\surface.d(429): Error: none of the overloads of 'fill' are callable using argument types (GLColor!float), candidates are: E:\Dropbox\Projects\d\mach\sdl\surface.d(179): mach.sdl.surface.Surface.fill(const(uint) color) E:\Dropbox\Projects\d\mach\sdl\surface.d(187): mach.sdl.surface.Surface.fill(const(ubyte) r, const(ubyte) g, const(ubyte) b, const(ubyte) a = cast(ubyte)255u) E:\Dropbox\Projects\d\mach\sdl\surface.d(191): mach.sdl.surface.Surface.fill(const(Box!int) box, const(uint) color) E:\Dropbox\Projects\d\mach\sdl\surface.d(199): mach.sdl.surface.Surface.fill(const(Box!int) box, const(ubyte) r, const(ubyte) g, const(ubyte) b, const(ubyte) a = cast(ubyte)255u) E:\Dropbox\Projects\d\mach\sdl\surface.d(203): mach.sdl.surface.Surface.fill(const(SDL_Rect*) rect, const(uint) color) The module containing the GLColor struct is definitely imported correctly, and I don't see how this could be an issue with the GLColor since its (admittedly meager) unittests all pass. What am I missing?
Re: ggplotd - curve colour
On Sunday, 8 May 2016 at 01:50:38 UTC, brocolis wrote: How do I set the color of a curve with ggplotd? Thanks. Also see the below example on how to merge Colour with an existing range of points using mergeRange: (Copied from http://blackedder.github.io/ggplotd/stat.html) void main() { /// http://blackedder.github.io/ggplotd/images/function.png import std.random : uniform; import std.typecons : Tuple; import ggplotd.stat : statFunction; import ggplotd.ggplotd : GGPlotD; import ggplotd.geom : geomLine, geomPoint; import ggplotd.aes : mergeRange; auto f = (double x) { return x / (1 + x); }; auto aes = statFunction(f, 0.0, 10); auto gg = GGPlotD().put(geomLine(aes)); // Generate some noisy points auto f2 = (double x) { return x / (1 + x) * uniform(0.75, 1.25); }; auto aes2 = f2.statFunction(0.0, 10, 25); // Show points in different colour auto withColour = Tuple!(string, "colour")("aquamarine").mergeRange(aes2); gg = gg.put(withColour.geomPoint); gg.save("function.png"); }
Re: ggplotd - curve colour
On Sunday, 8 May 2016 at 01:50:38 UTC, brocolis wrote: How do I set the color of a curve with ggplotd? Thanks. You can set colours by name: https://github.com/BlackEdder/ggplotd/blob/master/source/ggplotd/colour.d#L20 Alternatively you can pass through the RGB value (see the link above for the specification). Finally if you have multiple curves and don't want to specify specific colours you can just give them a different identifier (e.g. different double/int value (any type should do)) and it will chose the colours according to the colourgradient used. There is an example on how to specify your own gradient in the hist3D.svg example: http://blackedder.github.io/ggplotd/ggplotd.html
Re: template auto instantiation when parameters empty
On Thursday, May 05, 2016 19:09:01 Steven Schveighoffer via Digitalmars-d- learn wrote: > On 5/5/16 6:50 PM, Erik Smith wrote: > > Alias works at the cost of adding a 2nd type name: > > > > alias Res = Resource!(); > > auto res = Res.create > > > > The other problem is that the alias definition by itself instantiates, > > which I can't afford. > > > > I have createResource() now, it just doesn't fit well with the rest of > > the calling styles. > > > > There is also this approach, which might be slightly more idiomatic > > > > struct Resource(T) {} > > struct Policy {} > > > > auto create(alias T)() { > > > > T!Policy r; > > return r; > > > > } > > > > auto r = create!Resource; > > I believe factory external IFTI functions are quite idiomatic. They are > all over phobos. When dealing with the creation of objects that are templatized, they're often practically required for using the object to be sane - particularly when the constructor itself needs to be further templatized. And since IFTI only works with functions, if you want something similar with templated types, wrapping the construction in a function to get IFTI is pretty much your only option if you want to avoid requiring explicit instantiations. - Jonathan M Davis
Re: How can I save a class use the RedBlackTree?
On Tuesday, May 03, 2016 13:26:22 Meta via Digitalmars-d-learn wrote: > On Tuesday, 3 May 2016 at 12:12:04 UTC, Jonathan M Davis wrote: > > On Tue, 3 May 2016 11:37:13 +0200 > > Steven Schveighoffer via Digitalmars-d-learn > > > >wrote: > >> bleh, Object.opCmp only works with mutable objects. Which > >> means RedBlackTree cannot work with objects because it uses > >> inout to ensure your objects are not modified (since 2.068) > >> > >> It doesn't work with const or immutable either, the only > >> possible solution is to go back to mutable only. > >> > >> So annoying, we need to fix Object.opCmp, or using > >> const/immutable comparisons with objects doesn't work. > > > > Hopefully someday... > > > > https://issues.dlang.org/show_bug.cgi?id=9770 > > > > - Jonathan M Davis > > What's stopping us right now from making opCmp a free function in > object.d? In general, the two big blockers for removing opEquals, opCmp, toString, and toHash from Object are 1. The built-in AAs either need to be fixed so that they don't need Object and use the actual type that you're telling them to use (e.g. by templatizing them internally), or using classes as keys in the built-in AAs needs to be deprecated. The first requires fixing the built-in AAs, which is a huge pain. There have been several attempts, but AFAIK, no one has ever succeeded (Martin was the last one to try from what I recall, but I don't know how far he got). The second requires that we have a proper replacement in Phobos so that folks would actually have an alternative when using classes as keys was deprecated. At some point here, we're going to need to decide whether it's actually feasible to fix the built-in AAs, or whether we should just reduce what they can do to the sane subset, but it doesn't necessarily matter much as long as we don't have a viable HashMap/HashTable implementation in Phobos. 2. One or more compiler devs have to be convinced to prioritize making the changes required to actually deprecate these functions without breaking code (which isn't exactly straightforward). And we haven't even worked out yet exactly how such deprecations would work. It would be trivial if we could just break code, and the changes required in programmers are likely to be minor, but immediately breaking code like that without a deprecation path is not acceptable. As for making opCmp a free function, that's not how operator overloading works. The fact that opEquals ends up using a free function to call the opEquals on your type is an anomally (it's required for opEquals because of communutativity concerns). It _might_ make sense for opCmp for the same reasons but only if opCmp is required to have strict ordering (which is a matter of some debate). But even if it did make sense to turn opCmp into a free function, making that work rather than just creating a free function called opCmp that never gets used by anything would likely require effort similar to (or worse than) what would be required to make it possible to cleanly deprecate opCmp on Object. The first concern is sorting out what we do with the built-in AAs, which is potentially blocked by Andrei's revamping of std.container so that we can have a proper HashMap/HashTable in Phobos. The second concern is then figuring out the best way to go about actually deprecating those 4 functions and getting someone to do it. I expect that it will happen, but it's blocked by some stuff that could take a while, and it hasn't been a high priority. - Jonathan M Davis