Re: Understanding lvalue and rvalue
On 04/28/2017 06:46 AM, ANtlord wrote: struct MyStruct { @disable this(this); int a; } void process(MyStruct obj) { writeln("incoming rvalue"); } void process(in ref MyStruct obj) { writeln("incoming lvalue"); } void main() { MyStruct obj = {a: 1}; process(obj); } Text of the error is "struct app.MyStruct is not copyable because it is annotated with @disable" Regarding overloads, the spec [1] defines an "exact match" to win over a "match with conversion to const". On `ref` it only says that "literals [i.e. rvalues] do not match `ref` [...] parameters". In your code, the non-ref variant is an exact match for `obj`. Be aware that the non-ref overload accepts lvalues as well as rvalues. The ref-variant is not considered an exact match, because calling it involves converting `obj` to `const MyStruct`. So, that's why the non-ref version wins in your code. Everything works as specified here. Also I try to change word `in` by `const` and I get same result. But when I remove `in` program is compiled. When you remove `in`, the ref overload becomes an exact match as well. Now the compiler has to choose between two exact matches. The spec says that "partial ordering" is then used to find the correct overload. I'm not sure if the text properly describes how that works for ref vs non-ref, though. In practice, the compiler prefers a ref overload over a non-ref overload, *if* they have the same match level. Instead of removing `in`/`const` from the ref overload, you can also add it to the non-ref overload. Again, the overloads will have the same match level ("match with conversion to const"), and the ref version will win. [1] https://dlang.org/spec/function.html#function-overloading
Re: Understanding lvalue and rvalue
On Friday, 28 April 2017 at 04:46:00 UTC, ANtlord wrote: Does make sense for me because it is more obvious in client code, but I want to understand reason of error pointed above. Typo fix. It makes sense for me*
Understanding lvalue and rvalue
Hello! Short time ago I've met strange thing at least for me. I have a non-copyable structure and two methods for it with same name. I mean that I use function overloading. First method takes rvalue of this structure. Second method takes constant lvalue structure. But when I try to use this function with instantiated object I get compile error. struct MyStruct { @disable this(this); int a; } void process(MyStruct obj) { writeln("incoming rvalue"); } void process(in ref MyStruct obj) { writeln("incoming lvalue"); } void main() { MyStruct obj = {a: 1}; process(obj); } Text of the error is "struct app.MyStruct is not copyable because it is annotated with @disable" Also I try to change word `in` by `const` and I get same result. But when I remove `in` program is compiled. Is this mug or feature. If feature, please help to understand it. Should I pass structure instances by pointer? Like void process(in MyStruct* obj) { writeln("incoming lvalue"); } void main() { MyStruct obj = {a: 1}; process(); } Does make sense for me because it is more obvious in client code, but I want to understand reason of error pointed above. Thanks. Sorry if my English is not clear.
Re: scoped classes
On Thursday, 27 April 2017 at 19:18:14 UTC, Stanislav Blinov wrote: On Thursday, 27 April 2017 at 18:36:08 UTC, Alex wrote: move() is only destructive if the type has custom postblit or destructor, otherwise it's just a bitwise copy. But, as mentioned, there's an issue with it at the moment: it doesn't really care if the type being moved has const/immutable members. uninitializedArray is scary. If you do use it, probably best to localize the usage as much as possible and be very very VERY careful with it ;) :-) Here's a sketch of something that's a little bit more convenient: https://dpaste.dzfl.pl/ee472fd872a5 But I'm not going to pretend it'd survive a review. Wow! So much work already done... Thanks for so much ideas :) Also note that, going back to your original question, docs for scoped state that it's illegal to move it, so that particular type you can't really store in any of these arrays. yeah... At the beginning of the day, I thought, this would act as a wrapper, which could simplify things... just a wrong direction.
Re: COM Expertise needed: COM Callbacks
On Thursday, 27 April 2017 at 07:51:26 UTC, John Chapman wrote: On Wednesday, 26 April 2017 at 23:04:53 UTC, Nierjerson wrote: On Wednesday, 26 April 2017 at 15:30:37 UTC, John Chapman wrote: On Tuesday, 25 April 2017 at 18:39:56 UTC, Nierjerson wrote: [...] When you use DISPATCH_PROPERTYPUT you need to set cNamedArgs and rgdispidNamedArgs like so: int dispidNamed = DISPID_PROPERTYPUT; params.cNamedArgs = 1; params.rgdispidNamedArgs = You should also call AddRef on any COM objects you add to your paramVars array. Did you try this? I tried and same issue. Are you sure the above is required? I'm not using any "named" args so not sure why it should matter? From the documentation (https://msdn.microsoft.com/en-us/library/windows/desktop/ms221479(v=vs.85).aspx): "When you use IDispatch::Invoke() with DISPATCH_PROPERTYPUT or DISPATCH_PROPERTYPUTREF, you have to specially initialize the cNamedArgs and rgdispidNamedArgs elements of your DISPPARAMS structure" Thought it might help. Ok, thanks. I will try again, Maybe I did something wrong. It seems though that it isn't necessary, at least in my specific test case since the same behavior was seen(although it might have been a future bug). I think the main issue though, is that I really don't know what is going on when I invoke the PS function. It seems to call the server method that takes the interface and then the server does it's "magic"(which is calling my QueryInterface) but how the implemented QueryInterface is suppose to respond is beyond me... I've tried some based stuff but nothing seem to work. The good news is that it is doing something(calling QueryInterface) which means that the server is at work. Any more ideas? I think the issue currently is is the QueryInterface(it is simply not doing what it is suppose to). I'll probably have to look at some other implementations to see what is going on.
Re: scoped classes
On Thursday, 27 April 2017 at 18:36:08 UTC, Alex wrote: * I'm pretty sure that the code is going to be invalid when you're dealing with const/immutable data. Ok... this is important... I tried this out, and the value of the immutable data even remains the same. But for safety reasons, I would reconstruct the structs inside the array anyway, so I can live with this, I think... move() is only destructive if the type has custom postblit or destructor, otherwise it's just a bitwise copy. But, as mentioned, there's an issue with it at the moment: it doesn't really care if the type being moved has const/immutable members. uninitializedArray is scary. If you do use it, probably best to localize the usage as much as possible and be very very VERY careful with it ;) Here's a sketch of something that's a little bit more convenient: https://dpaste.dzfl.pl/ee472fd872a5 But I'm not going to pretend it'd survive a review. Also note that, going back to your original question, docs for scoped state that it's illegal to move it, so that particular type you can't really store in any of these arrays.
Re: scoped classes
On Thursday, 27 April 2017 at 17:39:42 UTC, ag0aep6g wrote: On 04/27/2017 05:47 PM, Alex wrote: void main() { S[] arr; S s = S(42); arr = [s]; // this doesn't work :( } struct S { @disable this(); @disable this(this); this(size_t dummy){} } 1) Construct the S instance directly in the array literal: arr = [S(42]); But I guess that's besides the point. So ... 2) Use std.algorithm.mutation.move [1]: import std.algorithm.mutation: move; S s = S(42); arr = [move(s)]; `move` makes a "destructive copy" here; i.e, it resets `s` to `S.init`. You probably want to append to that array at some point. That's going to be more tricky, because appending potentially involves copying the whole array. This might work: import std.algorithm.mutation: moveEmplace; import std.array: uninitializedArray; /* Make a new, larger array: */ S[] new_arr = uninitializedArray!(S[])(arr.length + 1); /* Copy existing elements; destroy old array: */ foreach (size_t i; 0 .. arr.length) moveEmplace(arr[i], new_arr[i]); /* Copy new element; destroy s: */ moveEmplace(s, new_arr[$ - 1]); /* Replace old array with new one: */ arr = new_arr; Cool! Works like a charm :) Notes: * `moveEmplace` and `uninitializedArray` are completely unsafe. You must ensure safety yourself. Yes, I'm aware of this... * I'm not entirely sure that the code is completely correct. It might be invalid and break some language rule. :-) I'm not sure about what is worse: to be forced to use pointers or to use black magic practices at preparation step only. So... Now, I have at least a choice... * I'm pretty sure that the code is going to be invalid when you're dealing with const/immutable data. Ok... this is important... I tried this out, and the value of the immutable data even remains the same. But for safety reasons, I would reconstruct the structs inside the array anyway, so I can live with this, I think... * The code destroys the old array. References to it (slices of it, pointers into it) will show .init values. That's ok... at creation time, there won't be any references yet... * Maybe one can make use of `.capacity` somehow. As it is, the code makes a copy of the whole array every time. Tried this out for some values, capacity of the new array is always 0. * If this "moveAppend" functionality can be done in a valid manner, it might be a worthwhile addition to the "move" function family. :-) Thanks a lot! [1] http://dlang.org/phobos/std_algorithm_mutation.html#.move
Re: scoped classes
On 04/27/2017 05:47 PM, Alex wrote: void main() { S[] arr; S s = S(42); arr = [s]; // this doesn't work :( } struct S { @disable this(); @disable this(this); this(size_t dummy){} } 1) Construct the S instance directly in the array literal: arr = [S(42]); But I guess that's besides the point. So ... 2) Use std.algorithm.mutation.move [1]: import std.algorithm.mutation: move; S s = S(42); arr = [move(s)]; `move` makes a "destructive copy" here; i.e, it resets `s` to `S.init`. You probably want to append to that array at some point. That's going to be more tricky, because appending potentially involves copying the whole array. This might work: import std.algorithm.mutation: moveEmplace; import std.array: uninitializedArray; /* Make a new, larger array: */ S[] new_arr = uninitializedArray!(S[])(arr.length + 1); /* Copy existing elements; destroy old array: */ foreach (size_t i; 0 .. arr.length) moveEmplace(arr[i], new_arr[i]); /* Copy new element; destroy s: */ moveEmplace(s, new_arr[$ - 1]); /* Replace old array with new one: */ arr = new_arr; Notes: * `moveEmplace` and `uninitializedArray` are completely unsafe. You must ensure safety yourself. * I'm not entirely sure that the code is completely correct. It might be invalid and break some language rule. * I'm pretty sure that the code is going to be invalid when you're dealing with const/immutable data. * The code destroys the old array. References to it (slices of it, pointers into it) will show .init values. * Maybe one can make use of `.capacity` somehow. As it is, the code makes a copy of the whole array every time. * If this "moveAppend" functionality can be done in a valid manner, it might be a worthwhile addition to the "move" function family. [1] http://dlang.org/phobos/std_algorithm_mutation.html#.move
Re: scoped classes
On Thursday, 27 April 2017 at 17:07:05 UTC, Ali Çehreli wrote: I haven't used it yet but it's worth noting that there is EMSI's container library as well: http://code.dlang.org/packages/emsi_containers A brief glance at the source of dynamicarray there suggests that it won't help with non-copyables either.
Re: scoped classes
I haven't used it yet but it's worth noting that there is EMSI's container library as well: http://code.dlang.org/packages/emsi_containers Ali
Re: scoped classes
On Thursday, 27 April 2017 at 16:39:38 UTC, Stanislav Blinov wrote: On Thursday, 27 April 2017 at 15:47:38 UTC, Alex wrote: struct S { @disable this(); @disable this(this); this(size_t dummy){} } Given a struct with an explicit constructor and a postblit. How to make an array of it? You mean with a disabled default ctor and postblit? You can't with built-in arrays. They expect that elements can be default-constructed and copied. Even std.container.Array in its current implementation won't help you there. The only way to get around that is to devise your own array type that carefully deals with uninitialized storage and uses emplace/move/moveEmplace to store elements. Hm... ok. This is a acceptable answer. So, if such structs exist, it is forced to use pointers on their instances as an indirection... apart from using some reference type things surrounding them... Thanks for helping with perception :)
Re: scoped classes
On Thursday, 27 April 2017 at 15:47:38 UTC, Alex wrote: struct S { @disable this(); @disable this(this); this(size_t dummy){} } Given a struct with an explicit constructor and a postblit. How to make an array of it? You mean with a disabled default ctor and postblit? You can't with built-in arrays. They expect that elements can be default-constructed and copied. Even std.container.Array in its current implementation won't help you there. The only way to get around that is to devise your own array type that carefully deals with uninitialized storage and uses emplace/move/moveEmplace to store elements.
Re: scoped classes
On Thursday, 27 April 2017 at 15:06:44 UTC, Stanislav Blinov wrote: The only "possible" way would be like this: typeof(scoped!A())[] a; a = [ scoped!A(1), scoped!A(2), scoped!A(3) ]; But even so, you shouldn't do that. scoped isn't designed for it. And then, the amount of elements is not known at compile time... But I think, I can generalize the question little bit: void main() { S[] arr; S s = S(42); arr = [s]; // this doesn't work :( } struct S { @disable this(); @disable this(this); this(size_t dummy){} } Given a struct with an explicit constructor and a postblit. How to make an array of it? Tried stuff with emplace, move and memmove already, nothing worked, at least in the form I had it... It is good, that it is hidden so well, as I'm intend to do this action in a constructor only, but I didn't find not a single solution so far...
Re: scoped classes
On Thursday, 27 April 2017 at 06:40:49 UTC, Alex wrote: Hi all, a short question about an example. having read this: https://dlang.org/library/std/typecons/scoped.html There is a struct B defined in the middle of the example, with a scoped class member. How to define an array of such members (and to put some items to it)? So, I want to have something like // Use as member variable struct B { typeof(scoped!A())[] a; // note the trailing parentheses this(int i) { // construct member a.length = 5; // doesn't work, as the default constructor is disabled. a ~= scoped!A(i); // doesn't work, as the type is not copyable // ??? } } The only "possible" way would be like this: typeof(scoped!A())[] a; a = [ scoped!A(1), scoped!A(2), scoped!A(3) ]; But even so, you shouldn't do that. scoped isn't designed for it.
Re: Can't break App execution by ctrl+c
Just catch the empty result exception. I do not want to go to catch block if I have empty result. I just want to get there if any other error type occur. If result is empty that simply skip this step.
Re: Can't break App execution by ctrl+c
On Thursday, 27 April 2017 at 12:25:11 UTC, Adam D. Ruppe wrote: On Thursday, 27 April 2017 at 12:17:12 UTC, Suliman wrote: Before my code handle empty result in `catch` block. You must be catching the ctrl+c exception... don't do that. Just catch the empty result exception. The issue is gone after removing http://code.dlang.org/packages/consoled it's look like that it's produced error. Now ctrl+c is woking fine...
Re: Can't break App execution by ctrl+c
On Thursday, 27 April 2017 at 12:17:12 UTC, Suliman wrote: Before my code handle empty result in `catch` block. You must be catching the ctrl+c exception... don't do that. Just catch the empty result exception.
Can't break App execution by ctrl+c
Before my code handle empty result in `catch` block. Then I moved it's checking to main loop, and now I can't abort App execution by ctrl+c. It's simply continue working. Here is my code: foreach(cargpspoint; cargpspoints) { auto cmd_dist = new PGCommand(pgconnection, sql_query)); try { auto nresult = cmd_dist.executeQuery(); auto nanswer = nresult.array; nresult.close(); if(nanswer.empty) { continue; } } OS: Windows.
Re: Persistent key-value-store for D?
On Thursday, 27 April 2017 at 01:56:12 UTC, Matthias Klumpp wrote: On Wednesday, 26 April 2017 at 17:06:52 UTC, krylon wrote: [...] If I understand what I have read so far correctly, it is possible to access libraries written in C or C++ from D - in that case, I could just use Tokyocabinet directly, but I have not found any pointers on how to do this. Is this a feasible option, and if so, where can I find documentation on how to do this? I can recommend using LMDB[1] which likely does all you want. It also has D bindings[2]. [...] Cheers, Matthias [1]: https://en.wikipedia.org/wiki/Lightning_Memory-Mapped_Database [2]: https://github.com/ximion/appstream-generator/blob/master/src/asgen/bindings/lmdb.d Thank you very much, that sounds exactly like what I was looking for!
Re: Persistent key-value-store for D?
On Wednesday, 26 April 2017 at 19:07:22 UTC, bachmeier wrote: On Wednesday, 26 April 2017 at 17:06:52 UTC, krylon wrote: [...] Welcome to the D community. [...] You can call C libraries directly. I'd suggest trying dstep on the header files as a first step. https://github.com/jacob-carlborg/dstep These resources might help: https://wiki.dlang.org/Bind_D_to_C http://dlang.org/spec/interfaceToC.html You only need to write a binding for functions that you actually want to call, which might explain why nobody has made bindings available. Thank you! I will look into that!
Re: readf interferes with readln
On Thursday, 27 April 2017 at 08:37:26 UTC, ketmar wrote: Bastiaan Veelo wrote: Hi, I am having trouble explaining the following to someone learning D. Can someone explain why readln has different behaviour when it is preceded by readf? Suppose we want to not end the program before the user presses Enter by having readln at the end of main(): ``` import std.stdio; void main() { int num; write("Give a number "); readf(" %s", num); writeln("Thanks"); readln; readln; } ``` In this example this requires twice readln. When you comment out readf, you need readln only once. Thanks! 'cause your `readf()` stops before consuming `'\n`. i.e. EOL is still in input buffer, and first `readln()` will immediately consume it. Right, of course. Thanks a lot.
Re: readf interferes with readln
Bastiaan Veelo wrote: Hi, I am having trouble explaining the following to someone learning D. Can someone explain why readln has different behaviour when it is preceded by readf? Suppose we want to not end the program before the user presses Enter by having readln at the end of main(): ``` import std.stdio; void main() { int num; write("Give a number "); readf(" %s", num); writeln("Thanks"); readln; readln; } ``` In this example this requires twice readln. When you comment out readf, you need readln only once. Thanks! 'cause your `readf()` stops before consuming `'\n`. i.e. EOL is still in input buffer, and first `readln()` will immediately consume it.
readf interferes with readln
Hi, I am having trouble explaining the following to someone learning D. Can someone explain why readln has different behaviour when it is preceded by readf? Suppose we want to not end the program before the user presses Enter by having readln at the end of main(): ``` import std.stdio; void main() { int num; write("Give a number "); readf(" %s", num); writeln("Thanks"); readln; readln; } ``` In this example this requires twice readln. When you comment out readf, you need readln only once. Thanks!
Re: COM Expertise needed: COM Callbacks
On Wednesday, 26 April 2017 at 23:04:53 UTC, Nierjerson wrote: On Wednesday, 26 April 2017 at 15:30:37 UTC, John Chapman wrote: On Tuesday, 25 April 2017 at 18:39:56 UTC, Nierjerson wrote: [...] When you use DISPATCH_PROPERTYPUT you need to set cNamedArgs and rgdispidNamedArgs like so: int dispidNamed = DISPID_PROPERTYPUT; params.cNamedArgs = 1; params.rgdispidNamedArgs = You should also call AddRef on any COM objects you add to your paramVars array. Did you try this? I tried and same issue. Are you sure the above is required? I'm not using any "named" args so not sure why it should matter? From the documentation (https://msdn.microsoft.com/en-us/library/windows/desktop/ms221479(v=vs.85).aspx): "When you use IDispatch::Invoke() with DISPATCH_PROPERTYPUT or DISPATCH_PROPERTYPUTREF, you have to specially initialize the cNamedArgs and rgdispidNamedArgs elements of your DISPPARAMS structure" Thought it might help.
scoped classes
Hi all, a short question about an example. having read this: https://dlang.org/library/std/typecons/scoped.html There is a struct B defined in the middle of the example, with a scoped class member. How to define an array of such members (and to put some items to it)? So, I want to have something like // Use as member variable struct B { typeof(scoped!A())[] a; // note the trailing parentheses this(int i) { // construct member a.length = 5; // doesn't work, as the default constructor is disabled. a ~= scoped!A(i); // doesn't work, as the type is not copyable // ??? } }