Re: How to make a generic function to take a class or struct by reference?
Auto ref? ```D int* getX(T)(auto ref T t) { ... ```
Re: A debug class has started
On 13.12.2021 14:26, ag0aep6g wrote: On 13.12.21 12:09, drug wrote: That's because `str` is initialized by a literal and you can not change it by definition. When you call `toStringz` it duplicates that literal (adding terminating zero at the end) and the duplicate is mutable. I would recommend do not use `toStringz` and just make duplicate of the literal - https://run.dlang.io/is/vaosW0 From the link: string str = "abc;def;ab".dup; // allocates the string in the heap char* w = cast(char*)str; writeln(replaceChar(w, str.length, ';', 'X')); That still has undefined behavior. You cannot mutate the characters in a `string`. It doesn't matter if it came from a literal or `.dup`. Use `char[]` instead of `string`. You're right. I forget to change `string str` to `auto str` or `char[] str`.
Re: A debug class has started
On 13.12.2021 13:49, forkit wrote: On Monday, 13 December 2021 at 09:49:05 UTC, forkit wrote: char* w = cast(char*)str.toStringz; // this seems to be the solution class has ended ;-) That's because `str` is initialized by a literal and you can not change it by definition. When you call `toStringz` it duplicates that literal (adding terminating zero at the end) and the duplicate is mutable. I would recommend do not use `toStringz` and just make duplicate of the literal - https://run.dlang.io/is/vaosW0
Re: I need some help for my DCV update
On 26.11.2021 12:16, Ferhat Kurtulmuş wrote: I am working on the DCV to make it compilable with the recent versions of LDC, mir libraries, and stuff. I have not yet simply forked it to work on it. I am including modules one by one for my convenience instead. Hope, I am close to the end. Here is my temporary repo: https://github.com/aferust/ddcv I run into some problems with module convolution, especially the function conv invoked by the below code which calls canny edge filter: ``` Image image = imread("lena.png"); auto slice = image.sliced.rgb2gray; //auto equalized = slice.histEqualize(slice.flattened.calcHistogram); slice.asImage.imshow("Original"); auto edge = slice.canny!ubyte(15); edge.asImage.imshow("edge"); waitKey(); ``` Somehow, the compiler fails in deducting the types. I need some help from Ilya or other people familiar with mir.ndslice. To reproduce it, download my repo and try to compile it as it is. There is a main with the test code in the repo. Just be sure you have a glfw3.dll/.so. ``` source\dcv\imgproc\filter.d(547,18): Error: template `dcv.imgproc.convolution.conv` cannot deduce function from argument types `!()(Slice!(ubyte*, 2LU, mir_slice_kind.contiguous), Slice!(float*, 2LU, mir_slice_kind.contiguous), Slice!(float*, 2LU, mir_slice_kind.contiguous), Slice!(float*, 2LU, mir_slice_kind.contiguous), TaskPool)` source\dcv\imgproc\filter.d(548,18): Error: template `dcv.imgproc.convolution.conv` cannot deduce function from argument types `!()(Slice!(ubyte*, 2LU, mir_sut, KernelTensor kerlice_kind.contiguous), Slice!(float*, 2LU, mir_slice_kind.contiguous), Slice!(float*, 2LU, mir_slice_kind.contiguous), Slice!(float*, 2LU, mir_slice_kind.contiguous), TaskPool)` lice_kind.contiguous source\dcv\imgproc\convolution.d(78,13): Candidate is: `conv(alias bc = neumann, InputTensor, KernelTensor, MaskTensor = KernelTensor)(InputTensor input, KernelTensor kernel, InputTensor prealloc = InputTensor.init, MaskTensor mask = MaskTensor.init, TaskPool pool = taskPool)` ut, KernelTensor ker source\dcv\imgproc\filter.d(674,18): Error: template instance `dcv.imgproc.filter.calcGradients!(Slice!(ubyte*, 2LU, mir_slice_kind.contiguous), float)` error instantiating r instantiating source\dcv\imgproc\filter.d(694,24): instantiated from here: `canny!(ubyte, ubyte, mir_slice_kind.contiguous)` source\app.d(48,34): instantiated from here: `canny!(ubyte, ubyte, mir_slice_kind.contiguous)` ``` I tried explicitly passing template parameters in dcv.imgproc.filter.calcGradients like below, but in that way, I am getting some other compilation errors: ``` alias Empty2Type = Slice!(V*, 2LU, SliceKind.contiguous); fx = input.conv(neumann, typeof(input), Empty2Type, Empty2Type) (kx, emptySlice!(2LU, V), emptySlice!(2LU, V), pool); fy = input.convinput.conv(neumann, typeof(input), Empty2Type, Empty2Type) (ky, emptySlice!(2LU, V), emptySlice!(2LU, V), pool); ``` Thanks in advance! Didn't test it, just read the error output. `conv` takes (InputTensor, KernelTensor, InputTensor, MaskTensor = KernelTensor) but you pass to it (InputTensor, KernelTensor, KernelTensor, KernelTensor) and InputTensor !is KernelTensor. InputTensor = Slice!(ubyte*, 2LU, mir_slice_kind.contiguous) and KernelTensor = Slice!(float*, 2LU, mir_slice_kind.contiguous). The key argument of slices is a pointee type - InputTensor pointee has ubyte type and KernelTensor has float. I'm not sure this solves your problem but at least I'd start from here.
Re: What is the proper way to outline static-if-conditions ?
On 10.10.2021 18:01, Elmar wrote: Well, I just wondered why your code would compile and mine wouldn't. The `version(all)` variant will not compile on my computer with `rdmd` because `PointerTarget` only allows pointers. It depends on compiler version. This variant is compiled on version 2.092.1 and above But the 2nd one will compile. The `is()` expression catches the compilation error which is nice. This is sufficient: ```d enum isPointedStaticArray(T) = is(PointerTarget!T : P[N], P, size_t N); ``` It would be nice if one could use pattern-matching for it in D. Is this possible? ```d enum isPointedStaticArray(X : P*, P) = .isStaticArray!(PointerTarget!X); enum isPointedStaticArray(X : else) = false; ``` As I know it's impossible, but you can use a regular template: ```d template isPointedStaticArray(T) { static if (isPointer!T) enum isPointedStaticArray = isStaticArray!(PointerTarget!T); else enum isPointedStaticArray = false; } ``` https://run.dlang.io/is/lR7feP this compiles from 2.086.1 and above
Re: What is the proper way to outline static-if-conditions ?
You just need to check if T is a pointer: ```D import std; alias DA = int[]; alias SA = int[3]; alias PSA = SA*; alias PDA = DA*; version(all) enum isPointedStaticArray(T) = isPointer!T && isStaticArray!(PointerTarget!T); else enum isPointedStaticArray(T) = isPointer!T && is(PointerTarget!T : P[N], P, size_t N); // this way you can get array length static assert(!isPointedStaticArray!DA); static assert(!isPointedStaticArray!SA); static assert(!isPointedStaticArray!PDA); static assert( isPointedStaticArray!PSA); void main() { } ``` https://run.dlang.io/is/qKdx1D Also you can use another way to detect static array - it can be useful if you need to get its length
Re: GDC - program runs in one thread, DMD - in 4 threads, why?
10.09.2021 12:27, eugene пишет: //import std.container.dlist; // dmd (v2.097.2) import std.container: DList; // gdc (4.9.2) It is off-topic a bit but I think none can compare gdc 4.9.2 to dmd 2.097.2 because gdc has older version than dmd. I would compare gdc to appropriate dmd version, it's about 2.078. But note that gdc backported some code from more recent dmd-fe versions so it has 2.078-dirty version in fact.
Re: How to get element type of a slice?
17.08.2021 15:21, Ferhat Kurtulmuş пишет: Hello folks, Hope everyone is doing fine. Considering the following code, in the first condition, I am extracting the type Point from the slice Point[]. I searched in the std.traits, and could not find a neater solution something like ElementTypeOf!T. Is there any neater solution for it? Thanks in advance. ```d static if (isArray!VecPoint){ VecPoint dummy; alias Point = typeof(dummy[0]); } else static if (isRandomAccessRange!VecPoint){ alias ASeq2 = TemplateArgsOf!VecPoint; alias Point = ASeq2[0]; } else static assert(0, typeof(VecPoint).stringof ~ " type is not supported"); ``` Ferhat https://dlang.org/library/std/range/primitives/element_type.html
Re: I do not understand copy constructors
12.08.2021 14:32, Paul Backus пишет: This is not true. Qualifying the ctor as `inout` works fine: https://run.dlang.io/is/Kpzp5M The problem in this example is that `.dup` always returns a mutable array, even if the array being copied is `inout`. The solution is to cast the copy back to the original type: ```d this(ref return scope inout A rhs) inout { data = cast(typeof(rhs.data)) rhs.data.dup; } ``` Yes, it's not true. I forgot that ctors are special in contrast to regular methods and can modify the aggregate they belong to even if the ctor has const/immutable/inout qualifier.
Re: I do not understand copy constructors
12.08.2021 14:07, drug пишет: 12.08.2021 12:36, Learner пишет: > It seems that there is no easy way to transition from a postblit to a copy constructor, no? You just need both const and mutable copy ctors to replace inout one: ```D struct A { int[] data; this(ref return scope A rhs) { data = rhs.data.dup; } this(ref return scope const A rhs) const { data = rhs.data.dup; } } ``` the mutable copy ctor accepts mutable data and the const copy ctor accepts const and immutable data but using inout ctor is easier: ```D struct A { int[] data; this(ref return scope inout A rhs) /* no inout here */ { data = rhs.data.dup; } } ``` The problem is that if you qualify the ctor itself then if you pass const/immutable rhs to it then the ctor is const/immutable too (like the args) and of course you cannot modify this, so the error. To make a copy ctor you need to qualify copy ctor args as inout but the copy ctor itself shall be mutable and have no const,immutable or inout qualifier.
Re: I do not understand copy constructors
12.08.2021 12:36, Learner пишет: > It seems that there is no easy way to transition from a postblit to a copy constructor, no? You just need both const and mutable copy ctors to replace inout one: ```D struct A { int[] data; this(ref return scope A rhs) { data = rhs.data.dup; } this(ref return scope const A rhs) const { data = rhs.data.dup; } } ``` the mutable copy ctor accepts mutable data and the const copy ctor accepts const and immutable data
Re: Performance issue with fiber
28.07.2021 17:39, Mathias LANG пишет: On Wednesday, 21 July 2021 at 22:51:38 UTC, hanabi1224 wrote: Hi, I'm new to D lang and encounter some performance issues with fiber, not sure if there's something obviously wrong with my code. I took a quick look, and the first problem I saw was that you were using `spawnLinked` but not replacing the scheduler. `std.concurrency` uses a global `scheduler` variable to do its job. Hence doing: ```diff - auto scheduler = new FiberScheduler(); + scheduler = new FiberScheduler(); ``` Will ensure that `spawnLinked` works as expected. There are a few other things to consider, w.r.t. fibers: - Our Fibers are 4 pages (on Linux) by default; - We have an extra guard page, because we are a native language, so we can't do the same trick as Go to auto-grow the stack; - Spawning fibers *is* expensive and other languages reuse fibers (Yes, Go recycle them); The `FiberScheduler` implementation is unfortunately pretty bad: it [does not re-use fibers](https://github.com/dlang/phobos/blob/b48cca57e8ad2dc56872499836bfa1e70e390abb/std/concurrency.d#L1578-L1599). I believe this is the core of the issue. I profiled the provided example (not `FiberScheduler`) using perf. Both dmd and ldc2 gave the same result - `void filterInner(int, int)` took ~90% of the run time. The time was divided between: `int std.concurrency.receiveOnly!(int).receiveOnly()` - 58% `void std.concurrency.send!(int).send(std.concurrency.Tid, int)` - 31% So most of the time is messages passing. Between the fibers creating took very few time. Perf output contains information only of `void std.concurrency.FiberScheduler.create(void delegate()).wrap()` which took less than 0.5%. But I wouldn't say that I did the profiling ideally so take it with a grain of salt.
Re: Initializing a complex dynamic array (with real part from one array, and imaginary from other array)?
I wouldn't state it is the best way but you can try something like that: ```D import std.complex; import std.range : zip; import std.algorithm : equal, map; import std.array : array; void main(){ auto N=2; double[] x,y; x.length = N; y.length = N; x[0] = 1.1; x[1] = 2.2; y[0] = 3.3; y[1] = 4.4; auto z = zip(x, y) // concatenate two ranges .map!(a=>Complex!double(a[0],a[1])) // take the current first element of the first range as the real part and the current first element of the second range as the imaginary part .array; // convert the lazy range to a dynamic array, probably you can avoid but this depends on how you use it later assert(z.equal([ Complex!double(1.1, 3.3), Complex!double(2.2, 4.4), ])); } ```D
Re: Trivial simple OpenGl working example
08.07.2021 19:11, Виталий Фадеев пишет: I fix source code, as drug say. I've fixed the issue upstream, shortly gfm7 v1.1.2 will be available.
Re: Trivial simple OpenGl working example
08.07.2021 18:46, Виталий Фадеев пишет: On Thursday, 8 July 2021 at 15:30:07 UTC, drug wrote: 08.07.2021 17:20, Виталий Фадеев пишет: [...] I failed to reproduce that. What platform you use and what is the compiler version? drug, Linux, Ubuntu, x64 # uname -a Linux unknown 5.11.0-22-generic #23-Ubuntu SMP Thu Jun 17 00:34:23 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux # dmd --version DMD64 D Compiler v2.097.0 # dub --version DUB version 1.26.0, built on Jun 3 2021 # pkg-config --modversion sdl2 2.0.14 Yes, it's reproducible with dmd 2.097. Trivial fix is deleting that line `../../sdl2/gfm/sdl2/timer.d:69` then it works.
Re: Trivial simple OpenGl working example
08.07.2021 17:20, Виталий Фадеев пишет: vital@unknown:~/src/dtest/working-example/gfm7/examples/simpleshader$ dub run Fetching bindbc-opengl 0.15.0 (getting selected version)... Fetching colorize 1.0.5 (getting selected version)... Fetching gfm 8.0.6 (getting selected version)... Fetching bindbc-sdl 0.19.2 (getting selected version)... Fetching intel-intrinsics 1.4.0 (getting selected version)... Fetching bindbc-loader 0.3.2 (getting selected version)... Performing "debug" build using /usr/bin/dmd for x86_64. colorize 1.0.5: building configuration "library"... gfm7:logger 1.1.1: building configuration "library"... bindbc-loader 0.3.2: building configuration "noBC"... bindbc-opengl 0.15.0: building configuration "dynamic"... intel-intrinsics 1.4.0: building configuration "library"... gfm:math 8.0.6: building configuration "library"... gfm7:opengl 1.1.1: building configuration "unittest"... bindbc-sdl 0.19.2: building configuration "dynamic"... gfm7:sdl2 1.1.1: building configuration "library"... ../../sdl2/gfm/sdl2/timer.d(69,13): Warning: statement is not reachable Error: warnings are treated as errors Use -wi if you wish to treat warnings only as informational. /usr/bin/dmd failed with exit code 1. Error. Has dub flag for disable "warnings are treated as errors" ? I failed to reproduce that. What platform you use and what is the compiler version?
Re: Trivial simple OpenGl working example
08.07.2021 16:51, Виталий Фадеев пишет: Hi! I searching trivial simple D/OpenGL working in 2021 year example. It may be triangle. It may be based on any library: SDL, GLFW, Derelict, etc. Can you help me ? https://github.com/drug007/gfm7/tree/master/examples/simpleshader it's not trivial though but it works (tested in linux) just `dub fetch gfm7` then go to `path\to\gfm7\examples\simpleshader` and run `dub`. All kudos to Guillaume Piolat, original author of gfm library.
Re: How to disable assigning a value to a property?
06.07.2021 13:06, Jack Applegame пишет: Code: ```d import std.stdio; struct Field { void opAssign(int a) { writefln("Field.opAssign(%s)", a); } } struct Register { Field clock(int a) { writefln("Register.clock(%s)", a); return Field(); } } void main() { Register register; register.clock(1) = 10; // works, good register.clock = 10; // works too, how to disable it? } ``` How to disable `register.clock = 10;` but allow `register.clock(1) = 10;`? I want to get a compilation error on `register.clock = 10;` Something like using different types for arguments in `Register.clock` and `Field.opAssign`?
Re: Any 3D Game or Engine with examples/demos which just work (compile) out of the box on linux ?
07.06.2021 17:02, Prokop Hapala пишет: Basically I'm desperate do find anything which encapsulates OpenGL calls into some nice D-lang classes Did you try gfm? specifically its 7th version - [gfm7](https://github.com/drug007/gfm7)? It has nice [classes](https://github.com/drug007/gfm7/tree/master/opengl/gfm/opengl) to wrap OpenGL but the online documentation is currently unavailable. But the library itself is pretty nice documented. Ask me if you will help with it.
Re: wanting to try a GUI toolkit: needing some advice on which one to choose
02.06.2021 12:50, Ola Fosheim Grøstad пишет: Depends on the data, I guess, if they are all visible at once then you basically have to very carefully write your own GPU render stage for that view and carefully cache things that does not move by rendering them to buffers (in GPU memory). Usually 1 million of items aren't visible at once. Also there is opinion that total redrawing can be more efficient than caching because of making a decision what to cache and what not can be very complex. But if you deal with large number of items you basically can write your own view and dynamically create elements as the user scrolls. You do need to estimate the height though. To estimate the height you need to have height of every elements, you can't dynamically create elements in that case. I create some wrapper over data set that stores height of elements. It's much cheaper and faster than creating a widget per item - that is a real advantage over retained gui. And user has access to that info - that is advantage over immediate gui. But yes, there are tasks that can/should be performed by dynamically created elements.
Re: wanting to try a GUI toolkit: needing some advice on which one to choose
02.06.2021 00:47, Ola Fosheim Grøstad пишет: Note: Many simple GUI toolkits are horribly inefficient as they let each object render themselves. An efficient GUI engine will have to replicate some of the browser complexity... I tried retained and immediate GUI, both fail (imho) for my use case - large data set of 1M+ heterogeneous items. GTK and Qt are very complicated in case of TreeView widgets in contrast to dear imgui or nuklear. In retained GUI (GTK and Qt) you need to prepare your data, create some intermediate data, probably copy data. TreeView in immediate GUI (imgui, nuklear) is pretty trivial and intuitive - you just use your data w/o anything else but it draws all items always so immediate GUI works nice if you have small data set. nuklear lets you use large data set but only if items have the same height. But because an item of TreeView can be collapsed or not its height changes and you need to calculate height for each items - you can do it yourself but available implementations of immediate GUI aren't capable to use that info so you need to modify immediate GUI core system and that is very complicated job in contrast to retained GUI where adding new widget is much easier. I was forced to invent my own wheel some where in-between retained and immediate GUI. Later I got know that it worked like browsers did (of course in general). I think that browser-like GUI is the future. Just current browsers are very over-engineered. My impression is that immediate and retained GUI belong to different domains and are not interchangeable. Browser-like GUI is superset of both retained and immediate GUI. Just it should be implemented properly.
Re: Format
21.05.2021 16:45, newbie пишет: I am following https://wiki.dlang.org/Defining_custom_print_format_specifiers, why sink and formatValue are not @safe? What are the best practice for toString in safe code? Thank you sink is obsolete now, use W(riter) ```D import std.range : isOutputRange; void toString(W)(ref W writer) const if (isOutputRange!(W, char)) { // your stuff } ``` writer can be @safe, @nogc, nothrow etc like you want
Re: gtkd ,drawingarea, capture mouse pressed
21.05.2021 15:39, Alain De Vos пишет: I'll have a look at that website. With this code I capture the mouse press event ``` this() { addEvents(GdkEventMask.BUTTON_PRESS_MASK); addOnDraw(); addOnButtonPress(); } ``` ``` public bool onButtonPress(Event event, Widget widget) { writeln("Button pressed"); return false; } ``` But I still need the coordinates of pointer. I'm not gtk user too but you could try to use GdkEventMask.BUTTON_MOTION_MASK to get pointer motion events while some button is pressed
Re: Is inc function part of the library ?
13.05.2021 16:30, Alain De Vos пишет: Shouldn't the compiler error it is not pure ? Or have I a wrong understanding of pure or the compiler. The function is pure. If you call it several times passing the same argument it will return the same result. https://run.dlang.io/is/futqjP
Re: Question about property & method access scope.
11.05.2021 12:10, Vinod K Chandran пишет: Hi all, I am practising D with a win api GUI hobby project. I have a Window class and it resides in module window.d My WndProc function resides in another module named wnd_proc_module.d Inside my WndProc, I get the Window class like this. ```d Window win = cast(Window) (cast(void*) GetWindowLongPtrW(hWnd, GWLP_USERDATA)) ; ``` So in many situations, I need to check some boolean properties of Window class and call some functions of Window class in WndProc. But I don't want to expose those props and functions to the user. So if I make them private, I can't access them inside the WndProc function. How do solve this issue. Thanks in advance. Make them `protected`?
Re: Iteratable single linked list of floats.
21.04.2021 16:19, Alain De Vos пишет: import std.stdio; void main(){ struct List { struct Node { float f; Node *next; } Node * root=null; bool empty() const {return !root;} void popFront() {root=root.next;} float front() const {return root.f;} void push(float f) { Node * newnode=new Node(); newnode.f=f; root.next=newnode; // Segmentation fault } } List * l=new List(); l.push(3); foreach(element;l){ // Invalid foreach aggregate writeln(element.root.f); } } ```D import std.stdio; void main(){ struct List { struct Node { float f; Node *next; } Node * root=null; bool empty() const {return !root;} void popFront() {root=root.next;} float front() const {return root.f;} void push(float f) { Node * newnode=new Node(); newnode.f=f; if (root) // by default root is null so you need to initialize it first time root.next=newnode; else root = newnode; } } List * l=new List(); l.push(3); foreach(element; *l){ // Invalid foreach aggregate because `l` is a pointer to List, so you need to dereference the pointer writeln(element); } } ``` 1) you need to initialize the root 2) pointer to range is not valid foreach aggregate
[OT]
02.04.2021 15:06, Ali Çehreli пишет: For those who prefer a video description with some accent :) here is how What about accent - I'm curious what would you say about this old Russian sketch about English and its dialects (in English, no facebook account required): https://www.facebook.com/ABBYY.Lingvo/videos/954190547976075 skip first 50 seconds up to English part
Re: How to parse JSON in D?
I use asdf https://code.dlang.org/packages/asdf Also vibe-d https://code.dlang.org/packages/vibe-d has vibe-d:data subpackage
Re: Can't call splitter with range struct
On 3/16/21 1:58 AM, David Skluzacek wrote: > > Error: template std.algorithm.iteration.splitter cannot deduce function from argument types !()(GZippedFile, string), candidates are: > /usr/include/dlang/dmd/std/algorithm/iteration.d(4678): splitter(alias pred = "a == b", Range, Separator)(Range r, Separator s) >with pred = "a == b", > Range = GZippedFile, > Separator = string >must satisfy the following constraint: > is(typeof(binaryFun!pred(r.front, s)) : bool) That means that you should be able to call your predicate ("a == b") with GZippedFile.front and separator as arguments (they are dchar and string respectively) > (...) > > If I change the newline separator to a character literal, I get: > > (...) > /usr/include/dlang/dmd/std/algorithm/iteration.d(5055): splitter(alias pred = "a == b", Range, Separator)(Range r, Separator s) >with pred = "a == b", > Range = GZippedFile, > Separator = char >must satisfy the following constraint: > is(typeof(binaryFun!pred(r.front, s.front)) : bool) > > It seems like "\n" should pass the second constraint and '\n' should pass the first. Using a dchar or dstring makes no difference. Adding @property to front makes no difference. Is this a bug? > Also there are other constraints (see https://run.dlang.io/is/rcSJJf) like: /dlang/ldc-1.25.1/bin/../import/std/algorithm/iteration.d(5055): splitter(alias pred = "a == b", Range, Separator)(Range r, Separator s) with pred = "a == b", Range = GZippedFile, Separator = string must satisfy one of the following constraints: hasSlicing!Range isNarrowString!Range That means that you GZippedRange should provide opSlice operator and should be a narrow string (string of char or wchar)
Re: Profiling
On 2/10/21 2:52 PM, JG wrote: On Tuesday, 9 February 2021 at 18:33:16 UTC, drug wrote: On Tuesday, 9 February 2021 at 07:45:13 UTC, JG wrote: I was trying to profile a d program. So I ran: dub build --build=profile. I then ran the program and it produced trace.log and trace.def. I then ran d-profile-viewer and got the following error: std.conv.ConvException@/home/jg/dlang/ldc-1.24.0/bin/../import/std/conv.d(2382): Unexpected '-' when converting from type char[] to type ulong I'm guessing only but it looks like slurp is used to read text output but the format used does not correspond to the real data format. Thanks for the suggestions. However, I would prefer not to spend time trying to debug d-profile-viewer at the moment. As a follow up question I would like to know what tool people use to profile d programs? Could you provide trace.log that I can take a look? I have no much time but some bugs can be fixed fast. It would be ideal if you create the issue in the package repo and provides the test case. Also there is probability the author will fix this.
Re: Profiling
On Tuesday, 9 February 2021 at 07:45:13 UTC, JG wrote: I was trying to profile a d program. So I ran: dub build --build=profile. I then ran the program and it produced trace.log and trace.def. I then ran d-profile-viewer and got the following error: std.conv.ConvException@/home/jg/dlang/ldc-1.24.0/bin/../import/std/conv.d(2382): Unexpected '-' when converting from type char[] to type ulong I'm guessing only but it looks like slurp is used to read text output but the format used does not correspond to the real data format.
Re: Using mir to work with matrices
On 1/29/21 8:20 PM, 9il wrote: On Friday, 29 January 2021 at 15:35:49 UTC, drug wrote: Between is there a plan to implement some sort of static slice where the lengths of the dimensions are known in compile time? Compiler help is very useful. No. BLAS/LAPACK API's can't use compile-time information. User matrix I see loops can be optimized by the compiler using constants and without introducing new types. If you need a stack-allocated matrix, then a 1D stack-allocated array can be used > import mir.slice.slice; double[12] payload; auto matrix = payload[].sliced(3, 4); Yes, it's how I did it.
Re: Using mir to work with matrices
On 1/29/21 4:50 PM, 9il wrote: On Tuesday, 26 January 2021 at 14:43:08 UTC, drug wrote: It is not easy to understand what mir library one should use to work with matrices. mir-glas turns out unsupported now and I try to use mir-blas. I need to reimplement my Kalman filter version to use more high dimension matrix than 4x4 plus Kronecker product. Is mir-blas recommended to work with matrices? Yes, it is wrapper around a common BLAS libraries such as OpenBLAS or Intel MKL. I've implemented the filter using mir-lapack. But then I found lubeck - I didn't try it but it seemed that it provided more high level functionality like matrix inversion (`inv` wrapper is much handy than `getrf_` and `dgetri_` combination I used directly). So my first thought was that lubeck should be more preferable but then I found there was lubeck2 so I didn't know what to think further. But I pretty well understand the situation and the reasons behind it. Thank you for you efforts! Between is there a plan to implement some sort of static slice where the lengths of the dimensions are known in compile time? Compiler help is very useful.
Using mir to work with matrices
It is not easy to understand what mir library one should use to work with matrices. mir-glas turns out unsupported now and I try to use mir-blas. I need to reimplement my Kalman filter version to use more high dimension matrix than 4x4 plus Kronecker product. Is mir-blas recommended to work with matrices?
Re: Convert double to long if lossless
On 1/19/21 9:28 PM, Per Nordlöw wrote: On Tuesday, 19 January 2021 at 16:14:17 UTC, drug wrote: https://dlang.org/phobos/std_bitmanip.html#FloatRep Doesn't this pattern already cover all possible cases of `value` needed? void f(double value) { auto lvalue = cast(long)value; if (lvalue == value) // `value` lacks fraction and in range [long.min .. long.max] { // use long lvalue return; } // use double value } Sure. You don't even need to use isFinite like I wrote above because special values like inf and nan become some long values and will never equal to itself. Your question motivated me to do a little workout for my brains. Sorry if it confused you.
Re: Convert double to long if lossless
On 1/19/21 6:50 PM, Ali Çehreli wrote: On 1/19/21 6:04 AM, drug wrote: > Another (low level) way is to shift mantissa left by exponent value. Luckily, we already have a helper in Phobos: https://dlang.org/phobos/std_bitmanip.html#FloatRep Ali That makes life simpler, thanks for sharing this: ```D import std; void main() { auto valueRange = [ 10.001, 10.0001, // in fact this is just 10.0 ]; foreach(value; valueRange) { auto dr = DoubleRep(value); const hasFractional = !!(dr.fraction << (dr.exponent-1023+12)); writefln("has `%.18f` fractional part: %s", value, hasFractional); } } ``` but I think that casting to long and comparing it to the value is easier to understand and more portable: ```D import std; void main() { auto valueRange = [ 10.001, 10.0001, // in fact this is 10.0 ]; foreach(value; valueRange) { const hasFractional = (value != cast(long)value); writefln("has `%.18f` fractional part: %s", value, hasFractional); } } ``` P.S. shouldn't compiler emit the error if a literal can't be represented lossless?
Re: Convert double to long if lossless
On 1/19/21 5:04 PM, drug wrote: On 1/19/21 4:48 PM, Per Nordlöw wrote: On Tuesday, 19 January 2021 at 13:36:58 UTC, Steven Schveighoffer wrote: Use a cast instead. const lvalue = cast(long)value; Ahh, good point. Followd by a compare of the original value I presume. don't forget to check by std.math.isFinite before casting Another (low level) way is to shift mantissa left by exponent value. If the remainder equals to zero then no fractal part was encoded in the floating value. *fractional part
Re: Convert double to long if lossless
On 1/19/21 4:48 PM, Per Nordlöw wrote: On Tuesday, 19 January 2021 at 13:36:58 UTC, Steven Schveighoffer wrote: Use a cast instead. const lvalue = cast(long)value; Ahh, good point. Followd by a compare of the original value I presume. don't forget to check by std.math.isFinite before casting Another (low level) way is to shift mantissa left by exponent value. If the remainder equals to zero then no fractal part was encoded in the floating value.
Re: Directory recursive walking
On 1/14/21 7:06 PM, dog2002 wrote: On Thursday, 14 January 2021 at 16:01:43 UTC, drug wrote: On 1/14/21 6:55 PM, drug wrote: But this method consumes a huge amount of memory (up to 4 GB and more). Is there a more appropriate way to walk directories recursively that does not consume a lot of memory? DirEntry is a struct. First of all I would try this: ```D foreach(ref entry; dirEntries(path, SpanMode.shallow, false)) ``` Does your directory just contain large amount of files? Yes. I forgot to add it in the original post. How much files do you have? DirEntry size is 168 bytes only and dirEntry is lazy range so I'm curious what is the reason of huge memory consumption. Do you use Windows 32 bits between?
Re: Directory recursive walking
On 1/14/21 7:30 PM, dog2002 wrote: On Thursday, 14 January 2021 at 16:18:28 UTC, drug wrote: On 1/14/21 7:06 PM, dog2002 wrote: On Thursday, 14 January 2021 at 16:01:43 UTC, drug wrote: [...] Yes. I forgot to add it in the original post. Does using `ref` changed anything? Try following: ``` import std; void DirIteration(ref DirEntry dir) { try { foreach(ref entry; dirEntries(dir, SpanMode.shallow, false)) { //SpanMode.shallow allows skip directories if any error happens if (entry.isFile && !entry.isSymlink) writeln(entry); //Or something instead of this if (entry.isDir) DirIteration(entry); } } catch (Throwable) {} } void main() { auto de = DirEntry("."); DirIteration(de); } ``` No, it doesn't. Seems like memory can't clear. It is a recursion. Memory will be freed only after completion. Then I would try to get rid of recursion.
Re: Directory recursive walking
On 1/14/21 7:06 PM, dog2002 wrote: On Thursday, 14 January 2021 at 16:01:43 UTC, drug wrote: On 1/14/21 6:55 PM, drug wrote: But this method consumes a huge amount of memory (up to 4 GB and more). Is there a more appropriate way to walk directories recursively that does not consume a lot of memory? DirEntry is a struct. First of all I would try this: ```D foreach(ref entry; dirEntries(path, SpanMode.shallow, false)) ``` Does your directory just contain large amount of files? Yes. I forgot to add it in the original post. Does using `ref` changed anything? Try following: ``` import std; void DirIteration(ref DirEntry dir) { try { foreach(ref entry; dirEntries(dir, SpanMode.shallow, false)) { //SpanMode.shallow allows skip directories if any error happens if (entry.isFile && !entry.isSymlink) writeln(entry); //Or something instead of this if (entry.isDir) DirIteration(entry); } } catch (Throwable) {} } void main() { auto de = DirEntry("."); DirIteration(de); } ```
Re: Directory recursive walking
On 1/14/21 6:55 PM, drug wrote: But this method consumes a huge amount of memory (up to 4 GB and more). Is there a more appropriate way to walk directories recursively that does not consume a lot of memory? DirEntry is a struct. First of all I would try this: ```D foreach(ref entry; dirEntries(path, SpanMode.shallow, false)) ``` Does your directory just contain large amount of files?
Re: Directory recursive walking
On 1/14/21 6:46 PM, dog2002 wrote: I need to make some operations with all the files in a directory and subdirectories. Currently, I do it like this: import std; void DirIteration(string path) { try { foreach(entry; dirEntries(path, SpanMode.shallow, false)) { //SpanMode.shallow allows skip directories if any error happens if (entry.isFile && !entry.isSymlink) writeln(entry); //Or something instead of this if (entry.isDir) DirIteration(entry); } } catch (Throwable) {} } void main() { DirIteration("C:\\Users\\angrypuppy\\MyDir"); } But this method consumes a huge amount of memory (up to 4 GB and more). Is there a more appropriate way to walk directories recursively that does not consume a lot of memory? DirEntry is a struct. First of all I would try this: ```D foreach(ref entry; dirEntries(path, SpanMode.shallow, false)) ```
Re: How to debug D on Linux
On 1/13/21 4:47 PM, Roguish wrote: Also, what does it mean to "always emit a stackframe" (compiler option -gs) ? Short answer - sometimes the compiler does not emit a stackframe (due to optimization for example). In general if you are able to debug your binary by gdb then you don't need to worry this flag. I skip long answer, sorry :-) But you can google about stack frame.
Re: How to debug D on Linux
On 1/13/21 4:47 PM, Roguish wrote: On Wednesday, 13 January 2021 at 13:30:48 UTC, Roguish wrote: Anything else I need to know when debugging on Linux, without an IDE? One specific question I have is: what's the difference between -g and -debug and -d-debug? Also, what does it mean to "always emit a stackframe" (compiler option -gs) ? https://stackoverflow.com/questions/17392200/debugging-dmd-generate-program-through-gdb
Re: Can I output strings using core.stdc.stdio?
On 12/23/20 3:23 PM, Godnyx wrote: Any ideas? Just fix your typos: ```D import std : printf, toStringz; void put(A...)(string prompt, A args) { static foreach (ulong i; 0..args.length) { static if (is(typeof(args[i]) == string)) printf("%s\n", args[i].toStringz); static if (is(typeof(args[i]) == int)) printf("%i\n", args[i]); static if (is(typeof(args[i]) == bool)) { if (args[i]) printf("true"); else printf("false"); } } } void main() { put("Prompt:", "Hello, my age is: ", 19, true); } ``` P.S. replace `arg` by `args[i]`
Re: Running unit tests from DUB single file packages
On 12/22/20 8:32 PM, jmh530 wrote: On Tuesday, 22 December 2020 at 15:06:09 UTC, drug wrote: [snip] But what do you mean exactly by "work with dependency"? As I understand, `dub test` does not run unit tests in dependencies and single file packages work with dependencies in general. Do you mean something else? I'm finishing the new PR to fix #2051 finally and I'd like to know if there is something else I should include in it. https://github.com/dlang/dub/pull/2064 Thanks. It looks like your UT with taggedalgebraic does exactly what I was looking for. My problem is that run.dlang.org will skip unittests when you have dependencies. I had made some progress on fixing this a few months ago [1], but put it on the back burner when I ran into similar issues that the OP was dealing with. The problem ultimately came down to dub test not working with --single, which it looks like this latest PR will fix for good. [1] https://github.com/dlang-tour/core-exec/pull/56 Ah, I see. Then I would say that `dub test` doesn't run unit tests from the main source file (where the main function is placed). And this is the reason, I guess. Now `dub test` runs unit tests from the main source file if the package is a single file one. I think that dependencies is irrelevant here, at least I didn't do anything special for them. Let's see what happens.
Re: Running unit tests from DUB single file packages
On 12/22/20 10:52 AM, drug wrote: On 12/21/20 7:31 PM, jmh530 wrote: On Monday, 21 December 2020 at 11:31:49 UTC, drug wrote: [snip] Unfortunately I'm very busy. But I check it again and it turns out that the fix does not resolve the problem completely. This PR just remove the single file from testing so currently dub does not run unit tests in the single file package at all. The first variant (https://github.com/dlang/dub/pull/2050) fixes the issue indeed. I need to reevaluate these PRs and close the issue. I'll do it later. Thanks for taking a look. Not at all. But what do you mean exactly by "work with dependency"? As I understand, `dub test` does not run unit tests in dependencies and single file packages work with dependencies in general. Do you mean something else? I'm finishing the new PR to fix #2051 finally and I'd like to know if there is something else I should include in it. https://github.com/dlang/dub/pull/2064
Re: Running unit tests from DUB single file packages
On 12/21/20 7:31 PM, jmh530 wrote: On Monday, 21 December 2020 at 11:31:49 UTC, drug wrote: [snip] Unfortunately I'm very busy. But I check it again and it turns out that the fix does not resolve the problem completely. This PR just remove the single file from testing so currently dub does not run unit tests in the single file package at all. The first variant (https://github.com/dlang/dub/pull/2050) fixes the issue indeed. I need to reevaluate these PRs and close the issue. I'll do it later. Thanks for taking a look. Not at all. But what do you mean exactly by "work with dependency"? As I understand, `dub test` does not run unit tests in dependencies and single file packages work with dependencies in general. Do you mean something else? I'm finishing the new PR to fix #2051 finally and I'd like to know if there is something else I should include in it.
Re: Running unit tests from DUB single file packages
On 12/20/20 9:31 PM, jmh530 wrote: On Wednesday, 2 December 2020 at 12:51:11 UTC, drug wrote: [snip] Thanks! Let's see if it gets merged or if a slightly more involved solution is needed. Remake it - https://github.com/dlang/dub/pull/2052 This has more chances to be merged Looks like this got merged and will be part of the newest version, which is great news. Have you checked that it works with dependencies? Unfortunately I'm very busy. But I check it again and it turns out that the fix does not resolve the problem completely. This PR just remove the single file from testing so currently dub does not run unit tests in the single file package at all. The first variant (https://github.com/dlang/dub/pull/2050) fixes the issue indeed. I need to reevaluate these PRs and close the issue. I'll do it later.
Re: binary search
Phobos provides this by SortedRange: https://dlang.org/phobos/std_range.html#.SortedRange Example of usage: https://run.dlang.io/is/WW2bn0
Re: Running unit tests from DUB single file packages
On 12/1/20 5:18 PM, Johannes Loher wrote: Am 01.12.20 um 14:55 schrieb drug: On 12/1/20 2:40 PM, Johannes Loher wrote: ... However, I am having trouble running the unit tests when using the ... This can be one of solution https://github.com/dlang/dub/pull/2050 Thanks! Let's see if it gets merged or if a slightly more involved solution is needed. Remake it - https://github.com/dlang/dub/pull/2052 This has more chances to be merged
Re: Running unit tests from DUB single file packages
On 12/1/20 2:40 PM, Johannes Loher wrote: ... However, I am having trouble running the unit tests when using the ... This can be one of solution https://github.com/dlang/dub/pull/2050
Re: Druntime undefined references
On 11/2/20 1:50 PM, Severin Teona wrote: Hi guys! I build the druntime for an ARM Cortex-M based microcontroller and I trying to create an application and link it with the druntime. I am also using TockOS[1], which does not implement POSIX thread calls and other OS-dependent implementations. As I was looking through the errors I got, I found some functions and I don’t know what they do, or how should I solve the errors. The first one is: libdruntime-ldc.a(dwarfeh.o): in function `_d_eh_personality_common': dwarfeh.d:(.text._d_eh_personality_common[_d_eh_personality_common]+0x2c): undefined reference to `_d_eh_GetIPInfo' and the second one is: dl.d:(.text._D4core8internal3elf2dl12SharedObject14thisExecutableFNbNiZSQCgQCeQByQBxQBx[_D4core8internal3elf2dl12SharedObject14thisExecutableFNbNiZSQCgQCeQByQBxQBx]+0x1a): undefined reference to `dl_iterate_phdr' (the druntime was build as a static library, because I can’t use dynamic libraries on a microcontroller) Does anyone know what these exactly do and how important/essential are they? Is there any way I could solve them? Thank a lot. [1]: https://www.tockos.org cant' help much but just in case - see https://github.com/ldc-developers/ldc/pull/2405#issuecomment-346187456, may be it helps also you can define this symbol yourself with assert(0) to check if it is called at all what about - quick glance at https://linux.die.net/man/3/dl_iterate_phdr says us that this symbol is used only with shared objects so you can try to define it yourself with assert(0) like this (not tested!!!): ```D extern(C): alias Callback = int function (void*, size_t, void*); int dl_iterate_phdr(Callback callback, void* data) { assert(0); } ``` this lets you to link druntime at least and if those symbols were called abort the execution
Re: Skipping or Stepping Through an Array?
There are two other way: ```D import std; void main() { int[] a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ]; // using foreach foreach (i; 0..a.length) write(a[i], ", "); writeln; // using stride writeln(stride(a, 2)); } ```
Re: GC-less string formatting
On 10/20/20 9:42 AM, Per Nordlöw wrote: If I want GC-free string formatting and outputting to stdout/stderr what packages should I prefer at code.dlang.org? Probably https://code.dlang.org/packages/nogc
Re: question on dub and postgresql
On 10/5/20 12:05 PM, Alaindevos wrote: On Monday, 5 October 2020 at 08:54:39 UTC, Daniel Kozak wrote: On Mon, Oct 5, 2020 at 10:25 AM Alaindevos via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: Can I say python has pip, ruby has bundle and D has dub. Meaning they perform the same function ? Or am I wrong? Yes and no. Dub is Dlang dependency solution but it is not installer as pip is As I use unix the parameters for include and library are a real pain. I have totally no idea how to connect to a postgresql database. Where and how do I start to connect to a postgresql database ? I write a .d program to connect. But then I need to include the database-connection-library.d file. Where do I place it ? And link a database-connection. object file. How is it installed ? There is a only a git i can clone ? Do I need to create and edit a specific dub json config file ? It is very unclear how to start. Yes if you want to use any of dub packages you need to add it as a dependency to your dub.json (dub.sdl) A name dependency solution is at least vage. How do I install , https://github.com/denizzzka/dpq2 on unix so in the code i write the .d files of that library and after compilation linked to the libary shared objects. For that shared object must be installed. How ? Take a look at https://code.dlang.org/packages/dpq2 This is how packages work in D To add dpq2 dependency to your project you need to execute the command: ``` dub add dpq2 ``` it adds the last version of the dpq2 package. After this you are able to use this package in your project just import it in your source files.
Re: help: cannot build profdump, dub error (bug): Enforcement failed
On 9/29/20 4:38 PM, drug wrote: It reproduces. As a workaround you can use ``` dub run profdump ``` this command works as expected, I guess it is a bug of dub Do not execute this command in cloned `profdump` repository - it will fail too. It works if is called from other places, for example in home.
Re: help: cannot build profdump, dub error (bug): Enforcement failed
On 9/29/20 3:41 PM, mw wrote: I remember I used to able to build this package: https://github.com/AntonMeep/profdump but now, I cannot. Since that package haven't changed for 2 years, maybe it's a dub bug? System information $ uname -a Linux 4.15.0-117-generic #118-Ubuntu SMP Fri Sep 4 20:02:41 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux $ /usr/bin/dub --version DUB version 1.23.0, built on Sep 27 2020 $ /usr/bin/dmd --version DMD64 D Compiler v2.094.0 Copyright (C) 1999-2020 by The D Language Foundation, All Rights Reserved written by Walter Bright $ /usr/bin/dub build -v Using dub registry url 'https://code.dlang.org/' Refreshing local packages (refresh existing: true)... Looking for local package map at /var/lib/dub/packages/local-packages.json ... ... No valid package found in current working directory: Enforcement failed Enforcement failed Bug Description Enforcement failed How to reproduce? ``` git clone https://github.com/AntonMeep/profdump cd profdump dub build ``` https://github.com/dlang/dub/issues/2017 It reproduces. As a workaround you can use ``` dub run profdump ``` this command works as expected, I guess it is a bug of dub
Re: Why is dtor called for lazy parameter?
On 9/18/20 4:30 PM, drug wrote: Can't you put a var on the stack? ``` auto instance = create(); instance .do_lazy() .do_something(); ``` Ah, I totally missed your point. Now I see you can't...
Re: Why is dtor called for lazy parameter?
Can't you put a var on the stack? ``` auto instance = create(); instance .do_lazy() .do_something(); ```
Re: UDA inheritance
On 9/10/20 4:06 PM, Joseph Rushton Wakeling wrote: Hello folks, Is there any way to define UDAs such that they automatically inherit other UDA definitions? For example, suppose I define: enum BaseUDA { A, B } Is there a way to define `AnotherUDA` such that if `hasUDA!(T, AnotherUDA)` then it is a given that `hasUDA!(T, BaseUDA)` will also be true? (And similarly for the `A`, `B` specializations?) The use-case here is to create a UDA that defines some general distinction of code properties, and to allow downstream code to define its own more specialized cases of that distinction. Thanks in advance for any thoughts or advice! Thanks and best wishes, -- Joe Just a thought - couldn't you use classes for this? Get an UDA and check if it is a descendant of the specific class.
Re: Where can I find the DEFINITION of vibe IOMode ??
05.09.2020 23:19, Andy Balba пишет: https://github.com/vibe-d/eventcore/blob/a027c233c2542de8372bbff25d0a4804f32a094e/source/eventcore/driver.d#L1087 @drug: thank you..I'm now left with resolving @blocking you are welcome! Probably this? https://github.com/vibe-d/vibe-core/blob/6ceb462ab68079ab24bfc57b1168dae610099357/source/vibe/core/stream.d#L88
Re: Where can I find the DEFINITION of vibe IOMode ??
05.09.2020 22:17, Andy Balba пишет: Where do I fine where IOMode is defined.. as in the last line of ... module vibe.core.stream; import vibe.internal.traits : checkInterfaceConformance, validateInterfaceConformance; import vibe.internal.interfaceproxy; import core.time; import std.algorithm; import std.conv; public import eventcore.driver : IOMode; After endless searches, I find many references to it, but never a DEFINITION of it https://github.com/vibe-d/eventcore/blob/a027c233c2542de8372bbff25d0a4804f32a094e/source/eventcore/driver.d#L1087
Re: Install multiple executables with DUB
On 9/4/20 10:27 AM, glis-glis wrote: On Thursday, 3 September 2020 at 14:34:48 UTC, Jacob Carlborg wrote: Oh, multiple binaries, I missed that. You can try to add multiple configurations [1]. Or if you have executables depending on only one source file, you can use single-file packages [2]. Thanks, but this still means I would have to write an install-script running `dub build --single` on each script, right? I looked at tsv-utils [1] which seems to be a similar use-case as mine, and they declare each tool as a subpackage. The main package runs a d-file called `dub_build.d` which compiles all subpackages. Fells like an overkill to me, I'll probably just stick to a makefile. [1] https://github.com/eBay/tsv-utils/blob/master/docs/AboutTheCode.md#building-and-makefile I don't know is it suitable for your use case but I do the following: 1. add a recipe in every tool files like: ``` drug@drug: ~/utils$ cat ./tools/count.d #!/usr/bin/env dub /+ dub.sdl: name"count" targetType "executable" targetPath "../bin" targetName "count" dependency "abcdLibrary" version="*" path="path/to/abcdLibrary" +/ int main() { ... } ``` 2. place all tool files into one directory `tools` 3. build them using `dub build --single tools/count.d` 4. Now I have all binary in `bin` directory, all sources in `tools` directory and have no subpackages at all
Re: Problem with gfm.math.matrix (some gamedevs out there ?)
On 9/3/20 3:36 PM, Thomas wrote: Hi! I am following some examples in C++ about how OpenGL is working. There are great tutorials out there and most of it works also with D. For my code I am using gfm.math.matrix (Version 8.0.3) to be able to calculate the mouse position in a 3d world. Now I have some problems with the projection matrix by inverting it. My example code: - import std.stdio; int main() { import gfm.math.matrix; const int width = 800; const int height = 600; auto projectionMatrix = mat4!(float).identity(); auto ratio = cast(float)width / cast(float)height; projectionMatrix = mat4!(float).perspective( 45.0f, ratio, 0.0f, 100.0f ); writeln("projectionMatrix: ", projectionMatrix ); auto inversedMatrix = mat4!(float).identity(); inversedMatrix = projectionMatrix.inverse(); // <-- why this does not work ? writeln("inversedMatrix: ", inversedMatrix ); return 0; } The projection matrix will be calculated correctly with [1.3, 0, 0, 0, 0, 1.79259, 0, 0, 0, 0, -1, -0, 0, 0, -1, 0] assuming that the screen size is 800x600. But using the .inverse() function in gfm returns only a matrix with following values: [-nan, -nan, -nan, -nan, -nan, -nan, -nan, -nan, -nan, -nan, -nan, -nan, -nan, -nan, inf, -inf] I don't know what I am doing wrong here: - do I call the function wrong way ? (but there is no other way) - is there a bug in the function ? (I do not believe that because the library is battle proved) So I looked a couple of hours for an answer, but did not find anything useful. Is somebody out there who could help me out ? Maybe one developer of the d gfm library ? Thank you for you time! Thomas 1. zNear should not be equal to zero, this makes your matrix singular and inversion of singular matix is impossible so you get nans and infs. Make zNear a little bit more than zero and your code will work 2. FOV in perspective should be expressed in radians, not degrees so this fixes your problem: ``` projectionMatrix = mat4!(float).perspective( 45.0f * 3.14 / 180., ratio, 0.01f, 100.0f ); ```
Re: Unable to open filename passed as command line argument
On 9/3/20 1:47 PM, Curious wrote: Given the following: =a== void main(string[] args) { FILE* fp = fopen(args[1].ptr, "r"); if (!fp) throw new Exception("fopen"); } =b== void main(string[] args) { FILE* fp = fopen(args[1].dup.ptr, "r"); if (!fp) throw new Exception("fopen"); } Why does a fail but b succeed? try `toStringz`: ```D import std.string : toStringz; void main(string[] args) { FILE* fp = fopen(args[1].toStringz, "r"); if (!fp) throw new Exception("fopen"); } ``` The reason is that args are D strings (that contains no terminating 0) but `fopen` gets C string (null terminated) so your `a` variant fails because the filename becomes wrong as there is no terminating 0. Your `b` variant works in fact accidentally because after duplication in new memory after filename 0 appears due to random reason (for example all that memory area zeroed by allocator).
Re: Accurately serializing and deserializing a SysTime in binary format
On 7/21/20 2:44 PM, Ecstatic Coder wrote: Ah thanks for telling me :) The loaded byte array in the union type was indeed the same as the saved one, so I immediately thought it was crashing because of some hidden pointer for timezone or something which was then pointing to garbage at reloading, causing the crash of the ".toISOString" call. Ah, sorry, I serialize exactly long value and use it as SysTime, for example: ```D struct Foo { long value; void toString(Writer)(ref Writer w) const if (isOutputRange!(Writer, char)) { import std.datetime: SysTime; value.SysTime.toUTC.toISOExtString(w); } } ``` So it is not exactly what you said
Re: Accurately serializing and deserializing a SysTime in binary format
On 7/20/20 10:04 PM, Ecstatic Coder wrote: I'm currently implementing a small open source backup tool (dub), and therefore I need to accurately store the file modification SysTime in binary format, so that I can later load this SysTime from the snapshot file to compare it with the current file modification SysTime. Having unfortunately not understood how to do this from the SysTime documentation, in despair, I've tried to directly serialize the 16 bytes of the SysTime value. This worked fine until I call the ".toISOString()" on the deserialized SysTime, which inevitably crashes the executable ;) That is probably a bug. I serialize SysTime as long by means msgpack for exchanging between C++ client and D server and it works pretty nice. Anyway, that's not really want I intended to do, as in practice a "ulong" already has enough resolution for that purpose. So sorry for my ignorance, but I would definitely need some help on how to : - convert a file modification SysTime to a serializable number, for instance the number of hectonanoseconds since 1/1/1970 in UTC; - convert that number back into a SysTime that I can compare to the modification SysTime of the same file. Eric
Re: Storing a reference to the calling object
23.05.2020 12:27, Tim пишет: class Sprite{ /// Postional components of the sprite int* x, y; SDL_Surface* image_surface; auto parent; this(const char* path, auto parent){ writeln(*x); this.parent = parent; } void update(){ // Copy loaded image to window surface writeln("Sprites x: ", *x); SDL_Rect dstRect; dstRect.x = parent.x; dstRect.y = parent.y; SDL_BlitSurface(image_surface, null, g_surface, ); } } You can make the Sprite class templated one: ``` class Sprite(T){ /// Postional components of the sprite int* x, y; SDL_Surface* image_surface; T parent; this(const char* path, T parent){ writeln(*x); this.parent = parent; } void update(){ // Copy loaded image to window surface writeln("Sprites x: ", *x); SDL_Rect dstRect; dstRect.x = parent.x; dstRect.y = parent.y; SDL_BlitSurface(image_surface, null, g_surface, ); } } auto sprite(T)(const char* path, T parent) { return new Sprite!T(path, parent); } ``` and use it like: ``` auto sprite = sprite(path, this); ```
Re: Getting FieldNameTuple including all base-classes.
On 5/20/20 12:03 PM, realhet wrote: On Wednesday, 20 May 2020 at 01:18:24 UTC, Paul Backus wrote: On Tuesday, 19 May 2020 at 23:15:45 UTC, realhet wrote: I think what you want is `std.meta.staticMap`. Something like this: alias FieldNameTuple2(T) = staticMap!(FieldNameTuple, BaseClassesTuple!T); class A { int a, a1; } class B : A { int b; } class C : B { int c, c1; } alias AllClasses(T) = Reverse!(AliasSeq!(T, BaseClassesTuple!T[0..$-1])); alias AllFieldNames(T) = staticMap!(FieldNameTuple, AllClasses!T); void main(){ static foreach(T; "ABC") mixin("AllFieldNames!"~T~".stringof.writeln;"); } That statticMap unlike the normal map, it also joins the AliasSeq at the end. Just what I needed. Thank You! Just in case - you can avoid mixin using: ```D static foreach(T; AliasSeq!(A, B, C)) AllFieldNames!T.stringof.writeln; ``` https://run.dlang.io/is/Q6omgL
Re: How to get rid of "nothrow" ?
On 5/18/20 11:47 PM, Vinod K Chandran wrote: On Sunday, 17 May 2020 at 19:37:05 UTC, drug wrote: 17.05.2020 17:35, Vinod K Chandran пишет: It worked. Thanks :) I have one more question. Which is better, to include all the switch cases inside a single try catch or write separate try catch for each switch cases ? all the switch cases inside a single try catch is better Thanks a lot. :) Frankly speaking in some cases separate try catch blocks will be more suitable but while you do not see the difference in your case then use the single block for everything
Re: How to get rid of "nothrow" ?
17.05.2020 17:35, Vinod K Chandran пишет: It worked. Thanks :) I have one more question. Which is better, to include all the switch cases inside a single try catch or write separate try catch for each switch cases ? all the switch cases inside a single try catch is better
Re: Error running concurrent process and storing results in array
07.05.2020 17:49, data pulverizer пишет: On Thursday, 7 May 2020 at 02:06:32 UTC, data pulverizer wrote: On Wednesday, 6 May 2020 at 10:23:17 UTC, data pulverizer wrote: D: ~ 1.5 seconds This is going to sound absurd but can we do even better? If none of the optimizations we have so far is using simd maybe we can get even better performance by using it. I think I need to go and read a simd primer. After running the Julia code by the Julia community they made some changes (using views rather than passing copies of the array) and their time has come down to ~ 2.5 seconds. The plot thickens. That's a good sign because I was afraid that super short D time was a result of wrong benchmark (too good to be truth). I'm glad D time really is both great and real. Your blog post definitely will be very interesting.
Re: Error running concurrent process and storing results in array
06.05.2020 13:23, data pulverizer пишет: On Wednesday, 6 May 2020 at 08:28:41 UTC, drug wrote: What is current D time? ... Current Times: D: ~ 1.5 seconds Chapel: ~ 9 seconds Julia: ~ 35 seconds Oh, I'm impressed. I thought that D time has been decreased by 1.5 seconds but it is 1.5 seconds! That would be really nice if you make the resume of your research. Yes, I'll do a blog or something on GitHub and link it. Thanks for all your help. You're welcome! Helping others helps me too.
Re: Error running concurrent process and storing results in array
06.05.2020 16:57, Steven Schveighoffer пишет: ``` foreach(i; 0..n) // instead of for(long i = 0; i < n;) ``` I guess that `proc` delegate cant capture `i` var of `foreach` loop so the range violation doesn't happen. foreach over a range of integers is lowered to an equivalent for loop, so that was not the problem. I was surprised but `foreach` version do not have range violation, so there is difference between `foreach` and `for` loops. I did not try DerivedThread at all, only suggested them to avoid var capture. I just changed `for` by `foreach` and range violation gone. Probably this is implementation details.
Re: How to port C++ std::is_reference to D ?
06.05.2020 12:07, wjoe пишет: Hello, I'm choking on a piece of C++ I have no idea about how to translate to D. template typename std::enable_if< std::is_const::value == true, void>::type* = nullptr> constexpr const char *modifier() const { return "[in] "; } template typename std::enable_if< std::is_reference::value == true, void>::type* = nullptr> constexpr const char *modifier() const { return "[out] "; } my attempt at it is like this: template modifier(T) { static if (is (T==const)) { const char* modifier = "[in] "; } else static if (/* T is a reference ?*/) { // [*] const char* modifier = "[out] "; } } but even if I could e.g. say something like is(T == ref R, R), auto a = modifier!(ref T); wouldn't work. did you try https://dlang.org/spec/traits.html#isRef?
Re: Error running concurrent process and storing results in array
06.05.2020 11:18, data pulverizer пишет: CPU usage now revs up almost has time to touch 100% before the process is finished! Interestingly using `--boundscheck=off` without `--ffast-math` gives a timing of around 4 seconds and, whereas using `--ffast-math` without `--boundscheck=off` made no difference, having both gives us the 1.5 seconds. As Jacob Carlborg suggested I tried adding `-mcpu=native -flto=full -defaultlib=phobos2-ldc-lto,druntime-ldc-lto` but I didn't see any difference. Current Julia time is still around 35 seconds even when using @inbounds @simd, and running julia -O3 --check-bounds=no but I'll probably need to run the code by the Julia community to see whether it can be further optimized but it's pretty interesting to see D so far in front. Interesting when I attempt to switch off the garbage collector in Julia, the process gets killed because my computer runs out of memory (I have over 26 GB of memory free) whereas in D the memory I'm using barely registers (max 300MB) - it uses even less than Chapel (max 500MB) - which doesn't use much at all. It's exactly the same computation, D and Julia's timing were similar before the GC optimization and compiler flag magic in D. What is current D time? That would be really nice if you make the resume of your research.
Re: Error running concurrent process and storing results in array
06.05.2020 10:42, data pulverizer пишет: On Wednesday, 6 May 2020 at 07:27:19 UTC, data pulverizer wrote: On Wednesday, 6 May 2020 at 06:54:07 UTC, drug wrote: Thing are really interesting. So there is a space to improve performance in 2.5 times :-) Yes, `array` is smart enough and if you call it on another array it is no op. What means `--fast` in Chapel? Do you try `--fast-math` in ldc? Don't know if 05 use this flag I tried `--fast-math` in ldc but it didn't make any difference the documentation of `--fast` in Chapel says "Disable checks; optimize/specialize". Just tried removing the boundscheck and got 1.5 seconds in D! Congrats! it looks like the thriller! What about cpu usage? the same 40%?
Re: Error running concurrent process and storing results in array
06.05.2020 09:43, data pulverizer пишет: On Wednesday, 6 May 2020 at 05:50:23 UTC, drug wrote: General advice - try to avoid using `array` and `new` in hot code. Memory allocating is slow in general, except if you use carefully crafted custom memory allocators. And that can easily be the reason of 40% cpu usage because the cores are waiting for the memory subsystem. I changed the Matrix object from class to struct and timing went from about 19 seconds with ldc2 and flags `-O5` to 13.69 seconds, but CPU usage is still at ~ 40% still using `taskPool.parallel(iota(n))`. The `.array` method is my method for the Matrix object just returning internal data array object so it shouldn't copy. Julia is now at about 34 seconds (D was at about 30 seconds while just using dmd with no optimizations), to make things more interesting I also did an implementation in Chapel which is now at around 9 seconds with `--fast` flag. Thing are really interesting. So there is a space to improve performance in 2.5 times :-) Yes, `array` is smart enough and if you call it on another array it is no op. What means `--fast` in Chapel? Do you try `--fast-math` in ldc? Don't know if 05 use this flag
Re: Error running concurrent process and storing results in array
06.05.2020 09:24, data pulverizer пишет: On Wednesday, 6 May 2020 at 05:44:47 UTC, drug wrote: proc is already a delegate, so is a pointer to the delegate, just pass a `proc` itself Thanks done that but getting a range violation on z which was not there before. ``` core.exception.RangeError@onlineapp.d(3): Range violation ??:? _d_arrayboundsp [0x55de2d83a6b5] onlineapp.d:3 void onlineapp.process(double, double, long, shared(double[])) [0x55de2d8234fd] onlineapp.d:16 void onlineapp.main().__lambda1() [0x55de2d823658] ??:? void core.thread.osthread.Thread.run() [0x55de2d83bdf9] ??:? thread_entryPoint [0x55de2d85303d] ??:? [0x7fc1d6088668] ``` confirmed. I think that's because `proc` delegates captures `i` variable of `for` loop. I managed to get rid of range violation by using `foreach`: ``` foreach(i; 0..n) // instead of for(long i = 0; i < n;) ``` I guess that `proc` delegate cant capture `i` var of `foreach` loop so the range violation doesn't happen. you use `proc` delegate to pass arguments to `process` function. I would recommend for this purpose to derive a class from class Thread. Then you can pass the arguments in ctor of the derived class like: ``` foreach(long i; 0..n) new DerivedThread(double)(i), cast(double)(i + 1), i, z).start(); thread_joinAll(); ``` not tested example of derived thread ``` class DerivedThread { this(double x, double y, long i, shared(double[]) z) { this.x = x; this.y = y; this.i = i; this.z = z; super(); } private: void run() { process(x, y, i, z); } double x, y; long i; shared(double[]) z; } ```
Re: Error running concurrent process and storing results in array
06.05.2020 07:52, data pulverizer пишет: On Wednesday, 6 May 2020 at 04:04:14 UTC, Mathias LANG wrote: On Wednesday, 6 May 2020 at 03:41:11 UTC, data pulverizer wrote: Yes, that's exactly what I want the actual computation I'm running is much more expensive and much larger. It shouldn't matter if I have like 100_000_000 threads should it? The threads should just be queued until the cpu works on it? It does matter quite a bit. Each thread has its own resources allocated to it, and some part of the language will need to interact with *all* threads, e.g. the GC. In general, if you want to parallelize something, you should aim to have as many threads as you have cores. Having 100M threads will mean you have to do a lot of context switches. You might want to look up the difference between tasks and threads. Sorry, I meant 10_000 not 100_000_000 I square the number by mistake because I'm calculating a 10_000 x 10_000 matrix it's only 10_000 tasks, so 1 task does 10_000 calculations. The actual bit of code I'm parallelising is here: ``` auto calculateKernelMatrix(T)(AbstractKernel!(T) K, Matrix!(T) data) { long n = data.ncol; auto mat = new Matrix!(T)(n, n); foreach(j; taskPool.parallel(iota(n))) { auto arrj = data.refColumnSelect(j).array; for(long i = j; i < n; ++i) { mat[i, j] = K.kernel(data.refColumnSelect(i).array, arrj); mat[j, i] = mat[i, j]; } } return mat; } ``` At the moment this code is running a little bit faster than threaded simd optimised Julia code, but as I said in an earlier reply to Ali when I look at my system monitor, I can see that all the D threads are active and running at ~ 40% usage, meaning that they are mostly doing nothing. The Julia code runs all threads at 100% and is still a tiny bit slower so my (maybe incorrect?) assumption is that I could get more performance from D. The method `refColumnSelect(j).array` is (trying to) reference a column from a matrix (1D array with computed index referencing) which I select from the matrix using: ``` return new Matrix!(T)(data[startIndex..(startIndex + nrow)], [nrow, 1]); ``` If I use the above code, I am I wrong in assuming that the sliced data (T[]) is referenced rather than copied? That so if I do: ``` auto myData = data[5...10]; ``` myData is referencing elements [5..10] of data and not creating a new array with elements data[5..10] copied? General advice - try to avoid using `array` and `new` in hot code. Memory allocating is slow in general, except if you use carefully crafted custom memory allocators. And that can easily be the reason of 40% cpu usage because the cores are waiting for the memory subsystem.
Re: Error running concurrent process and storing results in array
06.05.2020 07:25, data pulverizer пишет: On Wednesday, 6 May 2020 at 03:56:04 UTC, Ali Çehreli wrote: On 5/5/20 8:41 PM, data pulverizer wrote:> On Wednesday, 6 May 2020 at 03:33:12 UTC, Mathias LANG wrote: >> On Wednesday, 6 May 2020 at 03:25:41 UTC, data pulverizer wrote: > Is there something I need to do to wait for each thread to finish > computation? thread_joinAll(). I have an example here: http://ddili.org/ders/d.en/concurrency.html#ix_concurrency.thread_joinAll This worked nicely thank you very much ... I want to point out that there is also std.parallelism, which may be better suited in many cases. I actually started off using std.parallelism and it worked well but the CPU usage on all the threads was less than half on my system monitor meaning there is more performance to be wrung out of my computer, which is why I am now looking into spawn. When you suggested using thread_joinAll() I saw that is in `core.thread.osthread` module. It might be shaving the yak this point but I have tried using `Thread` instead of `spawn`: ``` void process(double x, double y, long i, shared(double[]) z) { z[i] = x*y; } void main() { import core.thread.osthread; import std.stdio: writeln; long n = 100; shared(double[]) z = new double[n]; for(long i = 0; i < n; ++i) { auto proc = (){ process(cast(double)(i), cast(double)(i + 1), i, z); return; }; proc is already a delegate, so is a pointer to the delegate, just pass a `proc` itself new Thread().start(); } thread_joinAll(); writeln("z: ", z); } ``` and I am getting the following error: ``` onlineapp.d(20): Error: none of the overloads of this are callable using argument types (void delegate() @system*), candidates are: /dlang/dmd/linux/bin64/../../src/druntime/import/core/thread/osthread.d(646): core.thread.osthread.Thread.this(void function() fn, ulong sz = 0LU) /dlang/dmd/linux/bin64/../../src/druntime/import/core/thread/osthread.d(671): core.thread.osthread.Thread.this(void delegate() dg, ulong sz = 0LU) /dlang/dmd/linux/bin64/../../src/druntime/import/core/thread/osthread.d(1540): core.thread.osthread.Thread.this(ulong sz = 0LU) ```
Re: Error running concurrent process and storing results in array
06.05.2020 06:25, data pulverizer пишет: ``` onlineapp.d(14): Error: template std.concurrency.spawn cannot deduce function from argument types !()(void delegate(double x, double y, long i, shared(double[]) z) pure nothrow @nogc @safe, double, double, long, shared(double[])), candidates are: /dlang/dmd/linux/bin64/../../src/phobos/std/concurrency.d(460): spawn(F, T...)(F fn, T args) with F = void delegate(double, double, long, shared(double[])) pure nothrow @nogc @safe, T = (double, double, long, shared(double[])) must satisfy the following constraint: isSpawnable!(F, T) ``` I think the problem is in `process` attributes (error message you posted is strange, is it the full message?) Make your `process` function a template one to let the compiler to deduce its attributes. Or set them manually.
Re: sort a string
01.05.2020 18:04, notna пишет: hmmm, whích results in: Error: cannot use [] operator on expression of type dchar try this: ```D import std; void main() { string word = "Привет"; dchar[] line3 = to!(dchar[])(word.dup) // make a copy to get a range of mutable char // and convert char to dchar .sort // sort it .release; // get the sorted range assert(line3 == "Пвеирт"); } ```
Re: sort a string
01.05.2020 15:29, Steven Schveighoffer пишет: Don't do this, use to!(dchar[]) as you have above. This will create incorrect dchars for non-ascii text. -Steve Argh, as always you're right. Funny that I never did that and sadly that I posted wrong code. Thank you, Steven, for correction of my wrong posts, I appreciate it.
Re: sort a string
01.05.2020 10:38, Chris Katko пишет: I'm making anagrams. According to the nextPermutation() docs, I need to 'sort by less' to get all permutations. ... Except the doc page doesn't mention how to do that, nor does std.algorithm.sort show how to sort a string. ... and the google results on the dlang forums from 2017 don't work. I've tried .byCodeUnit. , .representation. I've tried sorting on the dchar. I've tried sorting the on string. The closest I've gotten: string word = "bar"; string line2 = toLower!(string)(word); dchar[] line3 = sort(line2.to!(dchar[])); "Error: cannot implicitly convert expression sort(to(line2)) of type SortedRange!(dchar[], "a < b") to dchar[]" import std; void main() { string word = "bar"; dchar[] line3 = word.dup // make a copy to get a range of mutable elements .map!"dchar(a)" // convert char to dchar .array // convert range to random access range (dynamic array here) to enable sorting .sort // sort .array; // convert SortedRange to dynamic array assert(line3 == "abr"); }
Re: Help, what is the code mean?
27.04.2020 18:28, data pulverizer пишет: I'm probably not the first person to say this but. Isn't @trusted an odd label to give unsafe functions and open to abuse by unscrupulous programmers? It almost says "nothing to see, this here piece of code is a-ok". Shouldn't it be explicitly labelled as @unsafe? It says "this piece of code is verified by its author manually so you (the compiler) can trust it is @safe"
Re: Idiomatic way to write a range that tracks how much it consumes
27.04.2020 06:38, Jon Degenhardt пишет: Is there a better way to write this? --Jon I don't know a better way, I think you enlist all possible ways - get a value using either `front` or special range member. I prefer the second variant, I don't think it is less consistent with range paradigms. Considering you need amount of consumed bytes only when range is empty the second way is more effective.
Re: GtkD - how to list 0..100K strings
26.04.2020 11:06, mark пишет: snipped Sorry for offtopic, imho both Qt and Gtk are too complex in case of virtual list/tree view. I think the reason is they are retained mode gui. I gave up to use them for that and develop custom virtual tree view that is easy in use and currently capable to handle over 2M heterogeneous items. But it is in alpha state and for general use needs much more attention.
Re: Integration testing, unit-threaded, and threads
23.04.2020 14:01, Russel Winder пишет: Hi, I need to start a process before the tests run, and terminate it after the tests run. A module with a shared static constructor and shared static destructor sounds like the way of doing this since the constructor is run before main and the destructor after main. However I am using unit-threaded, not for the threads but because it is great for a whole load of other reasons. In fact the threads are becoming a problem. As far as I can tell main is terminating before all the tests are complete which means the shared static destructor is executing before all the tests are complete. I would use Fixture (a class derived form TestCase) here and derive all tests from it. It allows you to start your process before all test in `setup()` Fixture member and terminate it after in `` and probably lets you run the tests simultaneously. To test this hypothesis I want to run single threaded. unit-threaded says this is possible using a command line option -s. The question is which command line? dub test doesn't accept it and neither does the dub command creating ut_main.d Did you try `dub test -- -s`?
Re: Integration testing, unit-threaded, and threads
23.04.2020 14:41, drug пишет: terminate it after in `` terminate it after in `shutdown()`
[dmd] Types and ScopeDsymbol
Is it true that user defined types are resolved to ScopeDsymbol and basic types aren't?
Re: assert expression in release mode
On 3/23/20 2:14 PM, Steven Schveighoffer wrote: E.g. https://dlang.org/dmd-osx.html#switch-release There are also other switches like -boundscheck and -check. It’s possible you have some library or project that is causing the behavior. -Steve Thank you, Steve. In my case I guess it was my mistake because now I returned to the problem to fix it and I can not reproduce that behavior locally.
assert expression in release mode
Before I lived in assurance that asserts are actual only in debug mode and in release mode they are nothing (except `assert(0)`). But today my whole life is going sour because I stumbled upon assert in release mode and of course that assert is failing. This doc https://dlang.org/spec/expression.html#assert_expressions say nothing about debug mode vs release mode. So the question is when and why assert expression is enabled in release mode (besides assert(0))
Re: What is the wrong with my C++ interfacing
On 3/16/20 12:24 PM, Ferhat Kurtulmuş wrote: Ok, here is a solution. I opened my lib (yielded by my auxilary cpp) using 7zip. There are two files containing symbol names, 1.txt and 2.txt. I searched for names of member functions. They were not there because c++ compiler does not compile member functions of class templates because we don't actually use them. So, I simply include this line in my aux cpp file and recompiled it: template class cv::Size_; I reopened 1.txt and they are there now: ?area@?$Size_@H@cv@@QEBAHXZ ?aspectRatio@?$Size_@H@cv@@QEBANXZ now everything works :D Would be nice if you update wiki ;)
Re: What is the wrong with my C++ interfacing
On 3/16/20 10:11 AM, Ferhat Kurtulmuş wrote: On Sunday, 15 March 2020 at 22:25:27 UTC, Arine wrote: On Sunday, 15 March 2020 at 21:27:32 UTC, Ferhat Kurtulmuş extern(C++, cv){ extern(C++, class) struct Size_(_Tp){ @disable this(); ~this() { } final _Tp area() const; final double aspectRatio() const; final bool empty() const; _Tp width; //!< the width _Tp height; //!< the height } } extern(C++){ cv.Size_!int* createSizeIntWH(int w, int h); } void main() { Size_!int* sz = createSizeIntWH(200, 100); writeln(sz.width); } This worked for me too. But member functions are still causing linker error. It seems like docs (https://dlang.org/spec/cpp_interface.html) do not cover those situations. Is there any other sources to read for it. Maybe you make a pull request to docs covering C++ interfacing tips in detail. Not tested: extern(C++, class) struct Size_(_Tp){ @disable this(); ~this() { } extern(C++): // <- IIRC linkage should be set for members separately from aggregate final _Tp area() const; final double aspectRatio() const; final bool empty() const; _Tp width; //!< the width _Tp height; //!< the height }
Re: What is the wrong with my C++ interfacing
15.03.2020 23:53, Ferhat Kurtulmuş пишет: I doubt it because in https://dlang.org/spec/cpp_interface.html#using_cpp_classes_from_d cpp code: Derived *createInstance(int i) d code: extern (C++){ ... Derived createInstance(int i); } Ah, really, you use classes on D side.
Re: What is the wrong with my C++ interfacing
15.03.2020 23:25, Ferhat Kurtulmuş пишет: On Sunday, 15 March 2020 at 20:21:57 UTC, drug wrote: 15.03.2020 22:39, Ferhat Kurtulmuş пишет: What is the D version of `createSizeIntWH`? In C++ it returns a pointer but in D version it returns an instance. extern(C++){ cv.Size_!int createSizeInt(); cv.Size_!int createSizeIntWH(int w, int h); void deleteSizeInt(ref cv.Size_!int sz); } createSizeIntWH returns a pointer to instance, not an instance. Try: cv.Size_!int* createSizeIntWH(int w, int h);
Re: What is the wrong with my C++ interfacing
15.03.2020 22:39, Ferhat Kurtulmuş пишет: The original C++ class https://github.com/opencv/opencv/blob/master/modules/core/include/opencv2/core/types.hpp#L315: template class Size_ { public: typedef _Tp value_type; //! default constructor Size_(); Size_(_Tp _width, _Tp _height); Size_(const Size_& sz); Size_(Size_&& sz) CV_NOEXCEPT; Size_(const Point_<_Tp>& pt); Size_& operator = (const Size_& sz); Size_& operator = (Size_&& sz) CV_NOEXCEPT; //! the area (width*height) _Tp area() const; //! aspect ratio (width/height) double aspectRatio() const; //! true if empty bool empty() const; //! conversion of another data type. template operator Size_<_Tp2>() const; _Tp width; //!< the width _Tp height; //!< the height }; // my auxiliary cpp code: cv::Size_* createSizeIntWH(int _width, int _height){ return new cv::Size_(_width, _height); } void deleteSizeInt(cv::Size_ *){ delete sz; } // d code: extern(C++, cv){ class Size_(_Tp){ @disable this(); final _Tp area() const; final double aspectRatio() const; final bool empty() const; _Tp width; //!< the width _Tp height; //!< the height } } // my test code that fails: Size_!int sz = createSizeIntWH(200, 100); writeln(sz.width); What is the D version of `createSizeIntWH`? In C++ it returns a pointer but in D version it returns an instance. One of the problems is that sz.width is not printed as 200, but a random int. Other problem is that if I try to call one of area, aspectRatio, and empty, it does not compile yielding a linker error: error LNK2019: unresolved external symbol "public: int __cdecl cv::Size_::area(void)const " (?area@?$Size_@H@cv@@QEBAHXZ) referenced in function _Dmain Somehow linker cannot locate that symbol. Is this a name mangling issue? In the same library I could successfully interface cv::Mat which is a template-free definition. I suspect if D allows interfacing C++ class templates since docs do not cover this, but only struct templates?