Re: how to allocate class without gc?
On Tuesday, 26 January 2016 at 01:09:50 UTC, Igor wrote: Is there any examples that shows how to properly allocate an object of a class type with the new allocators and then release it when desired? There are a number of different patterns discussed and illustrated with examples at http://wiki.dlang.org/Memory_Management. These don't use std.experimental.allocator, but should serve as a pretty good foundation for doing so. Mike
Re: nogc Array
On Tuesday, 26 January 2016 at 05:53:29 UTC, Igor wrote: On Tuesday, 26 January 2016 at 04:38:13 UTC, Adam D. Ruppe wrote: On Tuesday, 26 January 2016 at 04:31:07 UTC, Igor wrote: then std.algorithm.find!("a.myInt == b")(classes, 3) Try std.algorithm.find!("a.myInt == b")(classes[], 3) notice the [] after classes I guess std.container.array isn't a range? Or am I using it wrong? Containers aren't really ranges, they instead *offer* ranges that iterate over them. Built in arrays are a bit special in that they do this implicitly so the line is more blurred there, but it is a general rule that you need to get a range out of a container. Otherwise, consider that iterating over it with popFront would result in the container being automatically emptied and not reusable! Ok, does the [] do any conversion or any thing I don't want or does it just make the template know we are working over an array? Are there any performance issues? I am already using a for loop to find the type, it's 6 lines of code. I was hoping to get that down to one or 2 and make it a bit easier to understand. App app = null; for(int i = 0; i < Apps.length(); i++) if ((Apps[i] !is null) && (Apps[i].hWnd == hWnd)) { app = Apps[i]; break; } versus find!("a.hWnd == b")(Apps[], hWnd); Does [] take time to convert to a built in a array or range or whatever or will it be just as fast as the above code? The [] operator returns a Range object iterating over the Array elements, similarly to what the begin()/end() cbegin()/cend() function pairs do in C++. The range object does not copy the array element, only contains a slice to them. So your question ends up in comparing hand-written loops over std::find_if().
Re: how to allocate class without gc?
On Tuesday, 26 January 2016 at 01:09:50 UTC, Igor wrote: Is there any examples that shows how to properly allocate an object of a class type with the new allocators and then release it when desired? There's an example of class object allocation in the std.experimental.allocator docs: // Dynamically allocate a class object static class Customer { uint id = uint.max; this() {} this(uint id) { this.id = id; } // ... } Customer cust = theAllocator.make!Customer; assert(cust.id == uint.max); // default initialized cust = theAllocator.make!Customer(42); assert(cust.id == 42); To release the object (call the destructor and free the memory), call dispose(): theAllocator.dispose(cust); You'll need to replace "theAllocator" with the allocator you want.
Re: how to allocate class without gc?
V Tue, 26 Jan 2016 05:47:42 + Igor via Digitalmars-d-learnnapsáno: > On Tuesday, 26 January 2016 at 05:11:54 UTC, Mike Parker wrote: > > On Tuesday, 26 January 2016 at 01:09:50 UTC, Igor wrote: > >> Is there any examples that shows how to properly allocate an > >> object of a class type with the new allocators and then > >> release it when desired? > > > > Allocate a block of memory big enough to hold an instance of > > your class using whichever allocator you need, then instantiate > > a class instance with std.conv.emplace. > > > > http://p0nce.github.io/d-idioms/#Placement-new-with-emplace > > I created a class using this example. But my code is now failing. > It seems one can't just replace new with this and expect it to > work? > > What is happening is some fields(strings) are not retaining their > value. > > ubyte[__traits(classInstanceSize, App)] buffer; > auto app = cast(App)emplace!App(buffer[]); > //auto app = new App(); > > Basically the comment is the original. When I finally call > createWindow, it fails because the string representing the name > inside App is null... Which doesn't happen when I use new. > > Should it work as expected(which it isn't) or do I have to also > emplace all the fields and such so they are not for some reason > released? > Can you try it with GC.disable()?
Re: How do you draw in gtkD? Simple example overriding Widget.draw() doesn't compile.
Generally don't override methods in GtkD, use event handlers like addOnDraw. Because GtkD wraps GTK functions an overriden D method of GtkD will never get called by GTK since it is working with the underlying C functions directly.
Re: how to allocate class without gc?
On Tuesday, 26 January 2016 at 01:09:50 UTC, Igor wrote: Is there any examples that shows how to properly allocate an object of a class type with the new allocators and then release it when desired? This is more or less the same answer as you've get previously except that I don't use emplace but rather a copy of what's done in _d_new_class() from the D runtime: CT construct(CT, A...)(A a) @trusted @nogc if (is(CT == class)) { import std.experimental.allocator.mallocator; auto size = typeid(CT).init.length; auto memory = Mallocator.instance.allocate(size); // D runtime use GC here 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; } the GC stuff could look superfluous but without this and if there's a GC allocated members in your class (even a simple dynamic array) then you'll encounter random errors at run-time.
Re: how to allocate class without gc?
On Tuesday, 26 January 2016 at 09:32:06 UTC, Daniel Kozak wrote: V Tue, 26 Jan 2016 05:47:42 + Igor via Digitalmars-d-learnnapsáno: [...] Can you try it with GC.disable()? Didn't change anything.
Re: how to allocate class without gc?
On Tuesday, 26 January 2016 at 09:32:06 UTC, Daniel Kozak wrote: V Tue, 26 Jan 2016 05:47:42 + Igor via Digitalmars-d-learnnapsáno: On Tuesday, 26 January 2016 at 05:11:54 UTC, Mike Parker wrote: > [...] Can you try it with GC.disable()? //ubyte[__traits(classInstanceSize, App)] buffer; auto buffer = core.stdc.stdlib.malloc(__traits(classInstanceSize, App))[0..__traits(classInstanceSize, App)]; works, so it is the ubyte line.
free causes exception
I have successfully malloc'ed an object but when I go to free it in the destructor I get an exception. The destructor simply has ~this() // destructor for Foo { core.stdc.stdlib.free(); } auto buffer = core.stdc.stdlib.malloc(__traits(classInstanceSize, App))[0..__traits(classInstanceSize, App)]; auto app = cast(App)emplace!App(buffer[]); I tried to retain a ptr to buffer and free that but still no good. I also get a depreciation warning that is not an lvalue. Hopefully I don't have to keep a ptr around to this simply to free it and avoid future issues? So how am I suppose to free an object?
Re: how to allocate class without gc?
V Tue, 26 Jan 2016 13:56:39 + Igor via Digitalmars-d-learnnapsáno: > On Tuesday, 26 January 2016 at 09:32:06 UTC, Daniel Kozak wrote: > > V Tue, 26 Jan 2016 05:47:42 + > > Igor via Digitalmars-d-learn > > napsáno: > > > >> On Tuesday, 26 January 2016 at 05:11:54 UTC, Mike Parker wrote: > >> > [...] > >> > > Can you try it with GC.disable()? > > //ubyte[__traits(classInstanceSize, App)] buffer; > auto buffer = core.stdc.stdlib.malloc(__traits(classInstanceSize, > App))[0..__traits(classInstanceSize, App)]; > > works, so it is the ubyte line. > What about: auto buffer = new ubyte[__traits(classInstanceSize, App)];
Re: free causes exception
V Tue, 26 Jan 2016 14:20:29 + Igor via Digitalmars-d-learnnapsáno: > I have successfully malloc'ed an object but when I go to free it > in the destructor I get an exception. The destructor simply has > > ~this() // destructor for Foo > { > core.stdc.stdlib.free(); > } > > > auto buffer = core.stdc.stdlib.malloc(__traits(classInstanceSize, > App))[0..__traits(classInstanceSize, App)]; > auto app = cast(App)emplace!App(buffer[]); > > I tried to retain a ptr to buffer and free that but still no > good. I also get a depreciation warning that is not an > lvalue. Hopefully I don't have to keep a ptr around to this > simply to free it and avoid future issues? > > So how am I suppose to free an object? > > core.stdc.stdlib.free(cast(void *)this);
Dense multidimensional std.container.array?
Just wondering how to create a dense multidimensional array with the GC free array container? I don't want to use an array of arrays but I do want the array[0][0] notation.
Re: how to allocate class without gc?
On Tuesday, 26 January 2016 at 13:56:39 UTC, Igor wrote: //ubyte[__traits(classInstanceSize, App)] buffer; auto buffer = core.stdc.stdlib.malloc(__traits(classInstanceSize, App))[0..__traits(classInstanceSize, App)]; works, so it is the ubyte line. Can you please post the full code? From your description, it looks like the stack frame might get invalidated...
Re: how to allocate class without gc?
On Tuesday, 26 January 2016 at 13:56:39 UTC, Igor wrote: //ubyte[__traits(classInstanceSize, App)] buffer; auto buffer = core.stdc.stdlib.malloc(__traits(classInstanceSize, App))[0..__traits(classInstanceSize, App)]; works, so it is the ubyte line. Make sure the buffer outlives the class instance. If you emplace on the stack, then at the end of the scope your instance is gone.
Re: free causes exception
V Tue, 26 Jan 2016 15:24:00 + Igor via Digitalmars-d-learnnapsáno: > On Tuesday, 26 January 2016 at 14:48:48 UTC, Daniel Kozak wrote: > > V Tue, 26 Jan 2016 14:20:29 + > > Igor via Digitalmars-d-learn > > napsáno: > > > >> [...] > > > > core.stdc.stdlib.free(cast(void *)this); > > I still get an exception: > > Exception thrown at 0x7FF6C7CA3700 in test.exe: 0xC005: > Access violation reading location 0x. Can you post full code?
Re: free causes exception
On Tuesday, 26 January 2016 at 14:48:48 UTC, Daniel Kozak wrote: V Tue, 26 Jan 2016 14:20:29 + Igor via Digitalmars-d-learnnapsáno: [...] core.stdc.stdlib.free(cast(void *)this); I still get an exception: Exception thrown at 0x7FF6C7CA3700 in test.exe: 0xC005: Access violation reading location 0x.
Types as keys
Hello, I'm having problem with converting from Java style coding to D, probably doing wrong something. I want to have a map (associative array) which will return specific object depending on provided key. Key is a type of other object. Let say i want to hold single instances of some kind of parser for each key object types. class BaseFooBar{} class Foo:BaseFooBar{ ... } class Bar:BaseFooBar{ } BaseParser{} Parser(T) :BaseParser{ abstract string parse(T value); } ParserOne:Parser!Foo{ override string parse(Foo value){ ... } ParserTwo:Parser!Bar{ override string parse(Bar value){ ... } Parser[TypeInfo] container; container~=new ParserOne(); container~=new ParserTwo(); Now i have some data Foo and some Bar in array and each one must be parsed using proper parser parserFoobars(BaseFooBar[] values){ foreach(BaseFooBar foobar;values){ BaseParser parser=container[typeid(foobar)]; ... Now i would have to cast check if parser is ParserOne or ParserTwo and then cast foobar to Bar or Foo depending on which parser has been retrieved. This has no sense ... In Java i could place generic code in BaseParser and depending on FooBar type i will get proper parser from map, and values would be parsed without casting. How to handle this correctly?
Re: Types as keys
On Tuesday, 26 January 2016 at 15:54:14 UTC, Voitech wrote: How to handle this correctly? Make BaseParser the value type of the AA. Parser!Foo and Parser!Bar are subtypes of BaseParser. Unlike Java, just `Parser` is not a type but a template. It must be instantiated to create a type. Java implements generics differently from templates, with its own set of disadvantages and advantages.
Re: traits getOverload of a template method
On Thursday, 6 February 2014 at 23:06:03 UTC, QAston wrote: How do i get aliases to overloads of a template method like Class A { int a(T)(T tq,T tw); int a(T)(T tq); } __traits(getOverloads, A, "a(int)")doesnt work Bump. I also have a similar problem. I have a module with two function templates that are overloaded (they have the same name, but different sets of parameters) and I need to select one of them so I can cast it to a function with the @nogc attribute, similar to this: http://p0nce.github.io/d-idioms/#Bypassing-@nogc. ``` // move has two overloads: `T move(T)(ref T)` and `void move(T)(ref T, ref T)` // and I need to select the second one here: cast(FT)(move!int)(arg1, arg2) ``` Otherwise I get "Error: template std.algorithm.mutation.move matches more than one template declaration".
Re: Dense multidimensional std.container.array?
On Tuesday, 26 January 2016 at 14:55:53 UTC, Wilson wrote: Just wondering how to create a dense multidimensional array with the GC free array container? I don't want to use an array of arrays but I do want the array[0][0] notation. I suggest using std.experimental.ndslice [1] for multidimensional arrays and std.experimental.allocator [2] for GC-free allocation. For an introduction to the design ideas behind [2], you can also check Andrei's talk at DConf [3]. Here's an example: import std.stdio : writeln; import std.experimental.allocator : makeArray, dispose; import std.experimental.allocator.mallocator : Mallocator; import std.experimental.ndslice : sliced; void main() { ulong[] arr = Mallocator.instance.makeArray!ulong(36); scope (exit) Mallocator.instance.dispose(arr); // All of the below matrices refer to the same array // that was allocated above. auto matrix4x9 = arr.sliced(4, 9); // 2D 4x9 matrix auto matrix6x6 = arr.sliced(6, 6); // 2D 6x6 matrix auto matrix2x3x6 = arr.sliced(2, 3, 6); // 3D 2x3x6 matrix // matrix.length!N - gets the number of elements in the Nth dimention foreach (rowIdx; 0 .. matrix6x6.length!0) foreach (columnIdx; 0 .. matrix6x6.length!1) matrix6x6[rowIdx, columnIdx] = (rowIdx + 1) * 10 + columnIdx + 1; writeln (matrix6x6); writeln (matrix4x9); writeln (matrix2x3x6); // The memory allocated by arr will be freed implicitly here. } Which prints: [[11, 12, 13, 14, 15, 16], [21, 22, 23, 24, 25, 26], [31, 32, 33, 34, 35, 36], [41, 42, 43, 44, 45, 46], [51, 52, 53, 54, 55, 56], [61, 62, 63, 64, 65, 66]] [[11, 12, 13, 14, 15, 16, 21, 22, 23], [24, 25, 26, 31, 32, 33, 34, 35, 36], [41, 42, 43, 44, 45, 46, 51, 52, 53], [54, 55, 56, 61, 62, 63, 64, 65, 66]] [[[11, 12, 13, 14, 15, 16], [21, 22, 23, 24, 25, 26], [31, 32, 33, 34, 35, 36]], [[41, 42, 43, 44, 45, 46], [51, 52, 53, 54, 55, 56], [61, 62, 63, 64, 65, 66]]] [1]: http://dlang.org/phobos-prerelease/std_experimental_ndslice [2]: http://dlang.org/phobos-prerelease/std_experimental_allocator [3]: http://dconf.org/2015/talks/alexandrescu.html
Re: Speed of csvReader
On Thursday, 21 January 2016 at 21:24:49 UTC, H. S. Teoh wrote: While this is no fancy range-based code, and one might say it's more hackish and C-like than idiomatic D, the problem is that current D compilers can't quite optimize range-based code to this extent yet. Perhaps in the future optimizers will improve so that more idiomiatic, range-based code will have comparable performance with fastcsv. (At least in theory this should be possible.) As a D novice still struggling with the concept that composable range-based functions can be more efficient than good-old looping (ya, I know, cache friendliness and GC avoidance), I find it extremely interesting that someone as expert as yourself would reach for a C-like approach for serious data crunching. Given that data crunching is the kind of thing I need to do a lot, I'm wondering how general your statement above might be at this time w.r.t. this and possibly other domains.
Re: Dense multidimensional std.container.array?
On Tuesday, 26 January 2016 at 18:07:40 UTC, ZombineDev wrote: [snip] Cool example.
Defining event handlers for function, method, or shared method
In many multi threading module designs of mine, I generally design a base class, and this class have some events. Exempli gratia: void eventOnStart(); void eventOnStop(); void eventOnItemAdded( size_t itemIndex ); There is this problem though. I need/want this class to be able to bind a function, a method, or a shared method. From the perspective of class design, there shouldn't be any difference. Its purpose is to let know about the event, not to care about how the event handler is designed. If I want handlers to be functions, I design it like, public alias EventOnStart = void function(); public EventOnStart eventOnStart; If it is for normal methods, design becomes like, public alias EventOnStart = void delegate(); For shared methods, it becomes, public alias EventOnStart = void delegate() shared; As you will guess, to be able to support any of those three, it becomes so complex. Is there any way generalise to support three of them without making this any complex? A secondary thing, this is not D related though, whether there is any different approach for event listener design like Observer pattern but with little overhead and complexity?
Re: Improving CSV parsing performance, Episode 2 (Was: Re: Speed of csvReader)
On Tuesday, 26 January 2016 at 06:27:49 UTC, H. S. Teoh wrote: On Sun, Jan 24, 2016 at 06:07:41AM +, Jesse Phillips via Digitalmars-d-learn wrote: [...] My suggestion is to take the unittests used in std.csv and try to get your code working with them. As fastcsv limitations would prevent replacing the std.csv implementation the API may not need to match, but keeping close to the same would be best. My thought is to integrate the fastcsv code into std.csv, such that the current std.csv code will serve as fallback in the cases where fastcsv's limitations would prevent it from being used, with fastcsv being chosen where possible. That is why I suggested starting with the unittests. I don't expect the implementations to share much code, std.csv is written to only use front, popFront, and empty. Most of the work is done in csvNextToken so it might be able to take advantage of random-access ranges for more performance. I just think the unittests will help to define where switching algorthims will be required since they exercise a good portion of the API.
Re: Defining event handlers for function, method, or shared method
On 01/26/2016 10:41 AM, tcak wrote: > I need/want this class to be able to bind > a function, a method, or a shared method. From the perspective of class > design, there shouldn't be any > difference. Its purpose is to let know about the event, not to care > about how the event > handler is designed. If I understand the problem correctly, an interface can define the interface and a templated class can provide the differences: import std.stdio; import std.algorithm; interface Event { void start(); void stop(); void itemAdded( size_t itemIndex ); } class ConcreteEvent(alias onStart, alias onStop, alias onItemAdded) : Event { void start() { onStart(); } void stop() { onStop(); } void itemAdded(size_t itemIndex) { itemAdded(itemIndex); } } void fooStart() { } void fooStop() { } void fooItemAdded(size_t itemIndex) { } void bar(size_t itemIndex) { } void main() { Event[] events; events ~= new ConcreteEvent!(fooStart, fooStop, fooItemAdded); struct S { void memberFunction() { } } auto s = S(); auto memberClosure(ref S s) {On 01/26/2016 10:41 AM, tcak wrote: > I need/want this class to be able to bind > a function, a method, or a shared method. From the perspective of class > design, there shouldn't be any > difference. Its purpose is to let know about the event, not to care > about how the event > handler is designed. If I understand the problem correctly, an interface can define the interface and a templated class can provide differences: import std.stdio; import std.algorithm; interface Event { void start(); void stop(); void itemAdded( size_t itemIndex ); } class ConcreteEvent(alias onStart, alias onStop, alias onItemAdded) : Event { void start() { onStart(); } void stop() { onStop(); } void itemAdded(size_t itemIndex) { itemAdded(itemIndex); } } void fooStart() { } void fooStop() { } void fooItemAdded(size_t itemIndex) { } void bar(size_t itemIndex) { } void main() { Event[] events; events ~= new ConcreteEvent!(fooStart, fooStop, fooItemAdded); struct S { void memberFunction() { } } auto s = S(); auto memberClosure(ref S s) { return () => s.memberFunction(); } events ~= new ConcreteEvent!(() => memberClosure(s), () => writeln("stop"), bar); events.each!(e => e.stop); } Ali return () => s.memberFunction(); } events ~= new ConcreteEvent!(() => memberClosure(s), () => writeln("stop"), bar); events.each!(e => e.stop); } Ali
Re: Defining event handlers for function, method, or shared method
What a lousy copy+paste mistake that was. I am glad no credit card number leaked there. :p On 01/26/2016 11:22 AM, Ali Çehreli wrote: > class ConcreteEvent(alias onStart, alias onStop, alias onItemAdded) : > void itemAdded(size_t itemIndex) { > itemAdded(itemIndex); > } That call should have been onItemAdded(). Ali
Re: free causes exception
On 01/26/2016 06:20 AM, Igor wrote: > I have successfully malloc'ed an object but when I go to free it in the > destructor I get an exception. The destructor simply has > > ~this() // destructor for Foo > { > core.stdc.stdlib.free(); > } That design suggests a complexity regarding object responsibilities: Assuming that the object was constructed on a piece of memory that it did *not* allocate, the memory was owned by somebody else. In that case and in general, freeing the memory should be the responsibility of that other somebody as well. Even if it is acceptable, you must also make sure that opAssign() and post-blit do the right thing: no two object should own the same piece of memory. Ali
Re: Defining event handlers for function, method, or shared method
On Tuesday, 26 January 2016 at 19:42:42 UTC, tcak wrote: On Tuesday, 26 January 2016 at 19:22:58 UTC, Ali Çehreli wrote: [...] Hmm. Your example works fine for functions, but I can't pass a method instead of function as alias. Check my example: [...] Edit: ... "I guess because it is runtime information, not compile time" ...
Re: Defining event handlers for function, method, or shared method
On Tuesday, 26 January 2016 at 19:22:58 UTC, Ali Çehreli wrote: On 01/26/2016 10:41 AM, tcak wrote: > I need/want this class to be able to bind > a function, a method, or a shared method. From the perspective of class > design, there shouldn't be any > difference. Its purpose is to let know about the event, not to care > about how the event > handler is designed. If I understand the problem correctly, an interface can define the interface and a templated class can provide the differences: import std.stdio; import std.algorithm; interface Event { void start(); void stop(); void itemAdded( size_t itemIndex ); } class ConcreteEvent(alias onStart, alias onStop, alias onItemAdded) : Event { void start() { onStart(); } void stop() { onStop(); } void itemAdded(size_t itemIndex) { itemAdded(itemIndex); } } void fooStart() { } void fooStop() { } void fooItemAdded(size_t itemIndex) { } void bar(size_t itemIndex) { } void main() { Event[] events; events ~= new ConcreteEvent!(fooStart, fooStop, fooItemAdded); struct S { void memberFunction() { } } auto s = S(); auto memberClosure(ref S s) {On 01/26/2016 10:41 AM, tcak wrote: > I need/want this class to be able to bind > a function, a method, or a shared method. From the perspective of class > design, there shouldn't be any > difference. Its purpose is to let know about the event, not to care > about how the event > handler is designed. If I understand the problem correctly, an interface can define the interface and a templated class can provide differences: import std.stdio; import std.algorithm; interface Event { void start(); void stop(); void itemAdded( size_t itemIndex ); } class ConcreteEvent(alias onStart, alias onStop, alias onItemAdded) : Event { void start() { onStart(); } void stop() { onStop(); } void itemAdded(size_t itemIndex) { itemAdded(itemIndex); } } void fooStart() { } void fooStop() { } void fooItemAdded(size_t itemIndex) { } void bar(size_t itemIndex) { } void main() { Event[] events; events ~= new ConcreteEvent!(fooStart, fooStop, fooItemAdded); struct S { void memberFunction() { } } auto s = S(); auto memberClosure(ref S s) { return () => s.memberFunction(); } events ~= new ConcreteEvent!(() => memberClosure(s), () => writeln("stop"), bar); events.each!(e => e.stop); } Ali return () => s.memberFunction(); } events ~= new ConcreteEvent!(() => memberClosure(s), () => writeln("stop"), bar); events.each!(e => e.stop); } Ali Hmm. Your example works fine for functions, but I can't pass a method instead of function as alias. Check my example: import std.socket; class EventClass{ public void eventHandlerMethod(){ writeln("Barking from method"); } } class Generator(alias eventHandler){ public void bark(){ eventHandler(); } } public void eventHandlerFunc(){ writeln("Barking from function"); } void main(){ auto events = new EventClass; auto gen1 = new Generator!( eventHandlerFunc )(); auto gen2 = new Generator!( events.eventHandlerMethod )(); gen1.bark(); gen2.bark(); } Error is given on "auto gen2 = ..." in main function due to passing method. I guess because it is runtime normal compile time information. I was looking for something like to be defined in the class Generator: public DelegateOnStart eventOnStart; So I could set eventOnStart as either function pointer, method pointer, or shared method pointer. To be able to support three of them, for every event, I need to define another variable, another alias, and while calling, check whichever variable (delegate pointer) is set, and call that one. I hope I am making it clear why it turns into mess.
Re: Defining event handlers for function, method, or shared method
On 01/26/2016 11:42 AM, tcak wrote: >> struct S { >> void memberFunction() { >> } >> } >> auto s = S(); >> >> auto memberClosure(ref S s) { >> return () => s.memberFunction(); >> } >> >> events ~= new ConcreteEvent!(() => memberClosure(s), >> () => writeln("stop"), >> bar); >> >> events.each!(e => e.stop); >> } >> >> Ali > Hmm. Your example works fine for functions, but I can't pass a method > instead of function as alias. That's why I used a closure in the example. > Check my example: > > > import std.socket; > > class EventClass{ > public void eventHandlerMethod(){ > writeln("Barking from method"); > } > } > > class Generator(alias eventHandler){ > public void bark(){ > eventHandler(); > } > } > > public void eventHandlerFunc(){ > writeln("Barking from function"); > } > > void main(){ > auto events = new EventClass; > > auto gen1 = new Generator!( eventHandlerFunc )(); > auto gen2 = new Generator!( events.eventHandlerMethod )(); As far as I know, just the member function name cannot be used that way. The problem boils down to how to create a type (or an alias) that will call a specific member function of a given object. One way is to have a dedicated type that always call foo(): import std.stdio; class C { void foo() { writeln("foo called"); } } class FooCaller { C c; this (C c) { this.c = c; } void call() { c.foo();// hard-coded to call foo() } } void main() { auto f = new FooCaller(new C()); f.call(); } The following one creates a lambda (closure in this case?) that allows the user to pick which member function to call. Admittedly, CallableCaller() is not really needed in this example but it demonstrates how "a member function call on a specific object" can be passed as an alias template parameter: import std.stdio; class C { void foo() { writeln("foo called"); } } class CallableCaller(alias closure) { void call() { closure(); } } void main() { auto c = new C(); auto f = new CallableCaller!(() => c.foo()); f.call(); } Ali
Re: free causes exception
On 1/26/16 9:20 AM, Igor wrote: I have successfully malloc'ed an object but when I go to free it in the destructor I get an exception. The destructor simply has ~this() // destructor for Foo { core.stdc.stdlib.free(); } auto buffer = core.stdc.stdlib.malloc(__traits(classInstanceSize, App))[0..__traits(classInstanceSize, App)]; auto app = cast(App)emplace!App(buffer[]); I tried to retain a ptr to buffer and free that but still no good. I also get a depreciation warning that is not an lvalue. Hopefully I don't have to keep a ptr around to this simply to free it and avoid future issues? So how am I suppose to free an object? Don't do it in the destructor. I can only imagine that you are triggering the destructor with destroy? In this case, destroy is calling the destructor, but then tries to zero the memory (which has already been freed). There is a mechanism D supports (but I believe is deprecated) by overriding new and delete. You may want to try that. It's deprecated, but has been for years and years, and I doubt it's going away any time soon. A class shouldn't care how it's allocated or destroyed. That is for the memory manager to worry about. -Steve
Re: Speed of csvReader
On Tue, 26 Jan 2016 18:16:28 +, Gerald Jansen wrote: > On Thursday, 21 January 2016 at 21:24:49 UTC, H. S. Teoh wrote: >> >> While this is no fancy range-based code, and one might say it's more >> hackish and C-like than idiomatic D, the problem is that current D >> compilers can't quite optimize range-based code to this extent yet. >> Perhaps in the future optimizers will improve so that more idiomiatic, >> range-based code will have comparable performance with fastcsv. (At >> least in theory this should be possible.) > > As a D novice still struggling with the concept that composable > range-based functions can be more efficient than good-old looping (ya, I > know, cache friendliness and GC avoidance), I find it extremely > interesting that someone as expert as yourself would reach for a C-like > approach for serious data crunching. Given that data crunching is the > kind of thing I need to do a lot, I'm wondering how general your > statement above might be at this time w.r.t. this and possibly other > domains. You want to reduce allocations. Ranges often let you do that. However, it's sometimes unsafe to reuse range values that aren't immutable. That means, if you want to keep the values around, you need to copy them -- which introduces an allocation. You can get fewer large allocations by reading the whole file at once manually and using slices into that large allocation.
Re: free causes exception
On Tuesday, 26 January 2016 at 20:17:20 UTC, Steven Schveighoffer wrote: On 1/26/16 9:20 AM, Igor wrote: I have successfully malloc'ed an object but when I go to free it in the destructor I get an exception. The destructor simply has ~this() // destructor for Foo { core.stdc.stdlib.free(); } auto buffer = core.stdc.stdlib.malloc(__traits(classInstanceSize, App))[0..__traits(classInstanceSize, App)]; auto app = cast(App)emplace!App(buffer[]); I tried to retain a ptr to buffer and free that but still no good. I also get a depreciation warning that is not an lvalue. Hopefully I don't have to keep a ptr around to this simply to free it and avoid future issues? So how am I suppose to free an object? Don't do it in the destructor. I can only imagine that you are triggering the destructor with destroy? In this case, destroy is calling the destructor, but then tries to zero the memory (which has already been freed). There is a mechanism D supports (but I believe is deprecated) by overriding new and delete. You may want to try that. It's deprecated, but has been for years and years, and I doubt it's going away any time soon. A class shouldn't care how it's allocated or destroyed. That is for the memory manager to worry about. um? Memory manager? I am doing it manually C++ style so I don't have to worry about the god forsaken memory manager. Why is it so difficult? I create the object and release it when I need to. I can replace the destroy(f) with free(inline the code) but I don't see why that should matter. The whole point of destructors is to do this sort of stuff. That's why they were invented in the first place!?!
Re: free causes exception
On Tuesday, 26 January 2016 at 19:34:22 UTC, Ali Çehreli wrote: On 01/26/2016 06:20 AM, Igor wrote: > I have successfully malloc'ed an object but when I go to free it in the > destructor I get an exception. The destructor simply has > > ~this() // destructor for Foo > { > core.stdc.stdlib.free(); > } That design suggests a complexity regarding object responsibilities: Assuming that the object was constructed on a piece of memory that it did *not* allocate, the memory was owned by somebody else. In that case and in general, freeing the memory should be the responsibility of that other somebody as well. Even if it is acceptable, you must also make sure that opAssign() and post-blit do the right thing: no two object should own the same piece of memory. Ali That shouldn't be the case. I allocate in a static method called New once. I then deallocate in the destructor. Basically just as one would do in C++. I'm not sure about opAssign and post-blit class Foo { ~this() // destructor for Foo { core.stdc.stdlib.free(cast(void *)this); } // Creates a Foo static public Foo New() { auto buffer = core.stdc.stdlib.malloc(__traits(classInstanceSize, Foo))[0..__traits(classInstanceSize, Foo)]; auto app = cast(Foo)emplace!Foo(buffer[]); } } hence auto f = Foo.New(); then .destroy(f); which is where the crash happens. If I don't destroy, it works fine + memory leak.
Re: free causes exception
On Tuesday, 26 January 2016 at 21:23:28 UTC, Igor wrote: On Tuesday, 26 January 2016 at 20:17:20 UTC, Steven Schveighoffer wrote: On 1/26/16 9:20 AM, Igor wrote: I have successfully malloc'ed an object but when I go to free it in the destructor I get an exception. The destructor simply has ~this() // destructor for Foo { core.stdc.stdlib.free(); } auto buffer = core.stdc.stdlib.malloc(__traits(classInstanceSize, App))[0..__traits(classInstanceSize, App)]; auto app = cast(App)emplace!App(buffer[]); I tried to retain a ptr to buffer and free that but still no good. I also get a depreciation warning that is not an lvalue. Hopefully I don't have to keep a ptr around to this simply to free it and avoid future issues? So how am I suppose to free an object? Don't do it in the destructor. I can only imagine that you are triggering the destructor with destroy? In this case, destroy is calling the destructor, but then tries to zero the memory (which has already been freed). There is a mechanism D supports (but I believe is deprecated) by overriding new and delete. You may want to try that. It's deprecated, but has been for years and years, and I doubt it's going away any time soon. A class shouldn't care how it's allocated or destroyed. That is for the memory manager to worry about. um? Memory manager? I am doing it manually C++ style so I don't have to worry about the god forsaken memory manager. Why is it so difficult? I create the object and release it when I need to. I can replace the destroy(f) with free(inline the code) but I don't see why that should matter. The whole point of destructors is to do this sort of stuff. That's why they were invented in the first place!?! Why not simply: class Foo { this(Arg1, Arg2) { ... } ... } // Option A: import std.typecons : scoped; auto foo = scoped!Foo(arg1, arg2); // Option B: import std.experimental.allocator : make, dispose; import std.experimental.allocator.mallocator; auto foo = Mallocator.instance.make!Foo(arg1, arg2); scope(exit) Mallocator.instance.dispose(foo); http://dlang.org/phobos/std_typecons#.scoped http://dlang.org/phobos/std_experimental_allocator
How do you link with GtkD in VisualD?
I'm getting: SeverityCodeDescription Project FileLine Error Error 42: Symbol Undefined _D3gtk4Main12__ModuleInfoZ C:\MyProjects\___LIGHTSHOWAPP\WindowsApp1\ Error Error 42: Symbol Undefined _D3gtk5Label5Label7__ClassZ C:\MyProjects\___LIGHTSHOWAPP\WindowsApp1\ Error Error 42: Symbol Undefined _D3gtk4Main4Main4initFKAAyaZv (void gtk.Main.Main.init(ref immutable(char)[][])) C:\MyProjects\___LIGHTSHOWAPP\WindowsApp1\ Error Error 42: Symbol Undefined _D3gtk5Label5Label6__ctorMFAyabZC3gtk5Label5Label (gtk.Label.Label gtk.Label.Label.__ctor(immutable(char)[], bool)) C:\MyProjects\___LIGHTSHOWAPP\WindowsApp1\ Error Error 42: Symbol Undefined _D3gtk10MainWindow10MainWindow7__ClassZ C:\MyProjects\___LIGHTSHOWAPP\WindowsApp1\ Error Error 42: Symbol Undefined _D3gtk10MainWindow10MainWindow6__ctorMFAyaZC3gtk10MainWindow10MainWindow (gtk.MainWindow.MainWindow gtk.MainWindow.MainWindow.__ctor(immutable(char)[])) C:\MyProjects\___LIGHTSHOWAPP\WindowsApp1\ Error Error 42: Symbol Undefined _D3gtk4Main4Main3runFZv (void gtk.Main.Main.run()) C:\MyProjects\___LIGHTSHOWAPP\WindowsApp1\ Error Error 42: Symbol Undefined _D3gtk5Label12__ModuleInfoZ C:\MyProjects\___LIGHTSHOWAPP\WindowsApp1\ Error Error 42: Symbol Undefined _D3gtk10MainWindow12__ModuleInfoZ C:\MyProjects\___LIGHTSHOWAPP\WindowsApp1\ For: import gtk.MainWindow; import gtk.Label; import gtk.Main; void main(string[] args) { Main.init(args); MainWindow win = new MainWindow("Hello World"); win.setDefaultSize(200, 100); win.add(new Label("Hello World")); win.showAll(); Main.run(); } After setting Project Properties > Linker > General > Library Files: gtkd
Re: free causes exception
On Tuesday, 26 January 2016 at 21:23:28 UTC, Igor wrote: On Tuesday, 26 January 2016 at 20:17:20 UTC, Steven Schveighoffer wrote: On 1/26/16 9:20 AM, Igor wrote: [...] Don't do it in the destructor. I can only imagine that you are triggering the destructor with destroy? In this case, destroy is calling the destructor, but then tries to zero the memory (which has already been freed). There is a mechanism D supports (but I believe is deprecated) by overriding new and delete. You may want to try that. It's deprecated, but has been for years and years, and I doubt it's going away any time soon. A class shouldn't care how it's allocated or destroyed. That is for the memory manager to worry about. um? Memory manager? I am doing it manually C++ style so I don't have to worry about the god forsaken memory manager. Why is it so difficult? I create the object and release it when I need to. I can replace the destroy(f) with free(inline the code) but I don't see why that should matter. The whole point of destructors is to do this sort of stuff. That's why they were invented in the first place!?! Destructors are meant to destroy the members of the object, not the object itself. An object should be freed by the destructor of its owner and so on, transitively. A class should not have a hard coded dependency on malloc/free, or the GC. You should strive to design it in such a way that the clients of the class are free to decide how to manage its memory.
Re: How do you link with GtkD in VisualD?
On Tuesday, 26 January 2016 at 22:04:55 UTC, Enjoys Math wrote: [...] Okay, fixed by changing 'gtkd' setting to 'gtkd.lib'.
Re: nogc Array
On Tuesday, 26 January 2016 at 03:03:40 UTC, Igor wrote: Is there a GC-less array that we can use out of the box or do I have to create my own? If you want containers, use: http://code.dlang.org/packages/emsi_containers If you just need an array, use: http://dlang.org/phobos/std_experimental_allocator#.makeArray
Re: Speed of csvReader
On Tuesday, 26 January 2016 at 20:54:34 UTC, Chris Wright wrote: On Tue, 26 Jan 2016 18:16:28 +, Gerald Jansen wrote: On Thursday, 21 January 2016 at 21:24:49 UTC, H. S. Teoh wrote: While this is no fancy range-based code, and one might say it's more hackish and C-like than idiomatic D, the problem is that current D compilers can't quite optimize range-based code to this extent yet. Perhaps in the future optimizers will improve so that more idiomiatic, range-based code will have comparable performance with fastcsv. ... data crunching ... I'm wondering how general your statement above might be at this time w.r.t. this and possibly other domains. You can get fewer large allocations by reading the whole file at once manually and using slices into that large allocation. Sure, that part is clear. Presumably the quoted comment referred to more than just that technique.
gtkd.lib: Error 43: Not a Valid Library File
I get this message either compiling at command line -or- in VisualD. At command line when I add -m64, I get another error: C:\MyProjects\___LIGHTSHOWAPP\___LIGHTSHOWAPP>dmd -m64 main.d -L+gtkd LINK : fatal error LNK1181: cannot open input file '+gtkd.obj' --- errorlevel 1181
Re: free causes exception
On 01/26/2016 01:21 PM, Igor wrote: > I allocate in a static method called New once. I then deallocate in the > destructor. Basically just as one would do in C++. I would never do that in even C++. I don't know any C++ idiom that warrants 'delete this' where superior alternatives cannot be used. > class Foo > { > ~this() // destructor for Foo > { > core.stdc.stdlib.free(cast(void *)this); > } > > // Creates a Foo > static public Foo New() > { > auto buffer = > core.stdc.stdlib.malloc(__traits(classInstanceSize, > Foo))[0..__traits(classInstanceSize, Foo)]; > auto app = cast(Foo)emplace!Foo(buffer[]); > } > } > > hence > > auto f = Foo.New(); > > then .destroy(f); Something else in the program must have something to do with it. I don't see the crash with the following program: import std.stdio; import core.stdc.stdlib; import std.conv; class Foo { ~this() // destructor for Foo { core.stdc.stdlib.free(cast(void *)this); } // Creates a Foo static public Foo New() { auto buffer = core.stdc.stdlib.malloc( __traits(classInstanceSize, Foo)) [0..__traits(classInstanceSize, Foo)]; auto app = cast(Foo)emplace!Foo(buffer[]); return app; } } void main() { auto f = Foo.New(); .destroy(f); } Ali
Re: gtkd.lib: Error 43: Not a Valid Library File
On Tuesday, 26 January 2016 at 22:10:42 UTC, Enjoys Math wrote: I get this message either compiling at command line -or- in VisualD. At command line when I add -m64, I get another error: C:\MyProjects\___LIGHTSHOWAPP\___LIGHTSHOWAPP>dmd -m64 main.d -L+gtkd LINK : fatal error LNK1181: cannot open input file '+gtkd.obj' --- errorlevel 1181 Got it to compile and run at command line! The proper command line is: dmd main.d -m64 -Lgtkd.lib (without +, with .lib)
Re: Speed of csvReader
On Tue, Jan 26, 2016 at 08:54:34PM +, Chris Wright via Digitalmars-d-learn wrote: > On Tue, 26 Jan 2016 18:16:28 +, Gerald Jansen wrote: > > > On Thursday, 21 January 2016 at 21:24:49 UTC, H. S. Teoh wrote: > >> > >> While this is no fancy range-based code, and one might say it's > >> more hackish and C-like than idiomatic D, the problem is that > >> current D compilers can't quite optimize range-based code to this > >> extent yet. Perhaps in the future optimizers will improve so that > >> more idiomiatic, range-based code will have comparable performance > >> with fastcsv. (At least in theory this should be possible.) > > > > As a D novice still struggling with the concept that composable > > range-based functions can be more efficient than good-old looping > > (ya, I know, cache friendliness and GC avoidance), I find it > > extremely interesting that someone as expert as yourself would reach > > for a C-like approach for serious data crunching. Given that data > > crunching is the kind of thing I need to do a lot, I'm wondering how > > general your statement above might be at this time w.r.t. this and > > possibly other domains. > > You want to reduce allocations. Ranges often let you do that. However, > it's sometimes unsafe to reuse range values that aren't immutable. > That means, if you want to keep the values around, you need to copy > them -- which introduces an allocation. > > You can get fewer large allocations by reading the whole file at once > manually and using slices into that large allocation. Yeah, in the course of this exercise, I found that the one thing that has had the biggest impact on performance is the amount of allocations involved. Basically, I noted that the less allocations are made, the more efficient the code. I'm not sure exactly why this is so, but it's probably something to do with the fact that tracing GCs work better with fewer allocations of larger objects, than many allocations of small objects. I have also noted in the past that D's current GC runs collections a little too often; in past projects I've obtained significant speedup (in one case, up to 40% reduction of total runtime) by suppressing automatic collections and scheduling them manually at a lower frequency. In short, I've found that reducing GC load plays a much bigger role in performance than the range vs. loops issue. The reason I chose to write manual loops at first is to eliminate all possibility of unexpected overhead that might hide behind range primitives, as well as compiler limitations, as current optimizers aren't exactly tuned for range-based idioms, and may fail to recognize certain range-based idioms that would lead to much more efficient code. However, in my second iteration when I made the fastcsv parser return an input range instead of an array, I found only negligible performance differences. This suggests that perhaps range-based code may not perform that badly after all. I have yet to test this hypothesis, as the inner loop that parses fields in a single row is still a manual loop; but my suspicion is that it wouldn't do too badly in range-based form either. What might make a big difference, though, is the part where slicing is used, since that is essential for reducing the number of allocations. The current iteration of struct-based parsing code, for instance, went through an initial version that was excruciatingly slow for structs with string fields. Why? Because the function takes const(char)[] as input, and you can't legally get strings out of that unless you make a copy of that data (since const means you cannot modify it, but somebody else still might). So std.conv.to would allocate a new string and copy the contents over, every time a string field was parsed, resulting in a large number of small allocations. To solve this, I decided to use a string buffer: instead of one allocation per string, pre-allocate a large-ish char[] buffer, and every time a string field was parsed, append the data into the buffer. If the buffer becomes full, allocate a new one. Take a slice of the buffer corresponding to that field and cast it to string (this is safe since the algorithm was constructed never to write over previous parts of the buffer). This seemingly trivial optimization won me a performance improvement of an order of magnitude(!). This is particularly enlightening, since it suggests that even the overhead of copying all the string fields out of the original data into a new buffer does not add up to that much. The new struct-based parser also returns an input range rather than an array; I found that constructing the array directly vs. copying from an input range didn't really make that big of a difference either. What did make a huge difference is reducing the number of allocations. So the moral of the story is: avoid large numbers of small allocations. If you have to do it, consider consolidating your allocations into a series of allocations of large(ish) buffers
attributes and properties lookup order
Hello $ cat t.d import std.net.curl: get; void main() { string[string] x; string y = x.get("",""); } $ dmd t.d t.d(6): Error: template std.net.curl.get cannot deduce function from argument types !()(string[string], string, string), candidates are: /usr/include/dmd/phobos/std/net/curl.d(527): std.net.curl.get(Conn = AutoProtocol, T = char)(const(char)[] url, Conn conn = Conn()) if (isCurlConn!Conn && (is(T == char) || is(T == ubyte))) It is strange that AA property 'get' is not considered first.
Not getting expected behavior from compile-time conditional
Here's a simple programming showing where I'm tripping up - void test(T)(in T value){ import std.traits; static if(is(T == char)){ writeln("char"); }else static if(is(isNumeric!(T))){ writeln("number"); } writeln("hi"); } public void main(){ test('g'); test(2); test(2.0); } Output is this - char hi hi hi I was expecting output to look like this - char hi number hi number hi How can I fix this?
Re: Not getting expected behavior from compile-time conditional
On 01/26/2016 04:12 PM, pineapple wrote: > Here's a simple programming showing where I'm tripping up - > > void test(T)(in T value){ > import std.traits; > static if(is(T == char)){ > writeln("char"); > }else static if(is(isNumeric!(T))){ Remove the extra is: :) }else static if(isNumeric!(T)){ Ali
Re: free causes exception
On Tuesday, 26 January 2016 at 21:23:28 UTC, Igor wrote: um? Memory manager? I am doing it manually C++ style so I don't have to worry about the god forsaken memory manager. Why is it so difficult? I create the object and release it when I need to. He's talking about *your* memory manager, whatever system you have set up to allocate and deallocate memory. I can replace the destroy(f) with free(inline the code) but I don't see why that should matter. The whole point of destructors is to do this sort of stuff. That's why they were invented in the first place!?! Not in D! You have to get your mind out of C++ mode when programming in D. D is not C++, no matter how similar they are, and there are idioms that work well in C++ that do not work in D. There are cases where D's destructors behave like those in C++, but not always. Since this approach is failing for you, I suggest you make a function or template that can take any object you've manually allocated, call destroy on it, then deallocate it. The destructor can still clean up any resources the object maintains, but the responsibility for deallocating the object will be taken out of the destructor. It also ensures that deallocation does not interfere with the operation of destroy.
Re: Not getting expected behavior from compile-time conditional
On Wednesday, 27 January 2016 at 00:17:18 UTC, Ali Çehreli wrote: Remove the extra is: :) Huh, I swear I tried that. Thanks!
Re: gtkd.lib: Error 43: Not a Valid Library File
On Wednesday, 27 January 2016 at 01:20:49 UTC, Mike Parker wrote: has no connection library files has no relationship with library files What I mean is it is not used to specify libraries.
Re: gtkd.lib: Error 43: Not a Valid Library File
On Tuesday, 26 January 2016 at 22:30:24 UTC, Enjoys Math wrote: On Tuesday, 26 January 2016 at 22:10:42 UTC, Enjoys Math wrote: I get this message either compiling at command line -or- in VisualD. At command line when I add -m64, I get another error: C:\MyProjects\___LIGHTSHOWAPP\___LIGHTSHOWAPP>dmd -m64 main.d -L+gtkd LINK : fatal error LNK1181: cannot open input file '+gtkd.obj' --- errorlevel 1181 Got it to compile and run at command line! The proper command line is: dmd main.d -m64 -Lgtkd.lib (without +, with .lib) You appear to have a lack of understanding of linker options. If I'm wrong, just ignore the rest of this post. -L tells DMD to pass an argument to the linker. Each linker it uses accepts options in a different format. The + you used above has no connection library files on any linker. It's used by OPTLINK, the default linker DMD uses, to set a path on which to search for libraries. So, if you had all of your libraries in C:\mylibs, then you could pass this to dmd: dmd -L+C:\mylibs main.d -Lgtkd.lib After compiling main.d, DMD will call optlink with +C\mylibs and, assuming gtkd.lib is in that directory, optlink will find it. When you use -m64 (or -m32mscoff), DMD is using the Microsoft Linker. It will not recognize the +, as it has a different syntax for specifying the path. dmd -L/LIBPATH:C:\mylibs main.d -Lgtkd.lib In both cases, you can actually drop the -L when specifying the libraries: dmd -L+C:\mylibs main.d gtkd.lib dmd -L/LIBPATH:C:\mylibs main.d gtkd.lib Here, dmd will recognize the .lib extension and will pass the library names to the linker without the need for -L. When compiling on other platforms where DMD uses the GNU (or compatible) linker, it would look like this: dmd -L-L/path/to/mylibs -L-lgtkd This linker accepts -L as the switch to specify the path, so -L-L tells DMD to send that on. It also requires -l (lowercase l) to specify libraries, so -L-l will do that. The linker will actually convert the 'gtkd' string to libgtkd.a or libgtkd.so. I can't recall if passing either, with the extension, on the command line without -L-l (e.g. libgtkd.a or libgtkd.so) works or not.
How do you draw in gtkD? Simple example overriding Widget.draw() doesn't compile.
import gtk.MainWindow; import gtk.Main; import gtk.DrawingArea; import cairo.Context; import std.stdio; void main(string[] args) { Main.init(args); auto win = new MainWindow("Hello World"); win.setDefaultSize(200, 100); win.add(new MyDrawingArea()); win.showAll(); Main.run(); } class MyDrawingArea : DrawingArea { override bool draw(Context cairo) { writeln("Hello"); return true; } } Error: Error: function main.MyDrawingArea.draw does not override any function, did you mean to override 'gtk.Widget.Widget.draw'?
Re: How do you draw in gtkD? Simple example overriding Widget.draw() doesn't compile.
On Wednesday, 27 January 2016 at 01:54:53 UTC, Enjoys Math wrote: import gtk.MainWindow; import gtk.Main; import gtk.DrawingArea; import cairo.Context; import std.stdio; void main(string[] args) { Main.init(args); auto win = new MainWindow("Hello World"); win.setDefaultSize(200, 100); win.add(new MyDrawingArea()); win.showAll(); Main.run(); } class MyDrawingArea : DrawingArea { override bool draw(Context cairo) { writeln("Hello"); return true; } } Error: Error: function main.MyDrawingArea.draw does not override any function, did you mean to override 'gtk.Widget.Widget.draw'? Oh i see, there are examples under the GDk directory under 'demos'.
Re: Improving CSV parsing performance, Episode 2 (Was: Re: Speed of csvReader)
On Tuesday, 26 January 2016 at 06:27:49 UTC, H. S. Teoh wrote: My thought is to integrate the fastcsv code into std.csv, such that the current std.csv code will serve as fallback in the cases where fastcsv's limitations would prevent it from being used, with fastcsv being chosen where possible. Wouldn't it be simpler to add a new function? Otherwise you'll end up with very different performance for almost the same data.
Re: D Dll's usefulness
On Monday, 25 January 2016 at 19:45:21 UTC, Igor wrote: Am I off target here? Dlls are currently not properly supported in D, I would strongly advice against using them. Just link everything statically and be happy for now. Kind Regards Benjamin Thaut