Re: Dispatching values to handlers, as in std.concurrency
On Tuesday, 7 May 2013 at 00:15:06 UTC, Luís Marques wrote: On Monday, 6 May 2013 at 23:53:51 UTC, Idan Arye wrote: If the type handlers are your own classes, then you can let them check it. Have a method in the handlers that check if an object can be handled by that handler, and use it on each handler until you find one that fits. I don't understand. Imagine I have: class X { void handleFoo(Foo msg) { ... } void handleBar(Bar msg) { ... } } I want to register an instance of X to receive messages of type Foo (or subclass) and messages of type Bar (or subclass) in the respective handler methods. Where are you proposing for your check to be implemented? I assume that `typeHandler` in your original code is *not* of type `X` - since it has a single `handler` method while `X` has two, with different names. That means that at some point, you had to create it - let's assume it's type is called `TypeHandler`. There is either a global function, static method, or constructor where you create a `TypeHandler` and pass to it the delegate you want to register. Now, if that function/method/constructor is templated - than you already have at compile time the type you want to handle, so you can prepare the check there(anon function?) If it's not templated - make it templated! You don't have to make the entire `TypeHanler` templated, just the method that creates it. There, you can create an anonymous function that receives `Object` and returns `bool` and all it does is check for type, and you can have a field in `TypeHandler` that keeps that function and uses it to check if it can handle a certain type.
Argument S to typeof is not an expression
template Test(alias N) if (isIntegral!(typeof(N))) { struct S { typeof(N) n = N; auto opAdd(T)(T rhs) { //Error: argument S to typeof is not an expression pragma(msg, typeof(T)); //Error: variable rhs cannot be read at compile time return Test!(n + rhs.n); } } auto st = S(N); alias Test = st; } void main() { auto a = Test!2; auto b = Test!3; writeln(typeof(a).stringof ~ a = , a, , , typeof(b).stringof ~ b = , b, , , typeof(a + b).stringof ~ a + b = ); } I don't really understand why either of these error messages are occurring. The first is just incomprehensible, and the second seems like it should work. In this case, rhs is fully accessible at compile time in the expression (a + b), so why does the compiler complain?
Re: Argument S to typeof is not an expression
On Tuesday, 7 May 2013 at 06:41:25 UTC, Meta wrote: template Test(alias N) if (isIntegral!(typeof(N))) { struct S { typeof(N) n = N; auto opAdd(T)(T rhs) { //Error: argument S to typeof is not an expression pragma(msg, typeof(T)); //Error: variable rhs cannot be read at compile time return Test!(n + rhs.n); } } auto st = S(N); alias Test = st; } void main() { auto a = Test!2; auto b = Test!3; writeln(typeof(a).stringof ~ a = , a, , , typeof(b).stringof ~ b = , b, , , typeof(a + b).stringof ~ a + b = ); } I don't really understand why either of these error messages are occurring. The first is just incomprehensible, and the second seems like it should work. In this case, rhs is fully accessible at compile time in the expression (a + b), so why does the compiler complain? First error occures,because typeof(T) is undefined - T is a type,not value. About second error,although in this case rhs is accessible,compiler can't know that you won't call this function in runtime,so it's expected - it's just ordinary function.
Re: Argument S to typeof is not an expression
Sorry for my english.
How to reserve memory for a slice in a struct
Hello, I am new to D. According to that power of 2 rule I want to reserve 2 sized chunks to my array, But how do I do that in a struct? Say: struct Stack(int){ int a[]; } Where do I put that a.reserve(2); Because right after the declaration of a I get an error Error: unexpected ( in declarator Error: basic type expected, not 2 Error: found '2' when expecting ')' Error: no identifier for declarator a.reserve(int) Error: semicolon expected following function declaration Error: Declaration expected, not ')'
Re: Argument S to typeof is not an expression
On Tuesday, 7 May 2013 at 06:41:25 UTC, Meta wrote: I don't really understand why either of these error messages are occurring. The first is just incomprehensible, and the second seems like it should work. In this case, rhs is fully accessible at compile time in the expression (a + b), so why does the compiler complain? 1) typeof don't work on types. Period. It is often inconvenient in generic code (I'd love it typeof(T) to be T for simplicity) but it is how it is done now. In your case pragma(msg, T) will be correct one. 2) template parameter must be known at compile time. rhs is a plain function parameter, so compiler can't be sure it is known at compile time, so it is an error. Same goes for n. In general, only enum's and template parameters can be assumed to be known at compile-time. Your code seems to wrongly mix plain variables with template code all over. If you can explain for behavior/API you are trying to achieve, most likely I'll be able to provide a more idiomatic D solution.
Re: How to reserve memory for a slice in a struct
On Tuesday, 7 May 2013 at 10:29:44 UTC, Namal wrote: Hello, I am new to D. According to that power of 2 rule I want to reserve 2 sized chunks to my array, But how do I do that in a struct? Say: struct Stack(int){ int a[]; } 2 sized chunks? Perhaps you want something like this: struct Stack{ int a[]; this(size_t r) { a.reserve(r); } } void main() { auto s = Stack(2); }
Re: Argument S to typeof is not an expression
On 2013-05-07 08:41, Meta wrote: template Test(alias N) if (isIntegral!(typeof(N))) { struct S { typeof(N) n = N; auto opAdd(T)(T rhs) { //Error: argument S to typeof is not an expression pragma(msg, typeof(T)); //Error: variable rhs cannot be read at compile time return Test!(n + rhs.n); } } auto st = S(N); alias Test = st; } void main() { auto a = Test!2; auto b = Test!3; writeln(typeof(a).stringof ~ a = , a, , , typeof(b).stringof ~ b = , b, , , typeof(a + b).stringof ~ a + b = ); } I don't really understand why either of these error messages are occurring. The first is just incomprehensible, and the second seems like it should work. In this case, rhs is fully accessible at compile time in the expression (a + b), so why does the compiler complain? As a workaround for typeof you can use this: https://github.com/jacob-carlborg/orange/blob/master/orange/util/Traits.d#L213 -- /Jacob Carlborg
Re: Argument S to typeof is not an expression
On Tuesday, 7 May 2013 at 11:03:31 UTC, Jacob Carlborg wrote: As a workaround for typeof you can use this: https://github.com/jacob-carlborg/orange/blob/master/orange/util/Traits.d#L213 You may want to update your implementation: http://dpaste.1azy.net/640a2580
Re: How to reserve memory for a slice in a struct
On Tuesday, 7 May 2013 at 10:58:42 UTC, John Colvin wrote: ... int a[]; please don't use C style declarations, D style is type followed by id: int[] a;
Re: How to reserve memory for a slice in a struct
On Tue, 07 May 2013 06:29:43 -0400, Namal soti...@mail.ru wrote: Hello, I am new to D. According to that power of 2 rule I want to reserve 2 sized chunks to my array, But how do I do that in a struct? Say: struct Stack(int){ int a[]; } Where do I put that a.reserve(2); Because right after the declaration of a I get an error Error: unexpected ( in declarator Error: basic type expected, not 2 Error: found '2' when expecting ')' Error: no identifier for declarator a.reserve(int) Error: semicolon expected following function declaration Error: Declaration expected, not ')' You cannot statically reserve heap space for any type. You have two choices: 1. make 'a' a fixed sized array (this reserves space inside the struct): int[2] a; 2. reserve space at runtime (e.g. during constructor): this(size_t n) { a.reserve(n); } Unfortunately, structs have no default constructor, so you can't specify that a *always* is reserved. A note of caution -- reserving space via a.reserve does *not* give you access to the space, it just reserves a block for your use to append the slice into the array. So for example: a.reserve(2); assert(a.length == 0); // length is still 0. assert(a.ptr !is null); // but block has been allocated with at least 2 elements. a ~= 1; // pointer has not changed, a is now filling into allocated block. If you want to reserve accessible space, set the length: a.length = 2; One other thing, the space you reserve is not exactly a power of 2. It will be 2^^n - 1. This is due to requirements of the array runtime. The minimal heap space for an int array is 3. Then it goes 7, 15, 31, etc. Once you get to page size, the amount of space you can reserve grows linearly. These are implementation details of the GC, so you shouldn't depend on this never changing. In any case, whatever space you request, the GC will give you at LEAST that much. -Steve
Re: How to reserve memory for a slice in a struct
On Tuesday, 7 May 2013 at 10:29:44 UTC, Namal wrote: Hello, I am new to D. According to that power of 2 rule I want to reserve 2 sized chunks to my array, But how do I do that in a struct? You can set some kind of statically allocated array size: struct S { int[] a; this(size_t size) { a.length = size; } } enum SE : S { A = S(2) } static assert(SE.init.a.length is 2); void main() { SE se; assert(se.a.length is 2); } Unfortunately this does not work with array reserve.
Re: WinAPI callbacks and GC
On Tue, 07 May 2013 00:03:58 +0100, Sean Kelly s...@invisibleduck.org wrote: On May 2, 2013, at 6:17 AM, Regan Heath re...@netmail.co.nz wrote: On Wed, 01 May 2013 01:12:39 +0100, Sean Kelly s...@invisibleduck.org wrote: On Apr 23, 2013, at 2:21 PM, Jack Applegame jappleg...@gmail.com wrote: According WinAPI documentation, CtrlHandler will be called in new additional thread. Is it safe to allocate GC memory in NOT Phobos threads? If not, how to make it safe? I'm trying call thread_attachThis() at the beginning of CtrlHandler fucntion, but it doesn't compile because thread_attachThis() is not no throw. thread_attachThis should probably just be labeled nothrow. I don't think there's anything in that function that can throw an Exception. That makes it callable.. but did you see my post about the various timing issues with using this in a non-GC thread (potentially while the GC is already collecting - or similar). The GC holds a lock on the global thread list while collecting, so it shouldn't be possible for thread_attachThis to register a thread when this is happening. In fact, thread_attachThis even temporarily disables the GC, and since this operation is protected by the GC lock, it's blocked there as well. Excellent. Might be nice to see some of these details in the docs :p .. or even just a will block if collection is in progress. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
unittest + struct ctorю + nested mixin template + alias
Version D 2.062 class MyClass {} struct MyStruct(T) if (is(T == class)) { string _message = nothing; this(T obj) { if (obj is null){ _message = Null reference message; } else{ _message = All right message; } } mixin Foo!(); private mixin template Foo() { void foo() {} } } unittest { alias MyStruct!MyClass StructType; auto inst = StructType(null); string msg = inst._message; // Wrong value! } The behavior varies between executions: sometimes msg contains empty string, in other times it holds nothing. If StructType is replaced with MyStruct!MyClass then everything works as expected. auto inst = MyStruct!MyClass(null); // OK If declaration of the Foo template is moved out of struct MyStruct(T) definition, everything works fine too. This strange behavior is observed only in unittest block, not when executed in main(). Am I doing something incorrectly or is this a bug?
Re: Argument S to typeof is not an expression
On Tuesday, 7 May 2013 at 10:33:58 UTC, Dicebot wrote: On Tuesday, 7 May 2013 at 06:41:25 UTC, Meta wrote: I don't really understand why either of these error messages are occurring. The first is just incomprehensible, and the second seems like it should work. In this case, rhs is fully accessible at compile time in the expression (a + b), so why does the compiler complain? 1) typeof don't work on types. Period. It is often inconvenient in generic code (I'd love it typeof(T) to be T for simplicity) but it is how it is done now. In your case pragma(msg, T) will be correct one. 2) template parameter must be known at compile time. rhs is a plain function parameter, so compiler can't be sure it is known at compile time, so it is an error. Same goes for n. In general, only enum's and template parameters can be assumed to be known at compile-time. Your code seems to wrongly mix plain variables with template code all over. If you can explain for behavior/API you are trying to achieve, most likely I'll be able to provide a more idiomatic D solution. This is a little test to see if I can wrap types in structs and do some checking at compile time. For example, statically verifying in opAdd that neither number being added is negative. I added in the pragma to see what T's type is because I had the example compiling before, but two S structs added together was giving a result of void, and I was trying to figure out why that was happening.
Re: unittest + struct ctorю + nested mixin template + alias
On Tue, 07 May 2013 10:58:09 -0400, ref2401 refacto...@gmail.com wrote: Version D 2.062 class MyClass {} struct MyStruct(T) if (is(T == class)) { string _message = nothing; this(T obj) { if (obj is null){ _message = Null reference message; } else{ _message = All right message; } } mixin Foo!(); private mixin template Foo() { void foo() {} } } unittest { alias MyStruct!MyClass StructType; auto inst = StructType(null); string msg = inst._message; // Wrong value! } The behavior varies between executions: sometimes msg contains empty string, in other times it holds nothing. If StructType is replaced with MyStruct!MyClass then everything works as expected. auto inst = MyStruct!MyClass(null); // OK If declaration of the Foo template is moved out of struct MyStruct(T) definition, everything works fine too. This strange behavior is observed only in unittest block, not when executed in main(). Am I doing something incorrectly or is this a bug? How are you determining that _message is wrong? I see no observable printouts or anything. It may be that if you are using a debugger, the debugger can't handle the mixin and is looking at the wrong data, or maybe the compiler is outputting wrong debug info. If I put this line in, it never asserts: assert(msg == Null reference message); I think the compiler is outputting correct code. I don't have 2.062, only the beta, and 2.061. Tested with the latest beta. -Steve
Re: unittest + struct ctorю + nested mixin template + alias
i'm using VisualD. this assertion fails assert(msg == Null reference message); in my actual code instead of variable _message an exception is thrown if (obj is null) == true. i'm using the unittest block to test exception throwing. ... this(T obj) { if (obj is null){ throw new Exception(Null reference.); } } ... unittest { alias MyStruct!MyClass StructType; std.exception.assertThrown(StructType(null)); // Wrong assertion }
Re: How to reserve memory for a slice in a struct
You could allocate space inside a class itself with something like this: class Base { int[] slice; } template Derived(size_t N) { class Derived : Base { int[N] array; this() { slice = array; } } } Base b = new Derived!32(); A bit pointless though...
Re: Argument S to typeof is not an expression
On 2013-05-07 13:08, Dicebot wrote: You may want to update your implementation: http://dpaste.1azy.net/640a2580 Thanks. -- /Jacob Carlborg
Deallocate array?
Hi I'm running Windows Vista 64 with dmd 2.062. I have a simple program: import std.stdio, core.memory, std.cstream; void main() { string[] temp_array; for(int i=0;i500;i++) { ++temp_array.length; temp_array[temp_array.length - 1] = a; } temp_array = null; GC.collect(); writeln(end); din.getc(); } When the program waits at din.getc();, memory usage in the Task Manager is 150MB. Why isn't the memory deallocating? P.S.; I tried temp_array.clear() and destroy(temp_array), but nothing changed.
Re: Deallocate array?
On 05/07/2013 04:09 PM, Matic Kukovec wrote: Hi When the program waits at din.getc();, memory usage in the Task Manager is 150MB. Why isn't the memory deallocating? P.S.; I tried temp_array.clear() and destroy(temp_array), but nothing changed. GC.minimize() may work. Ali
Re: Deallocate array?
On Tuesday, 7 May 2013 at 23:14:20 UTC, Ali Çehreli wrote: On 05/07/2013 04:09 PM, Matic Kukovec wrote: Hi When the program waits at din.getc();, memory usage in the Task Manager is 150MB. Why isn't the memory deallocating? P.S.; I tried temp_array.clear() and destroy(temp_array), but nothing changed. GC.minimize() may work. Ali Thanks for the quick reply, Ali. Tried it, no changes.
Re: Deallocate array?
On 05/07/2013 04:18 PM, Matic Kukovec wrote: On Tuesday, 7 May 2013 at 23:14:20 UTC, Ali Çehreli wrote: GC.minimize() may work. Tried it, no changes. Works for your test program under Linux but as the documentation says, it is not guaranteed to have any effect at all. Ali
Re: Deallocate array?
On Tuesday, 7 May 2013 at 23:31:41 UTC, Ali Çehreli wrote: On 05/07/2013 04:18 PM, Matic Kukovec wrote: On Tuesday, 7 May 2013 at 23:14:20 UTC, Ali Çehreli wrote: GC.minimize() may work. Tried it, no changes. Works for your test program under Linux but as the documentation says, it is not guaranteed to have any effect at all. Ali I found this problem with a program that reads a large xml file (25+ lines), then stores the lines in a string[], does a comparison with another array and finally clears the original array. On the second or third file I always get an OutOfMemoryError, when the Task Manager shows about 1.3GB memory usage. Is this a Windows specific thing or am I doing something wrong?
Re: Deallocate array?
On 05/07/2013 04:42 PM, Matic Kukovec wrote: On Tuesday, 7 May 2013 at 23:31:41 UTC, Ali Çehreli wrote: On 05/07/2013 04:18 PM, Matic Kukovec wrote: On Tuesday, 7 May 2013 at 23:14:20 UTC, Ali Çehreli wrote: GC.minimize() may work. Tried it, no changes. Works for your test program under Linux but as the documentation says, it is not guaranteed to have any effect at all. Ali I found this problem with a program that reads a large xml file (25+ lines), then stores the lines in a string[], does a comparison with another array and finally clears the original array. You don't need to clear the original array but it should be harmless. On the second or third file I always get an OutOfMemoryError, when the Task Manager shows about 1.3GB memory usage. Is this a Windows specific thing or am I doing something wrong? Is this a 32-bit platform? If so, the reason may be the conservative GC that dmd uses. What happens is, unrelated 32-bit values in other parts of the program may look like pointers into the allocated space and the GC thinks that they are still in use. Ali
Re: Deallocate array?
Matic Kukovec: The system is Windows Vista 64bit. DMD is 2.062. DMD doesn't yet produce 64 bit binaries on Windows. I have tried to solve your problem using GC.free, but I am not seeing good results... Bye, bearophile
Re: Deallocate array?
Why isn't the memory deallocating? The memory might be free, but still not released to the OS. Especially in windows, when you free memory it still isn't freed from your process. But you can reuse it in your program if the GC has collected it. The correct test would be to copy and paste the same code below, and see if it stays at 150Mb or it jumps to 300Mb. If it jumps to 300Mb, then the GC hasn't collected it. If it stays at 150Mb, the GC had collected it but windows didn't claim it. --jm
Re: Deallocate array?
I found this problem with a program that reads a large xml file (25+ lines), then stores the lines in a string[], does a comparison with another array and finally clears the original array. On the second or third file I always get an OutOfMemoryError, when the Task Manager shows about 1.3GB memory usage. Is this a Windows specific thing or am I doing something wrong? Try the following before getting rid of your arrays: myarray[] = null; //if it is an array of classes or strings myIntArray[] = 0; //if it is an array of ints myBigString[] = '\0'; etc. This clears the contents of the arrays, and helps the garbage collector, so that it doesn't confuse data with pointers. Also, avoid growing arrays little by little. This is VERY bad for garbage accumulation. Use instead an appender!(string[])() for string arrays for instance. --jm
Re: Deallocate array?
On Tue, 07 May 2013 19:09:28 -0400, Matic Kukovec matic.kuko...@pametnidom.si wrote: Hi I'm running Windows Vista 64 with dmd 2.062. I have a simple program: import std.stdio, core.memory, std.cstream; void main() { string[] temp_array; for(int i=0;i500;i++) { ++temp_array.length; temp_array[temp_array.length - 1] = a; This is very inefficient, use temp_array ~= a; } temp_array = null; GC.collect(); writeln(end); din.getc(); } When the program waits at din.getc();, memory usage in the Task Manager is 150MB. Why isn't the memory deallocating? The GC does not return free memory to the OS, just to free memory pools/free-lists. GC.minimize may or may not help. But your code may not have freed that memory anyway. It is not really possible to ensure that temp_array isn't referred to. For example, the compiler could keep temp_array in a register. P.S.; I tried temp_array.clear() and destroy(temp_array), but nothing changed. Neither of these will deallocate memory. All are equivalent to setting temp_array = null. If you want to ensure deallocation, you need to free it using GC.free(temp_array.ptr). A very dangerous operation, use with caution, make sure there are no other references to that data. -Steve