Re: Can't pass [] to extern function object method
On Wednesday, 18 November 2020 at 10:50:12 UTC, frame wrote: I found the "bug". It was caused by a debug {} statement within a struct method. I assume that the debug symbol is just incompatible called from the DLL context. Were the DLL and main program built in different modes (debug/release)? Then this problem is understandable. Otherwise I find this surprising, and probably worth a bug report? — Bastiaan.
Re: Function Pointer Not Working
On Thursday, 19 November 2020 at 04:23:13 UTC, Marcone wrote: // Function threadingw() void threadingw(HWND hwn, void delegate() fun) nothrow { try { // Function _fun() extern(Windows) uint _fun(void * arg){ (*(cast(void delegate()*) arg))(); // Do not show "Hello World!" :( return 0; } CreateThread(null, 0, &_fun, &fun, 0, null); } catch(Throwable){} } void main(){ null.threadingw({writeln("Hello World!");}); } A delegate is a "fat" pointer (function pointer + context), so it can't fit in a void*. You could do something like the following to "uncurry" the delegate and extract its context to a void* and a regular function, which can then combine the void* given to it later to call the original delegate: import std.traits; auto uncurryDelegate(alias anchor, alias target)() { alias Args = Parameters!target; alias R = ReturnType!target; alias ContextPtr = void*; alias Dg = typeof(&target); union Delegate { Dg dg; struct { void* ptr; void* funcptr; } } auto dg = Delegate(&target); __gshared void* funcptr; // Will always be the same for this instantiation funcptr = (&target).funcptr; static struct Result { R function(ContextPtr ptr, Args args) fun; ContextPtr context; } static R fun(ContextPtr ptr, Args args) { Delegate dg; dg.funcptr = funcptr; dg.ptr = ptr; return dg.dg(args); } return Result(&fun, dg.ptr); } auto uncurryDelegate(alias target)() { return uncurryDelegate!(target, target); } unittest { int fun(int i) { return i + 1; } auto r = uncurryDelegate!fun; assert(r.fun(r.context, 2) == 3); } unittest { struct S { int i; int fun(int j) { return i + j; } auto funUncurried() { return uncurryDelegate!(i, fun); } } auto s = S(2); auto r = s.funUncurried(); assert(r.fun(r.context, 3) == 5); } Sadly you can't write `static immutable void* funcptr = (&target).funcptr;`, because the compiler tries to evaluate &target first. Alternatively you could do this (not recommended): https://stackoverflow.com/a/8656294/21501
Function Pointer Not Working
// Function threadingw() void threadingw(HWND hwn, void delegate() fun) nothrow { try { // Function _fun() extern(Windows) uint _fun(void * arg){ (*(cast(void delegate()*) arg))(); // Do not show "Hello World!" :( return 0; } CreateThread(null, 0, &_fun, &fun, 0, null); } catch(Throwable){} } void main(){ null.threadingw({writeln("Hello World!");}); }
Re: betterC question
On Thursday, 19 November 2020 at 00:20:50 UTC, Dibyendu Majumdar wrote: On Thursday, 19 November 2020 at 00:18:54 UTC, rikki cattermole wrote: You don't need the brackets to call a function (and with a little help from UFCS): void main() { import std.stdio; "Hello!".writeln; writeln; } Okay thanks. Bad idea IMO. Imagine what range pipelines would look like without it. This is one of my favorite D features.
Re: betterC question
On Thursday, 19 November 2020 at 00:18:54 UTC, rikki cattermole wrote: You don't need the brackets to call a function (and with a little help from UFCS): void main() { import std.stdio; "Hello!".writeln; writeln; } Okay thanks. Bad idea IMO.
Re: betterC question
On 19/11/2020 1:11 PM, Dibyendu Majumdar wrote: On Thursday, 19 November 2020 at 00:08:59 UTC, Adam D. Ruppe wrote: On Thursday, 19 November 2020 at 00:07:12 UTC, Dibyendu Majumdar wrote: int function() fp = test; This tries to *call* the function test and assign its return value to fp. Really? why does it do that? You don't need the brackets to call a function (and with a little help from UFCS): void main() { import std.stdio; "Hello!".writeln; writeln; }
Re: betterC question
On Thursday, 19 November 2020 at 00:08:59 UTC, Adam D. Ruppe wrote: On Thursday, 19 November 2020 at 00:07:12 UTC, Dibyendu Majumdar wrote: int function() fp = test; You want &test to get the address. Okay that works. Thanks
Re: betterC question
On Thursday, 19 November 2020 at 00:08:59 UTC, Adam D. Ruppe wrote: On Thursday, 19 November 2020 at 00:07:12 UTC, Dibyendu Majumdar wrote: int function() fp = test; This tries to *call* the function test and assign its return value to fp. Really? why does it do that? You want &test to get the address.
Re: betterC question
On Thursday, 19 November 2020 at 00:07:12 UTC, Dibyendu Majumdar wrote: int function() fp = test; This tries to *call* the function test and assign its return value to fp. You want &test to get the address.
betterC question
I have simple test program: import core.stdc.stdio : printf; void test() { int* a; printf("a == null %d\n", a == null); } int function() fp = test; extern (C) void main() { fp(); } Why do I get: \d\dmd-2.092.1\windows\bin64\dmd.exe -betterC tests.d tests.d(5): Error: printf cannot be interpreted at compile time, because it has no available source code This is on Windows
Re: Git-repo-root relative path
On Monday, 16 November 2020 at 10:21:27 UTC, Per Nordlöw wrote: I need a function that gets the relative path of a file in a Git-repo and preferrably also its status. I'm not sure I understand the question. I have written two programs, hopefully one of them does what you want :D Either via an external call to `git` or optionally via `libgit` (if available). Which DUB packages do you prefer? For such small tasks, the easiest is to just use the shell. 1st answer: Initially I thought that you want to convert the current working directory (I don't know why - I didn't read well the question apparently :D) to a path relative to the root git repo path. Here's my solution to that problem: ```d import std.exception : enforce; import std.format : format; import std.file : getcwd; import std.path : asRelativePath; import std.process : executeShell; import std.stdio : writeln; import std.string : stripRight; void main() { auto cwd = getcwd(); const gitRootPathResult = executeShell("git rev-parse --show-toplevel"); enforce( gitRootPathResult.status == 0, "`git` is not installed, or '%s' is not a git repo".format(cwd) ); // Trim trailing whitespace from the shell invocation const gitRoot = gitRootPathResult.output.stripRight; debug writeln("Git root path: ", gitRoot); gitRoot .asRelativePath(getcwd()) .writeln; } ``` Example usage: ``` $ cd ~/code/repos/dlang/dlang/dmd/src/dmd/backend/ $ dmd -run ~/code/cwd_to_git_relative_path.d ../../.. # Sanity check: $ dmd -debug -run ~/code/cwd_to_git_relative_path.d Git root path: /home/zlx/code/repos/dlang/dlang/dmd ../../.. $ cd '../../..' && pwd /home/zlx/code/repos/dlang/dlang/dmd ``` 2nd answer: Reading a second time, I don't understand what you meant by "gets the relative path of a file in a Git-repo". Did you mean that it receives an absolute path (or relative to current working directory) to a file and converts it to a path relative to a git repo? If so, here's my solution and for determining the status of a file: https://gist.github.com/PetarKirov/b4c8b64e7fc9bb7391901bcb541ddf3a
spurious conversion to int
The following code // module foo; static immutable ubyte [2] t = [2, 3]; ubyte g(const ubyte a) { return cast (ubyte) (a + 1); } void f(const ubyte a, const ubyte b, const int i) { ubyte [2] c = a > b ? [a.g(), b.g()] : [b, a]; // compile ubyte [2] d = a > b ? [t[i], a] : [a, t[i]]; // compile ubyte [2] e = a > b ? [t[i].g(), a.g()] : [a, t[i]]; // does not compile } // does not compile (with DMD 2.94.1). The error message is: foo.d(12): Error: incompatible types for ([g(t[cast(ulong)i]), g(a)]) : ([cast(int)a, cast(int)t[cast(ulong)i]]): ubyte[] and int[] Is this a compiler bug? Or can someone explain me what is wrong with the last line? Why the second array is converted to int[] in this case and not on the above line?
Re: implementing default opCmp
On Wednesday, 18 November 2020 at 22:29:17 UTC, Steven Schveighoffer wrote: How do I do something really simple for opCmp? I tried this it didn't work: return this == other ? 0 : this.tupleof < other.tupleof ? -1 : 1; std.typecons.Tuple has opCmp. So this works: int opCmp(S other) { import std.typecons: tuple; return tuple(this.tupleof).opCmp(tuple(other.tupleof)); }
Re: implementing default opCmp
On Wednesday, 18 November 2020 at 22:29:17 UTC, Steven Schveighoffer wrote: I have a struct like this: struct S { int x; int y; } and I want a default comparison. The problem is, that comparison doesn't have a default, and requires I implement opCmp. While this is useful for the compiler, there's no default I know of that is an easy one-liner. Here's a stab at a totally generic version that I haven't unit tested at all, except to verify that it works for your example struct S: auto cmp(T, U)(auto ref T lhs, auto ref U rhs) { import core.lifetime: forward; static if (__traits(compiles, lhs.opCmp(rhs))) return forward!lhs.opCmp(forward!rhs); else static if (__traits(compiles, rhs.opCmp(lhs))) return -forward!rhs.opCmp(forward!lhs); else return lhs < rhs ? -1 : lhs > rhs ? 1 : 0; } mixin template defaultOpCmp() { import std.traits: isAggregateType; static assert(isAggregateType!(typeof(this)), "opCmp can only be overloaded for aggregate types."); auto opCmp()(auto ref typeof(this) other) { import std.traits: ReturnType, CommonType, Fields; import std.meta: Map = staticMap; alias cmpType(T) = ReturnType!((T lhs, T rhs) => cmp(lhs, rhs)); alias Result = CommonType!(Map!(cmpType, Fields!(typeof(this; Result result; static foreach (i, _; typeof(this).tupleof) if (result == 0) result = cmp(this.tupleof[i], other.tupleof[i]); return result; } }
implementing default opCmp
I have a struct like this: struct S { int x; int y; } and I want a default comparison. The problem is, that comparison doesn't have a default, and requires I implement opCmp. While this is useful for the compiler, there's no default I know of that is an easy one-liner. The truth is, I'm not entirely caring what order these things come out in. I just want them to be defined as having an order given that all the members have a defined order. My expectation is that a default opCmp would look like: int opCmp(S other) { if(x == other.x) { if(y == other.y) return 0; return y < other.y ? -1 : 1; } return x < other.x ? -1 : 1; } But really, as long as there is something to do this easily I don't care what the ordering turns out to be. I can do equality like: return this.tupleof == other.tupleof; I can do assignment like: this.tupleof = other.tupleof; How do I do something really simple for opCmp? I tried this it didn't work: return this == other ? 0 : this.tupleof < other.tupleof ? -1 : 1; -Steve
Re: Calling function within class.
On 11/18/20 7:01 AM, Vino wrote: >Request your help on how to call a function(listFile) from another > function(getFilelist) within the same class(GetDirlist), below is an > example code. That code looks unnecessarily complex to me. First of all, parallel() already executes the loop body in separate threads, so I don't see any reason for Task in that code. std.parallel will appear during my DConf presentation on Saturday. The following program applies ideas from some of my slides and just works in parallel: import std.process; import std.exception; import std.format; import std.parallelism; import std.stdio; class GetDirlist { @system private auto listFile(immutable string st) { auto fl = execute(["ls","-l"]); enforce(fl.status == 0, format("File not Found: %s", fl.status)); return fl.output; } @system public auto getFilelist() { // I am using D dynamic arrays for simpliticy auto flstore = [ "/path1/Dir1", "path2/Dir2" ]; // Note preallocated slot for each result: auto amidata = new string[flstore.length]; // Taking advantage of automatic loop counter foreach(i, st; parallel(flstore,1)) { // Each execution assigns to its own slot amidata[i] = listFile(st); } return amidata[]; } } void main() { // Need an object to call a non-static member function: auto g = new GetDirlist(); writeln(g.getFilelist()); } Ali
Re: Calling function within class.
On 11/18/20 11:25 AM, Vino wrote: > why is this > so complicated in D where as in PHP it is simple like below > > PHP Code: > class PHPclass { >function test1 ($st) { return $st; } >function test2 () { return $this->test1("Test"); } > } > > $obj = new PHPclass(); > print_r($obj->test2()); It is so similar in D that one can say they are the same: class PHPclass { auto test1(T)(T st) { return st; } auto test2() { return this.test1("Test"); } } import std.stdio; void main() { auto obj = new PHPclass(); writeln(obj.test2()); } Ali
Re: Calling function within class.
On Wednesday, 18 November 2020 at 18:24:59 UTC, frame wrote: On Wednesday, 18 November 2020 at 17:55:36 UTC, Vino wrote: I made the changes as below , still not working auto fltask = task!listFile(st); to auto fltask = task!({listFile(st);})(this).executeInNewThread(); The syntax is just wrong: auto fltask = task!({listFile(st);})(this).executeInNewThread(); Should be: auto fltask = task!((GetDirlist obj){obj.listFile(st);})(this).executeInNewThread(); It's the anonymous function syntax in one line compressed - it's equal to: auto fltask = task!( function(GetDirlist obj) { obj.listFile(st); } )(this).executeInNewThread(); But with your context it must look like this: auto fltask = task!( function(GetDirlist obj, string foo) { obj.listFile(foo); } )(this, st); Still your code need to be fixed at lot to get working. Hi, The above code is a sample code, but the logic is same, correct me if my understanding is wrong, in the above code "obj" is a an object for the class GetDirlist, so we are accessing the class member using "obj.listFile(st)" , so why do we need the "(this)" and also why is this so complicated in D where as in PHP it is simple like below PHP Code: class PHPclass { function test1 ($st) { return $st; } function test2 () { return $this->test1("Test"); } } $obj = new PHPclass(); print_r($obj->test2());
Re: Calling function within class.
On Wednesday, 18 November 2020 at 17:55:36 UTC, Vino wrote: I made the changes as below , still not working auto fltask = task!listFile(st); to auto fltask = task!({listFile(st);})(this).executeInNewThread(); The syntax is just wrong: auto fltask = task!({listFile(st);})(this).executeInNewThread(); Should be: auto fltask = task!((GetDirlist obj){obj.listFile(st);})(this).executeInNewThread(); It's the anonymous function syntax in one line compressed - it's equal to: auto fltask = task!( function(GetDirlist obj) { obj.listFile(st); } )(this).executeInNewThread(); But with your context it must look like this: auto fltask = task!( function(GetDirlist obj, string foo) { obj.listFile(foo); } )(this, st); Still your code need to be fixed at lot to get working.
Re: Calling function within class.
On Wednesday, 18 November 2020 at 16:53:44 UTC, frame wrote: On Wednesday, 18 November 2020 at 15:01:53 UTC, Vino wrote: Hi All, Request your help on how to call a function(listFile) from another function(getFilelist) within the same class(GetDirlist), below is an example code. I think it's basically the same issue like that recently opened topic: https://forum.dlang.org/thread/ddxasuvusgibppccl...@forum.dlang.org You need to pass your class object as argument to a static method or anonymous function. Hi, I made the changes as below , still not working auto fltask = task!listFile(st); to auto fltask = task!({listFile(st);})(this).executeInNewThread(); Error: /DTECH/LDC/dlang/ldc-1.24.0/bin/../import/std/parallelism.d(516,34): Error: function literal __lambda2() is not callable using argument types (GetDirlist) /DTECH/LDC/dlang/ldc-1.24.0/bin/../import/std/parallelism.d(516,34): expected 0 argument(s), not 1 /DTECH/LDC/dlang/ldc-1.24.0/bin/../import/std/parallelism.d(842,16): Error: template instance GetDirlist.GetDirlist.getFilelist.__foreachbody2. Task!(delegate () @system { this.listFile(st); } , GetDirlist) error instantiating instantiated from here: task!(delegate () @system { this.listFile(st); } , GetDirlist) From, Vino.B
Re: Calling function within class.
On Wednesday, 18 November 2020 at 15:01:53 UTC, Vino wrote: Hi All, Request your help on how to call a function(listFile) from another function(getFilelist) within the same class(GetDirlist), below is an example code. I think it's basically the same issue like that recently opened topic: https://forum.dlang.org/thread/ddxasuvusgibppccl...@forum.dlang.org You need to pass your class object as argument to a static method or anonymous function.
Re: Executing AWS commands
On Tuesday, 17 November 2020 at 21:08:21 UTC, Paul Backus wrote: On Tuesday, 17 November 2020 at 19:07:42 UTC, Vino wrote: auto pid = execute(["/usr/bin/aws ec2 describe-images --filters 'Name=state,Values=available' --query 'Images[*].[ImageId]'"]); [...] auto pid = execute(["/usr/bin/aws ec2 describe-images --filters 'Name=state,Values=available' --query 'Images[*].[ImageId]'"]); You need to break up your command line so that each argument is in a separate array element. In the commands above you have multiple arguments grouped together into each array element. Alternately, you can pass everything in a single string to `executeShell`. Hi Paul, Thank you very much was able to execute the aws commands using `executeShell`. From, Vino.B
Calling function within class.
Hi All, Request your help on how to call a function(listFile) from another function(getFilelist) within the same class(GetDirlist), below is an example code. Code: class GetDirlist { @system private auto listFile(immutable string st) { auto fl = execute(["ls","-l"]); enforce(fl.status == 0, format("File not Found: %s", fl.status)); return fl.output; } @system public auto getFilelist() { Array!string amidata; auto flstore = Array!string("/path1/Dir1", "path2/Dir2"); foreach(st; parallel(flstore,1)) { auto fltask = task!listFile(st); fltask.executeInNewThread(); amidata.insert(fltask.yieldForce); } return amidata[]; } } void main() { writeln(getFilelist()); } From, Vino.B
Re: Can't pass [] to extern function object method
On Monday, 16 November 2020 at 22:22:42 UTC, frame wrote: On Monday, 16 November 2020 at 21:58:44 UTC, Jack wrote: What is the function prototype like and how are you declaring that struct? The struct is very simple, it contains: I found the "bug". It was caused by a debug {} statement within a struct method. I assume that the debug symbol is just incompatible called from the DLL context.