Re: What happened to Circular Studio?
for those that don't know: https://circularstudios.com/
What happened to Circular Studio?
I just found out a game using D to develop games but later I see the last updates on the github, web site, twitter etc is from 2015. Does anyone knows what happend to the company?
Re: Execute the Shell command and continue executing the algorithm
On Tuesday, 31 May 2022 at 15:29:16 UTC, frame wrote: On Monday, 30 May 2022 at 11:18:42 UTC, Alexander Zhirov wrote: if (here is my condition termination of the program) OT: Wouldn't it be great to have ArnoldC support? ;-) i'm pretty sure the terminattor is more efficient than kill -9 lmaof
Re: UI Library
On Friday, 20 May 2022 at 12:32:37 UTC, ryuukk_ wrote: Avoid GTK, it's bloated, GTK4 looks like a toolkit to design mobile apps, and you need runtime dependencies on windows adam's gui library is very nice, 0 dependencies I personally prefer IMGUI, 0 dependencies, you bring the could you send me please the link for this lib? windowing library of your choice, i pick GLFW since it's minimal IMGUI is fully capable, someone made a Spotify client with it! https://user-images.githubusercontent.com/3907907/81094458-d20d9200-8f03-11ea-81e0-e72c0063b3a7.png
Re: Faster Dlang Execution
On Tuesday, 8 June 2021 at 17:40:19 UTC, Basile B. wrote: On Tuesday, 8 June 2021 at 17:10:47 UTC, seany wrote: Hello How can I increase the speed of executable files created via : `dub build -b release` try `dub build -b release --compiler=ldc2` Then you can set some specific DFlags for ldc, like -O3 or --mcpu also there's the --parallel flag itself supported by ldc2, I have quite a while ago but I'm pretty sure it still is there
Re: how do i fix this node_dlang error?
On Tuesday, 8 June 2021 at 03:04:39 UTC, Mike Parker wrote: On Tuesday, 8 June 2021 at 00:58:12 UTC, Jack wrote: the dll which I was just build with dub command? how I have a version mismatch if they're the very same file? Electron embeds node and does not use whatever you have on your system. So if there’s a mismatch between the embedded version and the one you linked against, you can see the error you’re seeing. I know I took way too much of your time... but could you give just some overalls directions on how to make fix that? can I set that dll which gets embeded in electron? where does it take it initially from? it's embbeded in the binaries? I'm new to electron so I'm figuring out
Re: how do i fix this node_dlang error?
On Tuesday, 8 June 2021 at 04:56:27 UTC, NotSpooky wrote: On Tuesday, 8 June 2021 at 03:04:39 UTC, Mike Parker wrote: On Tuesday, 8 June 2021 at 00:58:12 UTC, Jack wrote: [...] Electron embeds node and does not use whatever you have on your system. So if there’s a mismatch between the embedded version and the one you linked against, you can see the error you’re seeing. I don't use Windows often, my bad for incompatibilities there. I updated Electron, node and DMD. After running console.log (process.versions) in Electron I get: { node: '14.16.0', v8: '9.1.269.28-electron.0', uv: '1.40.0', zlib: '1.2.11', brotli: '1.0.9', ares: '1.16.1', modules: '89', nghttp2: '1.41.0', napi: '7', llhttp: '2.1.3', openssl: '1.1.1', icu: '68.1', unicode: '13.0', electron: '13.1.1', chrome: '91.0.4472.77' } So I changed node.lib in node_dlang with the version from https://nodejs.org/download/release/v14.16.0/win-x64/ However, I get an Error: A dynamic link library (DLL) initialization routine failed. So I'll have to check what's happening now. It might be some API change in Node-API or something spookier. These days I'm quite busy but will do my best to fix this. Could you give me some direction how fix that, as mentioned by Mike Parker? I don't much about the details, I just started it a couple of days ago but as i need it working as soon as possible, I would try fix it myself. Otherwise I'll try use C++ and call my D stuff from there
Re: how to enable safeD ? dmd.conf ? dmd switch ?
On Tuesday, 8 June 2021 at 03:32:31 UTC, someone wrote: On Tuesday, 8 June 2021 at 02:59:28 UTC, rikki cattermole wrote: SafeD is an old name given to the attributes @safe @trusted @system. I have the Alexandrescu's book on hand so that explains it. There is no switch nor any special behavior now that it has long been added to mainline D. So DMD now enforces it by default ? Will it complain if I make something out of the ordinary then ? better read carefully how the attribute work, if you need aditional switches or anything, for example, if you want to use return scope parameter and make the compiler give a compiler error if you set this parameter to a variable outside the function's scope, you have to use -dip25 -dip1000 switches
Re: how do i fix this node_dlang error?
On Tuesday, 8 June 2021 at 00:00:50 UTC, Mike Parker wrote: On Monday, 7 June 2021 at 22:24:03 UTC, Jack wrote: I think the entry point function is ```void atStart(napi_env env) {}``` so there's no DllMain... DLLMain is not strictly required. It's called by the system loader when the DLL is first loaded into the process. The MainFunction for node is just a means for having a cross-platform approach to initialization: node will load your shared library then call the MainFunction. So you can initialize the runtime in DLLMain or in your atStart function. Shouldn't matter. i see Your problem may be unrelated to D, though. It appears to be a common error when developing native code for Electron. Googling for "electron {paste error message here}" or for "electron dll initialization" turns up several results. I'm googling this has been hours, none of the solutions worked for me, including rebuild the native module with electron-rebuild package Some cursory reading shows that the issue may be a version mismatch between the version of node the dll was linked with and that used by Electron. the dll which I was just build with dub command? how I have a version mismatch if they're the very same file?
Re: how do i fix this node_dlang error?
On Monday, 7 June 2021 at 20:37:19 UTC, MoonlightSentinel wrote: On Monday, 7 June 2021 at 19:03:44 UTC, Jack wrote: actually i didnt so I just added: ```d shared static this() { Runtime.initialize(); } shared static ~this() { Runtime.terminate(); } ``` but it didn't change anything That doesn't work because `Runtime.initialize()` is responsible to execute the module ctors. You could try `pragma(crt_constructor)`[1] instead. [1] https://dlang.org/spec/pragma.html#crtctor I see, thanks for pointing out. I think the entry point function is the one set by MainFunction in the exportToJs template so I guess there's no need to this or DllMain. the [example](https://github.com/NotSpooky/node_dlang/blob/master/examples/type_examples/source/example.d) from the node_dlang have no other entry function than the defined by MainFunction template
Re: how do i fix this node_dlang error?
On Monday, 7 June 2021 at 20:13:03 UTC, frame wrote: On Monday, 7 June 2021 at 02:33:38 UTC, Jack wrote: What am I missing? If this runs under Windows, there is no dlopen(), maybe a wrapper to LoadLibrary() but this will need to call a DllMain() in the DLL if I am not wrong. Is there a DllMain? I think the entry point function is ```void atStart(napi_env env) {}``` so there's no DllMain...
Re: how do i fix this node_dlang error?
On Monday, 7 June 2021 at 20:13:03 UTC, frame wrote: On Monday, 7 June 2021 at 02:33:38 UTC, Jack wrote: What am I missing? If this runs under Windows, there is no dlopen(), maybe a wrapper to LoadLibrary() but this will need to call a DllMain() in the DLL if I am not wrong. Is there a DllMain? I just noticied that's supposed to have a DllMain even tho the [code example](https://github.com/NotSpooky/node_dlang/blob/master/examples/type_examples/source/example.d) from node_dlang doesn't have one and it was working(?) I added one in my code but it give same error. I added like this: ```d module foo; import std.stdio : stderr; import node_dlang; import core.sys.windows.windows; import core.sys.windows.dll; mixin SimpleDllMain; extern(C): void atStart(napi_env env) { import std.stdio; writeln (`Loaded D native library!`); } int ultimate() { return 43; } mixin exportToJs! (ultimate, MainFunction!atStart); ```
Re: how do i fix this node_dlang error?
On Monday, 7 June 2021 at 17:22:48 UTC, MoonlightSentinel wrote: On Monday, 7 June 2021 at 02:33:38 UTC, Jack wrote: What am I missing? Does your code / `node_dlang` initialize Druntime before calling `writeln`? actually i didnt so I just added: ```d shared static this() { Runtime.initialize(); } shared static ~this() { Runtime.terminate(); } ``` but it didn't change anything Try replacing the `writeln` with `puts` (from `core.stdc.stdio`) which doesn't require an initialized runtime. I've tried just removed the writeln() call it didn't change anything either
Re: is it possible to have a default property for any given class ?
On Monday, 7 June 2021 at 15:26:27 UTC, someone wrote: Consider the following code: ```d class classComputer { private string pstrName; final @property string name() { return this.pstrName; } final @property void name(in string lstrName) { this.pstrName = lstrName; } this( string lstrComputerName ) { this.pstrName = lstrComputerName; } } class classComputers { classComputers lhs; classComputers rhs; int opApply(int delegate(classComputers) dg) { /// boilerplate code to handle the class's default collection if (lhs && lhs.opApply(dg)) return 1; if (dg(this)) return 1; if (rhs && rhs.opApply(dg)) return 1; return 0; } public classComputer[] computers; /// how can I tag this as the default property ? } void main ( ) { classComputers lobjComputers = new classComputers; lobjComputers.computers ~= new classComputer("dell"); lobjComputers.computers ~= new classComputer("ibm"); lobjComputers.computers ~= new classComputer("apple"); lobjComputers.computers[1].name = r"lenovo"; foreach(lobjComputer; lobjComputers.computers) { writeln(lobjComputer.name); } ///foreach(lobjComputer; lobjComputers) { writeln(lobjComputer.name); } /// with default property (if possible) I think you meant to implement ranges? you can implement in the way you wanted: ```foreach(lobjComputer; lobjComputers)``` but the recommend approach is to get this array through the array index operator. It would go like this: ```d class classComputer { private string pstrName; final string name() { return this.pstrName; } final void name(in string lstrName) { this.pstrName = lstrName; } this(string lstrComputerName = null) { this.pstrName = lstrComputerName; } classComputer lhs; classComputer rhs; int opApply(int delegate(classComputer) dg) { /// boilerplate code to handle the class's default collection if (lhs && lhs.opApply(dg)) return 1; if (dg(this)) return 1; if (rhs && rhs.opApply(dg)) return 1; return 0; } public classComputer[] computers; /// how can I tag this as the default property ? auto opIndex() nothrow { return Range(computers); } protected static struct Range { private classComputer[] a; auto front() { return a[0]; } auto back() { return a[$ - 1]; } void popFront() { a = a[1 .. $]; } bool empty() { return a.length == 0; } size_t opDollar() { return a.length; } auto opSlice(size_t start, size_t end) { return a[start .. end]; } } } void main () { import std.stdio : writeln; auto lobjComputers = new classComputer; lobjComputers.computers ~= new classComputer("dell"); lobjComputers.computers ~= new classComputer("ibm"); lobjComputers.computers ~= new classComputer("apple"); lobjComputers.computers[1].name = r"lenovo"; foreach(lobjComputer; lobjComputers[]) { writeln(lobjComputer.name); } ///foreach(lobjComputer; lobjComputers) { writeln(lobjComputer.name); } /// with default property (if possible) } ``` } ```
Re: how do i fix this node_dlang error?
On Sunday, 6 June 2021 at 21:44:44 UTC, NotSpooky wrote: On Sunday, 6 June 2021 at 04:25:39 UTC, Jack wrote: I'm trying to use the node_dlang pakckage but the code example from [this repo](https://github.com/NotSpooky/node_dlang/tree/v0.4.11/examples) isn't working the command ```dub build``` is fine but ```node example.js``` retuns an error saying the module.node is not a valid win32 application. How do I fix this? [1]: https://github.com/NotSpooky/node_dlang/tree/v0.4.11/examples Hello, I'm the author of the library. nice works, thanks for the library! Indeed I only tested it on 64-bit systems. I can try to make it 32-bit compatible if needed. for me i think it would be needed, i made everything 64bit so it at least compiled and ran. Aside from the auto-translated headers, in the case of Windows the repo also includes node.lib compiled for 64-bit, so unless the 32-bit version is added it will also give errors. I'm pretty sure it does work with electron as I have used it myself. I managed to compile the module and it passed this test: ```javascript const nativeModule = require('./module.node'); const assert = require('assert'); assert(nativeModule.ultimate() == 42); ``` The D code looks like this: ```d import std.stdio : stderr; import node_dlang; extern(C): void atStart(napi_env env) { import std.stdio; writeln ("Hello from D!"); } int ultimate() { return 42; } mixin exportToJs! (ultimate, MainFunction!atStart); ``` its builds sucessfully with ```dub``` no arguments (no --arch=x86_mscoff yet because it requires to fix other compilation error). The dub script looks like this: ```json { "authors": [ "test" ], "copyright": "Copyright © 2021, test", "dependencies": { "node_dlang": "~>0.4.11" }, "description": "using electron from D", "license": "proprietary", "name": "eled", "targetType": "dynamicLibrary", "targetName" : "module.node", "targetPath": "bin" } ``` then i test with node: ``` node test.js ``` it works fine. However, when I attempt to use it in the prescript within electron, I get this error: ``` A JavaScript error occured in the browser process --- Uncaught Exception: Error: A dynamic link library (DLL) initialization routine failed. \\?\C:\Users\001\Desktop\ele\module.node at process.func [as dlopen] (VM70 asar_bundle.js:5) at Object.Module._extensions..node (VM43 loader.js:1138) at Object.func [as .node] (VM70 asar_bundle.js:5) at Module.load (VM43 loader.js:935) at Module._load (VM43 loader.js:776) at Function.f._load (VM70 asar_bundle.js:5) at Function.o._load (VM75 renderer_init.js:33) at Module.require (VM43 loader.js:959) at require (VM50 helpers.js:88) at Object. (VM88 C:\Users\001\Desktop\ele\preload.js:6) ``` the lines of this in the prescript goes like this: ```javascript const nativeModule = require('./module.node'); const assert = require('assert'); assert(nativeModule.ultimate() == 42); ``` What am I missing?
Re: how do i fix this node_dlang error?
On Sunday, 6 June 2021 at 17:32:57 UTC, Mike Parker wrote: On Sunday, 6 June 2021 at 15:42:55 UTC, Jack wrote: 0.4.11\node_dlang\source\node_dlang.d(137,11): Error: none of the overloads of `this` are callable using argument types `(string, string, ulong, Throwable)`, candidates are: [...] The error is from line 137 of node_dlang.d. Looking at it, we see this: ```d super (message, file, line, nextInChain); ``` This is in the constructor of the `JSException` class, a subclass of `Exception`, calling the superclass constructor. According to the error message, one or more of the arguments in this list does not match any `Exception` constructor's parameter list. Looking closer, we can see that the arguments to the super constructor are all declared in the `JSException` constructor like this: ```d this ( napi_value jsException , string message = `JS Exception` , string file = __FILE__ , ulong line = cast (ulong) __LINE__ , Throwable nextInChain = null) ``` Compare that with the constructors in the `Exception` class and you should see that the problem is `ulong line`. The equivalent argument in the superclass is `size_t`. In 32-bit, `size_t` is defined as `uint`, not `ulong`. So it's passing a `ulong` to a `uint`, which is a no-no. The `JSException` constructor should be modified to this: ```d , size_t line = __LINE__ ``` Thanks, I managed to get out this error by making everything 64bit so no type sizes mismatch anymore. The electron itself was still 32bit, which was causing the error to load but it was gone once I reinstalled the 64version. The README does say it hasn't been tested with 32-bit. So there may be more such errors. Unrelated, but I recommend you use `--arch=x86_mscoff` thanks for the tip. in this case, i get the same error above not found the proper overload. But it's to avoid futher potential headaches, I'll edit the node_dlang.d file to make it work. Thanks! so that you can use the same linker and object file format as `-m64` uses (MS link, or lld, and PE/COFF), rather than the default (which is OPTLINK and OMF). It may save you further potential headaches.
Re: how do i fix this node_dlang error?
On Sunday, 6 June 2021 at 06:10:18 UTC, Mike Parker wrote: On Sunday, 6 June 2021 at 04:25:39 UTC, Jack wrote: I'm trying to use the node_dlang pakckage but the code example from [this repo](https://github.com/NotSpooky/node_dlang/tree/v0.4.11/examples) isn't working the command ```dub build``` is fine but ```node example.js``` retuns an error saying the module.node is not a valid win32 application. How do I fix this? [1]: https://github.com/NotSpooky/node_dlang/tree/v0.4.11/examples Looking at node_dlang's dub.json, it's building a DLL then renaming it to module.node. The JS script then causes node to load the DLL. So I expect this error may be related to a 32-bit vs. 64-bit issue. I assume you are on 64-bit Windows, in which case recent versions of dub compile as 64-bit by default. So if that's the case, and your installation of node is 32-bit, you would see this error. Ditto when you're loading a 32-bit DLL in a 64-bit process. the npm was 32bit so the switch to 64bit worked then npm example.js ran file but electron requires a 32bit module, so I need to switch back to npm 32bit. Now, I can't build the example from node_dlang with --arch=x86, returns the error: command: ```$ dub --arch=x86``` output: ``` Performing "debug" build using C:\D\dmd2\windows\bin\dmd.exe for x86, x86_omf. node_dlang 0.4.11: building configuration "node_dlang_windows"... ..\..\AppData\Local\dub\packages\node_dlang-0.4.11\node_dlang\source\node_dlang.d(137,11): Error: none of the overloads of `this` are callable using argument types `(string, string, ulong, Throwable)`, candidates are: C:\D\dmd2\windows\bin\..\..\src\druntime\import\object.d(2440,30): `object.Exception.this(string msg, string file = __FILE__, uint line = cast(uint)__LINE__, Throwable nextInChain = null)` C:\D\dmd2\windows\bin\..\..\src\druntime\import\object.d(2445,30): `object.Exception.this(string msg, Throwable nextInChain, string file = __FILE__, uint line = cast(uint)__LINE__)` C:\D\dmd2\windows\bin\dmd.exe failed with exit code 1. ```
Re: how do i fix this node_dlang error?
On Sunday, 6 June 2021 at 06:10:18 UTC, Mike Parker wrote: On Sunday, 6 June 2021 at 04:25:39 UTC, Jack wrote: I'm trying to use the node_dlang pakckage but the code example from [this repo](https://github.com/NotSpooky/node_dlang/tree/v0.4.11/examples) isn't working the command ```dub build``` is fine but ```node example.js``` retuns an error saying the module.node is not a valid win32 application. How do I fix this? [1]: https://github.com/NotSpooky/node_dlang/tree/v0.4.11/examples Looking at node_dlang's dub.json, it's building a DLL then renaming it to module.node. The JS script then causes node to load the DLL. So I expect this error may be related to a 32-bit vs. 64-bit issue. I assume you are on 64-bit Windows, in which case recent versions of dub compile as 64-bit by default. So if that's the case, and your installation of node is 32-bit, you would see this error. Ditto when you're loading a 32-bit DLL in a 64-bit process. that's right, I was on 64bit system and node was 32bit installation (I didn't even realize I installed the 32bit instead of 64bit). I just installed node 64bit version, that fixed, thanks!
how do i fix this node_dlang error?
I'm trying to use the node_dlang pakckage but the code example from [this repo](https://github.com/NotSpooky/node_dlang/tree/v0.4.11/examples) isn't working the command ```dub build``` is fine but ```node example.js``` retuns an error saying the module.node is not a valid win32 application. How do I fix this? [1]: https://github.com/NotSpooky/node_dlang/tree/v0.4.11/examples
Re: Working with ranges
On Wednesday, 26 May 2021 at 13:58:56 UTC, Elmar wrote: On Saturday, 8 December 2018 at 03:51:02 UTC, Adam D. Ruppe wrote: [...] That's amazing, this should be one thing that should appear in every tutorial just right at the start! I was looking hours for a way to generate an "iterator" (a range) from a fixed-size array which doesn't copy the elements (unless elements are deleted/added). [...] maybe array from std.array to make that range in array of its own?
Re: Template and alloca?
On Wednesday, 26 May 2021 at 11:31:31 UTC, Ola Fosheim Grostad wrote: On Wednesday, 26 May 2021 at 08:38:29 UTC, Imperatorn wrote: On Wednesday, 26 May 2021 at 07:34:06 UTC, Ola Fosheim Grøstad wrote: On Tuesday, 25 May 2021 at 17:55:17 UTC, Ola Fosheim Grostad wrote: Is it possible to use a template to write a "function" that provides initialized stack allocated memory (alloca)? Maybe I would have to use mixin? Nevermind, I've realized that I only need a way to force a function to be inlined with 100% certainty. Then I can return a structure holding alloca-allocated memory. Do you accomplish that with just pragma inline? (for future reference) I suspect that LDC allows LLVM to use an external function, but I dont know for sure. I would have to look over the code it sends to LLVM... But the beauty of Open Source is that it is easy to modify LDC! Anyway, dont do this with C compilers, as they might refuse to inline functions with alloca to prevent the stack from exploding... Very much a low level approach, but fun! for anyone that would ever use this approach with DMD remember to *always* use -inline flag otherwise the inline request by ```pragma(inline, true)``` can be ignored and this will result in a nasty bug
Re: DMC + Win32Api: Error: undefined identifier 'SetDCBrushColor'
On Sunday, 16 May 2021 at 14:51:56 UTC, Marcone wrote: Well, I program in D as a hobby for just over a year, and I like to learn and explore this wonderful programming language. Now I found the DMC compiler that compiles C ++ code. So I decided to test it. Creating a program with a win32api graphical interface I run into this error: Error: undefined identifier 'SetDCBrushColor' How to solve this problem? Thanks. if it's not one defined in one of the core.sys.windows module, export it yourself: ```d pragma(lib, "Gdi32.lib"); COLORREF SetDCBrushColor( HDC hdc, COLORREF color ); ```
Re: how do I implement opSlice for retro range?
On Friday, 14 May 2021 at 14:14:03 UTC, Steven Schveighoffer wrote: On 5/13/21 11:49 PM, Jack wrote: [...] Just slice the `a`, appropriately. You have to translate the indexes back into the original array. ```d auto opSlice(size_t start, size_t end) { return typeof(this)(a[$ - end .. $ - start]); } ``` You should also define `length`, `save`, `opIndex`, and `opDollar` so that it fits in the range hierarchy as a proper random-access range. But I question whether you shouldn't just use `std.range.retro` directly? It does all this for you: ```d // inside A auto retro() { import std.range : retro; return arr.retro; } ``` -Steve much easier, I'll be just using the one from std.range. Thanks!
Re: how do I implement opSlice for retro range?
On Friday, 14 May 2021 at 10:00:44 UTC, Christian Köstlin wrote: On 2021-05-14 05:49, Jack wrote: [...] arr.retro()[0..2] already works. see https://run.dlang.io/is/U8u3br oh, how i silly of i didn't notice that before
Re: how do I implement opSlice for retro range?
sorry, in this code i mean b must be [5, 4] ```d auto arr = [1, 2, 3, 4, 5]; auto a = new A!int(arr); auto b = a.retro[0 .. 2]; //5,4 ```
how do I implement opSlice for retro range?
How can I implement ranges in the retro range? I'd like to do this without allocate a new array with .array from std.array, can I do that? use like this: ```d auto arr = [1, 2, 3, 4, 5]; auto a = new A!int(arr); auto b = a.retro[0 .. 2]; // 4, 5 ``` the class: ```d class A(T) { private T[] arr; this(T[] a) { arr = a; } auto opIndex() nothrow { return Range(arr); } auto retro() { return RangeRetro(arr); } protected static struct Range { T[] a; T front() { return a[0]; } T back() { return a[$ - 1]; } void popFront() { a = a[1 .. $]; } bool empty() { return a.length == 0; } } protected static struct RangeRetro { import std.range : popFront; import std.range : popBack; T[] a; T front() { return a[$ - 1]; } T back() { return a[0]; } void popBack() { a.popFront(); } void popFront() { a.popBack(); } bool empty() { return a.length == 0; } auto opSlice(size_t start, size_t end) { ??? } } } ```
cannot I override and mark it as private?
I'd to change the visibility of a method overrided from public to private but it doesn't work tho to protected it does. Why is that? give: ```d class A { void f() { } } ``` this is ok: ```d class B : A { protected override void f() { } } ``` this is not: ```d class B : A { private override void f() { } } ``` Why is that? why must I leave it accessible somehow (even if it's protected) to all derived class of my derived class?
Re: can I reuse statements?
On Monday, 10 May 2021 at 21:10:13 UTC, Paul Backus wrote: On Monday, 10 May 2021 at 21:01:53 UTC, Jack wrote: [...] You can do it with a string mixin: ```d // Note: q{ ... } creates a "token string", a special kind of string literal // that's used for code strings. // See https://dlang.org/spec/lex.html#token_strings enum string handleXY = q{ auto c = arr[i]; // arr and i are available at switch(code)'s scope auto m = Message(...); switch(code) { case BAA_A: c.doSomething(m); break; case BAA_B: c.doSomething(m); break; default: assert(0, "error"); } }; ``` Usage: ```d case X, Y: mixin(handleXY); ``` sounds good, thanks!
can I reuse statements?
mixin template seems to allow only declarations so if I put a if or case-statement in the body it doesn't work. I'd like to make something like this work: ```d switch(code) { case X, Y: // that specific case repeats alot in the code in different procedures mixin handleXY; default: } ``` then ```d mixin template foo() { auto c = arr[i]; // arr and i are available at switch(code)'s scope auto m = Message(...); switch(code) { case BAA_A: c.doSomething(m); break; case BAA_B: c.doSomething(m); break; default: assert(0, "error"); } } ```
Without multiples inheritance, how is this done?
let's say I have: ```d class Base { int f() { doSomething(); return n * 5; } void doSomething() { } } class Foo : Base { void myMethod() { /* ... */ } } class Baa : Base { void myMethod2() { /* ... */ } } ``` then I'd like to make a extended version(making those DRY routines a class itself) of Foo and Baa, like this: ```d abstract class DRY : Base { this(int n) { this.n = n; } override int f() { super.doSomething(); return n; } private int n; } ``` but the class ExtendFoo and ExtendedBaa must inherit from Foo and Baa, respectively. But how can I make it inherit the routines from DRY class too without multiples inheritance? in C++ I'd just do: ```d class ExtendedFoo : DRY, Base { /* ... */ } class ExtendBaa : DRY, Base { /* ... */ } ```
Re: What does @nogc do to a class?
On Thursday, 6 May 2021 at 22:16:04 UTC, Per Nordlöw wrote: On Thursday, 6 May 2021 at 01:04:02 UTC, Jack wrote: Does it allocate the object rather on stack, like auto scope a = new A or what? Further note that auto scope a = new A; can be written shorter as scope a = new A; I'll be using that, thanks!
Re: What does @nogc do to a class?
On Thursday, 6 May 2021 at 02:11:27 UTC, Mike Parker wrote: On Thursday, 6 May 2021 at 01:04:02 UTC, Jack wrote: Does it allocate the object rather on stack, like auto scope a = new A or what? It doesn't do anything to classes. `@nogc` prevents you from any action triggers a GC allocation, such as using `new, so you would need to allocate from somewhere else (e.g., via `malloc`) for any class instances you want to create in a `@nogc` function. I see, thanks!
What does @nogc do to a class?
Does it allocate the object rather on stack, like auto scope a = new A or what?
What's a good approach to DRY with the block code of a case-statement?
I have a block of code that the only thing that change is the type passed in one of the template functions called so I'd like to make a DRY for this. But I'm not just replacing by a function due to control-flow, for example, there are if-statements where one just break and the other return 0. I think I could do something with mixin() that would kinda mimic C's macro but I still find it messy. Any alternatives? ```d static int doSomething() { switch(val) { case VAL_FOO: auto obj = getObject!MyType(someData); // this is the type // that changes if(obj.shouldExit()) break; auto m = Message(...); if(obj.doSomethingElse(m)) return 0; break; // ... default: } return doSomethingY(); } ``` Maybe my least resort, if I went to replace by a function, I could do something like this: ```d enum OP { BREAK, RETURN } pragma(inline, true): OP foo(T)() { auto obj = getObject!T(someData); // this is the type // that changes if(obj.shouldExit()) return OP.BREAK; auto m = Message(...); if(obj.doSomethingElse(m)) return OP.RETURN; return OP.BREAK; } ``` then: ```d static int doSomething() { switch(val) { case VAL_FOO: auto r = foo!MyType(); if(r == OP.BREAK) break; if(r == OP.RETURN0) return 0; break; // ... default: } return doSomethingY(); } ``` I still find this not much elegant. If anyone knows a better way to do this, help are very welcome
Re: write once type?
On Tuesday, 20 April 2021 at 19:56:33 UTC, Steven Schveighoffer wrote: I have had the need in some cases to *maybe* set a const value inside a loop. One can sometimes abstract this into a lambda function, but sometimes this is not possible (e.g. if the loop is static). Not only that, but I may also want to keep processing the loop and do something different if the value has already been set instead of returning immediately, which necessitates a second loop. [...] This is a feature that I wanted always since my C# and C++ time. I've tried to mimic it with class/struct (including readonly with C++) but it isn't same thing.
Re: get type name from current class at compile time?
On Sunday, 25 April 2021 at 08:36:51 UTC, Adam D. Ruppe wrote: On Sunday, 25 April 2021 at 03:45:13 UTC, Jack wrote: that's better, thanks Imporant to remember that any compile time thing will be the static type. If someone does: Base a = new Derived(); a.something(); it will still show up as Base in the this template. I find out this later. I give up trying to get this in automatic way at compile time
Re: get type name from current class at compile time?
On Sunday, 25 April 2021 at 02:45:38 UTC, Paul Backus wrote: On Sunday, 25 April 2021 at 02:26:00 UTC, Jack wrote: doesn't this work when called from member in a derived class? ```d class A { void doSomething(this T)() { writefln("name = [%s]", __traits(identifier, T)); } } class K : A { void baa() { doSomething(); } } ``` result in the error: Error: template `foo.A.doSomething` cannot deduce function from argument types `!()()`, It works if you call it with `this.doSomething()`: https://run.dlang.io/is/eIygNG that's better, thanks
Re: get type name from current class at compile time?
On Sunday, 25 April 2021 at 02:26:00 UTC, Jack wrote: On Sunday, 25 April 2021 at 02:02:47 UTC, Ali Çehreli wrote: On 4/24/21 6:50 PM, Jack wrote: I'd like to output `K` and get this identifier at compile time. This is solved by the "this template parameter": import std.stdio; class A { void showMyName(this T)() { writefln("name = [%s]", __traits(identifier, T)); } } class K : A { } void main() { new K().showMyName(); } Ali doesn't this work when called from member in a derived class? ```d class A { void doSomething(this T)() { writefln("name = [%s]", __traits(identifier, T)); } } class K : A { void baa() { doSomething(); } } ``` result in the error: Error: template `foo.A.doSomething` cannot deduce function from argument types `!()()`, I can call doSomething!(typeof(this)), I can live with that
Re: get type name from current class at compile time?
On Sunday, 25 April 2021 at 02:02:47 UTC, Ali Çehreli wrote: On 4/24/21 6:50 PM, Jack wrote: I'd like to output `K` and get this identifier at compile time. This is solved by the "this template parameter": import std.stdio; class A { void showMyName(this T)() { writefln("name = [%s]", __traits(identifier, T)); } } class K : A { } void main() { new K().showMyName(); } Ali doesn't this work when called from member in a derived class? ```d class A { void doSomething(this T)() { writefln("name = [%s]", __traits(identifier, T)); } } class K : A { void baa() { doSomething(); } } ``` result in the error: Error: template `foo.A.doSomething` cannot deduce function from argument types `!()()`,
Re: get type name from current class at compile time?
On Sunday, 25 April 2021 at 02:02:47 UTC, Ali Çehreli wrote: On 4/24/21 6:50 PM, Jack wrote: I'd like to output `K` and get this identifier at compile time. This is solved by the "this template parameter": import std.stdio; class A { void showMyName(this T)() { writefln("name = [%s]", __traits(identifier, T)); } } class K : A { } void main() { new K().showMyName(); } Ali good one Ali, thanks. Where is this template parameter documented at?
Re: Can I rely on format returned by fullyQualifiedName?
On Saturday, 24 April 2021 at 04:09:15 UTC, Mike Parker wrote: On Saturday, 24 April 2021 at 03:40:20 UTC, Jack wrote: Can I rely on this format from fullyQualifiedName? for example, let's say I do: ```d enum s = fullyQualifiedName!f.split; ``` where f is a function member of a class. Can I realy that s[0] is the module name, s[1] is the class name and s[2] the functio name? is this standard or can the compile change that? I've tested on dmd, does ldc or gdc do something different? You can rely on the order, but you cannot expect any of the names to be at a specific index. The FQN includes the symbol's entire hierarchy. So you could have one or more package names in front of the module name. Essentially: {all.package.names.}moduleName.{struct/class/functionName}.symbolName thank you Mike, having sure I can rely on the other is enough to me
get type name from current class at compile time?
```d class A { void showMyName() { writefln("name = [%s]", __traits(identifier, typeof(this))); } } class K : A { } ``` then ```d new K().showMyName(); ``` output: name = [A] I'd like to output `K` and get this identifier at compile time. But I'd to do so automatically so rule out something like: ```d class A { string name = __traits(identifier, typeof(this)); void showMyName() { writefln("name = [%s]", name); } } class K : A { this() { super.name = __traits(identifier, typeof(this)); } } ```
Can I rely on format returned by fullyQualifiedName?
Can I rely on this format from fullyQualifiedName? for example, let's say I do: ```d enum s = fullyQualifiedName!f.split; ``` where f is a function member of a class. Can I realy that s[0] is the module name, s[1] is the class name and s[2] the functio name? is this standard or can the compile change that? I've tested on dmd, does ldc or gdc do something different? ```d class A { void f() { } void baa() { enum s = fullyQualifiedName!f.split; } } ```
How to implement a range?
In order to my array class work with filter, I went to implement an ``InputRange``. But I don't quite get how do that and didn't find much help on the docs. From below code, is ``moveFront()`` implemented correctly? I'm using a simple int i as index of current item and in popFront() just increment it. I must reset the i value once the loop is done, right? where am I supposed to do that? opApply()? not properly reseting it result in obvious bugs like subsequent calls doesn't work because the index is in the end of the array: ```d auto arr = new MyArray!int; arr.Add(1); arr.Add(2); arr.Add(3); arr.Add(4); auto r = arr.filter!(n => (n % 2) == 0); auto r2 = arr.filter!(n => n >= 2); writeln(r); // ok writeln(r2); // empty ``` yeah, i'm a bit confused... here's the code: ```d class MyArray(T) : InputRange!T { private T[] arr; private int i = 0; void Add(T item) { arr ~= item; } void Add(T[] items) { foreach(item; items) { Add(item); } } size_t length() nothrow { return arr.length; } bool empty() { return i == length; } T front() { return arr[i]; } void popFront() { i++; } T moveFront() { auto r = front; popFront(); return r; } int opApply(scope int delegate(ref T) dg) { int result = 0; foreach (item; arr) { result = dg(item); if (result) { break; } } return result; } int opApply(scope int delegate(T) dg) { int result = 0; foreach (item; arr) { result = dg(item); if (result) { break; } } return result; } int opApply(scope int delegate(uint, T) dg) { int result = 0; foreach (j, item; arr) { result = dg(j, item); if (result) { break; } } return result; } } ```
Re: How do I create classes dynamically?
On Thursday, 15 April 2021 at 17:48:02 UTC, Imperatorn wrote: On Thursday, 15 April 2021 at 16:39:30 UTC, Kagamin wrote: On Wednesday, 14 April 2021 at 20:38:16 UTC, Mario wrote: [...] String mixins is D replacement of macros for code generation. Works like this: ```d mixin("class MyDynamicClassName { }"); MyDynamicClassName cls = new MyDynamicClassName; ``` Yes but not at runtime Could you give an example of what you're trying to archive?
Re: "this" as default parameter for a constructor.
On Sunday, 11 April 2021 at 20:38:10 UTC, Pierre wrote: Hi, I have a class with a reference to the parent object and a constructor that has the parent as parameter class foo { this ( foo p /* , other params */ ) { parent = p; } foo parent; } Of cause, the parent is almost always the object that creates the new intance. So auto f = new foo(this); I'd like to set "this" ( the creator ) as default argument if the constructor : this ( foo p = this ) {...} I can't. But however, the function, the argument and the current object in body of the constructor are 3 different things and the compiler can distinguish each one. Is there a way to pass the reference of the caller to the creator as default argument ? it isn't supported as far i know so use a default construtor like @Kagamin has show
How to allow +=, -=, etc operators and keep encapsulation?
Give this class: ```d class A { int X() { return x; } int X(int v) { return x = v;} private int x; } ``` I'd like to allow use ```+=```, ```-=``` operators on ```X()``` and keep encapsulation. What's a somehow elegant way to do that?
Re: Is there a more elegant way to do this in D?
On Thursday, 8 April 2021 at 16:45:14 UTC, Jack wrote: On Thursday, 8 April 2021 at 04:02:26 UTC, Ali Çehreli wrote: On 4/7/21 8:57 PM, Brad wrote: auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0]; I want to come out of this with a string that looks like this: 101110100 Me, me, me, me! :) import std; void main() { auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0]; string s = format!"%-(%s%)"(a); writeln(s); } Ali What does %-%s% do? nevermind, someone just asked this too[1] [1]: https://forum.dlang.org/thread/immypqwvbealjqrvb...@forum.dlang.org
Re: Is there a more elegant way to do this in D?
On Thursday, 8 April 2021 at 04:02:26 UTC, Ali Çehreli wrote: On 4/7/21 8:57 PM, Brad wrote: auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0]; I want to come out of this with a string that looks like this: 101110100 Me, me, me, me! :) import std; void main() { auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0]; string s = format!"%-(%s%)"(a); writeln(s); } Ali What does %-%s% do?
Re: How to update terminal output?
On Sunday, 28 March 2021 at 16:45:29 UTC, dog2002 wrote: I mean, I want to write a string without a new line. For example, some command line applications have progress bars. For a single line string I use \r. But it doesn't work for a multiple line string - the application is just adding new lines. you have to erase the line when you're about to display a new progress percent. On UNIX system, you have to use character terminal escapes[1] on window you have to dig the console API[2] or you can just use ncurse library[3][4] [1]: https://web.archive.org/web/20200415203148/http://ascii-table.com/ansi-escape-sequences-vt-100.php [2]: https://docs.microsoft.com/en-us/windows/console/console-reference [3]: https://invisible-island.net/ncurses/announce.html [4]: https://code.dlang.org/search?q=ncurses
Re: How can I allocate a int[] array on stack?
On Friday, 26 March 2021 at 06:45:39 UTC, Daniel Kozak wrote: On Fri, Mar 26, 2021 at 7:36 AM Daniel Kozak wrote: On Fri, Mar 26, 2021 at 7:31 AM Daniel Kozak wrote: On Fri, Mar 26, 2021 at 6:50 AM Jack via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: What's the equivalent of C's VLA in D? scoped from std.typecons doesn't seem to work with arrays. Should I use alloca() for my array or is there something else? https://dlang.org/library/std/array/static_array.html Sorry I was misread this You can use allocator: import std.experimental.allocator.showcase; import std.experimental.allocator; import std.stdio; StackFront!4096 stackAlloc; void main() { int[] a = stackAlloc.makeArray!int(2); writeln(a); } I thought this was going to use alloca() but it seems to be using malloc() internally?
How can I allocate a int[] array on stack?
What's the equivalent of C's VLA in D? scoped from std.typecons doesn't seem to work with arrays. Should I use alloca() for my array or is there something else?
Re: Using onOutOfMemoryError in C wrappers
On Wednesday, 24 March 2021 at 08:31:19 UTC, Basile B. wrote: On Wednesday, 24 March 2021 at 07:58:22 UTC, Per Nordlöw wrote: When wrapping C code that tries to allocate memory resources via functions such as X* X_create(); should one call `onOutOfMemoryError();` upon null return? Making more D wrappers `nothrow @nogc`. There are several ways to do that. In addition to onOutOfMemoryError, you can use a static instance or `if (somePtr is null) assert(0);` void v() @nogc nothrow { __gshared oom = new OutOfMemoryError(); auto X* = X_create(); if (X is null) throw oom; } why are you creating oom variable before the if(x is null) check?
Re: How do I check if this field is of this template struct?
On Saturday, 20 March 2021 at 00:16:06 UTC, Steven Schveighoffer wrote: On 3/19/21 12:41 PM, Jack wrote: On Friday, 19 March 2021 at 08:54:50 UTC, Paul Backus wrote: On Friday, 19 March 2021 at 07:14:46 UTC, Jack wrote: give below template struct, how can I list the members x, y and z? I've tried something with OriginalType and TemplateOf but no luck... it seems if I do foo!"str1" the "str1" became "part of type"? give .stringof from typeof(__traits(getMember, foo, field)) I thought the type would be foo!string or something. You want std.traits.isInstanceOf: static if(!isType!m && isInstanceOf!(foo, typeof(m))) thanks this works fine outside a method but not in a static method. what am I missing? void main() { // doesn't print anything Foo.list(); } alias Foo = foo!(); template foo(string s = null) { @nogc struct foo { int n; enum x = foo!"str1"(10); enum y = foo!"str2"(20); enum z = foo!"str3"(30); enum myEnum { none } void someMethod() { } static void list() { //writeln("members = ", [__traits(allMembers, foo!())]); static foreach(field; __traits(allMembers, foo!())) {{ alias m = __traits(getMember, foo!(), field); static if(!isType!m && isInstanceOf!(foo, typeof(m))) foo in this context is the *instantiated* foo (i.e. the struct foo above). What you want is `isIsntanceOf!(.foo, typeof(m))` -Steve Thank you Steve, that what I was looking for. Funny thing, I totally forget about the . operator
Re: How do I check if this field is of this template struct?
On Friday, 19 March 2021 at 17:40:39 UTC, frame wrote: On Friday, 19 March 2021 at 16:41:11 UTC, Jack wrote: thanks this works fine outside a method but not in a static method. what am I missing? Reading the manual ;) To use isInstanceOf to check the identity of a template while inside of said template, use TemplateOf. indeed, it shwos an example on how to use that in a static function
Can I make this work?
there's a value passed as template parameter which is know at compile time (can be used with static if) but I don't know how can I pass it around and use in a property. Obviously enum deosn't work because it would be a local to the function. immutable would result in compiler can't read it at compile time. version doesn't work either because it isn't at module scope but a function. full code: struct S { enum x = init!(false, 10); enum y = init!(true, 20); this(string s) { type = Type.type1; } this(int n) { type = Type.type2; } static auto init(bool v, int val)() { auto s = S(); static if(v) { s.type = Type.type1; } else { s.type = Type.type2; } s.n = val; return s; } int value() { // would to use static if here or just // get rid of that check if type is Type.type1, // information which is available at init() // template function. if(type == Type.type2) { // do something } return n; } Type type; int n; } enum Type { type1, type2, type3 }
Re: How do I check if this field is of this template struct?
On Friday, 19 March 2021 at 08:54:50 UTC, Paul Backus wrote: On Friday, 19 March 2021 at 07:14:46 UTC, Jack wrote: give below template struct, how can I list the members x, y and z? I've tried something with OriginalType and TemplateOf but no luck... it seems if I do foo!"str1" the "str1" became "part of type"? give .stringof from typeof(__traits(getMember, foo, field)) I thought the type would be foo!string or something. You want std.traits.isInstanceOf: static if(!isType!m && isInstanceOf!(foo, typeof(m))) thanks this works fine outside a method but not in a static method. what am I missing? void main() { // doesn't print anything Foo.list(); } alias Foo = foo!(); template foo(string s = null) { @nogc struct foo { int n; enum x = foo!"str1"(10); enum y = foo!"str2"(20); enum z = foo!"str3"(30); enum myEnum { none } void someMethod() { } static void list() { //writeln("members = ", [__traits(allMembers, foo!())]); static foreach(field; __traits(allMembers, foo!())) {{ alias m = __traits(getMember, foo!(), field); static if(!isType!m && isInstanceOf!(foo, typeof(m))) { writefln("field = [%s]", field); } }} } } }
Re: How do I check if this field is of this template struct?
On Friday, 19 March 2021 at 07:56:26 UTC, Panke wrote: On Friday, 19 March 2021 at 07:14:46 UTC, Jack wrote: give below template struct, how can I list the members x, y and z? I've tried something with OriginalType and TemplateOf but no luck... it seems if I do foo!"str1" the "str1" became "part of type"? give .stringof from typeof(__traits(getMember, foo, field)) I thought the type would be foo!string or something. Template parameter cannot only be types but also values, including strings. If you instantiate a template with different values you get different types. that design is a bit different but may be worth, gonna get used to it -- struct foo(T) { } struct bar(string s) {} alias a = foo!string; // type of a is foo!string alias b = bar!"str1"; // type of b is bar!"str1" alias c = bar!"str2"; // typo of c is bar!"str2" static assert (!is(typeof(c) == typeof(b))); --
How do I check if this field is of this template struct?
give below template struct, how can I list the members x, y and z? I've tried something with OriginalType and TemplateOf but no luck... it seems if I do foo!"str1" the "str1" became "part of type"? give .stringof from typeof(__traits(getMember, foo, field)) I thought the type would be foo!string or something. Here's the code: template foo(string s = null) { @nogc struct foo { int n; enum x = foo!"str1"(10); enum y = foo!"str2"(20); enum z = foo!"str3"(30); enum myEnum { none } void someMethod() { } } } not working listener: void list() { static foreach(field; __traits(allMembers, foo!())) {{ alias m = __traits(getMember, foo!(), field); static if(!isType!m && __traits(isSame, OriginalType!(typeof(m)), foo)) { writefln("field = [%s]", field); } }} }
question about ref keyword
let's assume this class: class C { private S m_s; this() { m_s = S(30); } ref S value() { return m_s; } ref S value(ref S s) { return m_s = s; } } and I do something like this: auto s1 = S(40); auto c = new C(); c.value = s1; s1.n = 80; give that value has ref in its signature, the s1 is passed as a "pointer" right? also, when I do: m_s = s; m_s is a copy of s1 or a reference to it? setting s1.n to 80 in the next line doesn't seem to change c.value so it seems it passed s1 as a pointer but when it comes to assignment a copy was made?
Re: How to change button text color in NM_CUSTOMDRAW (Win32 API question)
On Tuesday, 16 March 2021 at 17:26:01 UTC, Vinod K Chandran wrote: Hi all, I am creating a Button class with Win32 API functions. So far so good. I am using NM_CUSTOMDRAW message to change the back color of my buttons. It's really easy to change the back color in this way. But I can't change the text color of my button. This is my pseudo code. ``` uint setBtnBackColor( LPNMCUSTOMDRAW lp) { SetTextColor(lp.hdc, RGB(102, 255, 51) )// Not working if lp.uItemState & CDIS_SELECTED { //--- btn clicked // Change back color using SelectObject & FillRect // Its Working. No probs. } elseif lp.uItemState & CDIS_HOT { //Mouse over // Change back color using SelectObject & FillRect // Its Working. No probs. } else { // -Default state of button // Change back color using SelectObject & FillRect // Its Working. No probs. } return CDRF_SKIPDEFAULT } ``` What is wrong in my approach ? I'm afraid you have to do everything yourself, including draw the text and call SetTextColor() on the associated HDC (that you have used in the DrawText() for exe)
Re: Make foreach element optional
On Tuesday, 16 March 2021 at 15:02:54 UTC, Steven Schveighoffer wrote: On 3/16/21 8:49 AM, Per Nordlöw wrote: I find myself writing foreach (_; 0 .. n) doSomething(); // no using the variable `_` . What about relaxing the syntax to allow foreach (; 0 .. n) and/or foreach (0 .. n) ? Thereby making the `ForeachTypeList` of `AggregateForeach` in the grammar rule [1] optional. [1] https://dlang.org/spec/statement.html#foreach-statement Meh, is this a common need though? The first form isn't terrible. In general, I'd say it would be nice to designate _ as an unused variable (i.e. not allowed to access it, and it doesn't trigger shadowing errors). It's like this in Swift for instance. -Steve the _ as unused variable would be useful when the parameter has out parameter but wouldn't to ignore it. C# does something like this currently. int foo(int x, out bool state) { } // only wants return value int y = foo(x, _);
Re: How can I make this work?
On Tuesday, 16 March 2021 at 16:02:14 UTC, Vinod K Chandran wrote: On Sunday, 28 February 2021 at 13:15:47 UTC, Adam D. Ruppe wrote: And it is the simplest thing, no missing length, no weird property casting. The GC handled with two simple add/remove calls. Perfect example of teaching something. Thank you for this knowledge. Even though, this was not my problem, Its really helpful for me to my future project. :) elegant approach
Re: How can I make this work?
On Sunday, 28 February 2021 at 13:15:47 UTC, Adam D. Ruppe wrote: On Sunday, 28 February 2021 at 07:05:27 UTC, Jack wrote: I'm using a windows callback function where the user-defined value is passed thought a LPARAM argument type. I'd like to pass my D array then access it from that callback function. How is the casting from LPARAM to my type array done in that case? The best way to do this is to put the array inside a struct and pass the address of the struct instead. This way both length and pointer are passed, and you have the option to add more things if you ended up needing it later, and there's fewer weird things to worry about. int[] arr = [1, 2, 3]; struct MyMessage { int[] arr; } // this far is easy enough MyMessage* messagePointer = new MyMessage(arr); // but we do need to tell the GC we intend to pass this to the outside world // failure to do this MIGHT lead to random crashes as the GC can't see it (it can't look inside the Windows message queue), assumes it is unused, and frees it out from under you. import core.memory; GC.addRoot(messagePointer); // when the GC has a root, it will consider that pointer live until further notice and not collect it nor its member variables. // so it is now cool to do this PostMessage(hwnd, MSG_WHATEVER, 0, cast(LPARAM) messagePointer); /* then on the other side */ switch(iMsg) { case MSG_WHATEVER: MyMessage* messagePointer = cast(MyMessage*) lParam; // need to tell the GC the pointer can be automatically managed normally again. failure to do this will lead to a memory leak import core.memory; GC.removeRoot(messagePointer); // now can use it foreach(item; messagePointer.arr) { // yada yada yada } } And it is the simplest thing, no missing length, no weird property casting. The GC handled with two simple add/remove calls. This is what I ended up using. using a single pointer such as MyMessage makes things much simpler. Thanks for the rememinder of GC.removeRoot() Everyone else in this theread, thank you guys. Always helpful
Re: Can't I allocate at descontructor?
On Friday, 5 March 2021 at 21:24:08 UTC, tsbockman wrote: On Friday, 5 March 2021 at 21:17:24 UTC, tsbockman wrote: On Friday, 5 March 2021 at 21:02:08 UTC, H. S. Teoh wrote: class C {...} import core.memory : GC; C c = cast(C) GC.malloc(C.sizeof); ... ... import core.memory : GC; C c = cast(C) GC.malloc(C.sizeof); ... Also, that's not the correct way to manually allocate a class on the heap. C.sizeof is the size of a reference to C, not an instance of C, and we need to blit and construct the instance before it is safe to use: import core.memory : GC; C c = cast(C) GC.malloc(__traits(classInstanceSize, C)); import core.lifetime : emplace; emplace(c, anyConstructorArgsGoHere); ... good catch, thanks
Re: Can't I allocate at descontructor?
On Friday, 5 March 2021 at 21:25:52 UTC, Ali Çehreli wrote: On 3/5/21 12:57 PM, Jack wrote: >> destroy() executes the destructor. > > but I would need to call it manually and only after I somewhat I've > determined I no longer need the resources, right? so destroy(c) would be > no different from calling my own finalize-like method like freeResources()? Yes but perhaps with some extra functionality like the optional 'initialize': https://dlang.org/phobos/object.html#.destroy Ali Now about the behavior of a static destructor, like static ~this() { } is this guaranteed to be run?
Re: Can't I allocate at descontructor?
On Friday, 5 March 2021 at 21:02:08 UTC, H. S. Teoh wrote: On Fri, Mar 05, 2021 at 08:24:26PM +, Jack via Digitalmars-d-learn wrote: On Friday, 5 March 2021 at 20:18:44 UTC, Max Haughton wrote: > On Friday, 5 March 2021 at 20:13:54 UTC, Jack wrote: [...] > > But the ones heap may never run at all, is that right? > > You can't rely on the garbage collector for deterministic > destruction, no. Are there some kind of replacement or I have to make my own finalize-like method, once I determine somewhat the application no longer need those resources? [...] If you know when you can deallocate something, that means you don't need the GC to collect it, I'll modify the program so that I know the right state to call my finalize-like method or just destroy(c). Until I find out that destrutor behavior, I was going to just use the destrutor so you could just allocate it on the malloc heap instead, and call destroy/free once you're done. You could use the C version of malloc/free. You can also optionally use GC.malloc/GC.free. E.g.: class C {...} import core.memory : GC; C c = cast(C) GC.malloc(C.sizeof); ... // use c // We're done with c, destroy it destroy(c); // this will call the dtor GC.free(cast(void*) c); c = null; // optional, just to ensure we don't accidentally use it again T I'll do something like this, thanks
Re: Can't I allocate at descontructor?
On Friday, 5 March 2021 at 20:28:58 UTC, Ali Çehreli wrote: On 3/5/21 12:24 PM, Jack wrote: Are there some kind of replacement or I have to make my own finalize-like method, once I determine somewhat the application no longer need those resources? destroy() executes the destructor. but I would need to call it manually and only after I somewhat I've determined I no longer need the resources, right? so destroy(c) would be no different from calling my own finalize-like method like freeResources()? To my surprise, even though 'c' is not null below, the destructor is not executed multiple times. import std.stdio; class C { string fileName; this(string fileName) { writeln("constructing"); this.fileName = fileName; writeln("creating file"); } ~this() { writeln("destructing"); if (fileName) { writeln("removing the file"); } else { writeln("NOT removing the file"); } } } void main() { auto c = new C("some imaginary file name"); // Executes the destructor destroy(c); // This does not do anything destroy(c); // Neither does this import core.memory; GC.collect(); } Ali
Re: Can't I allocate at descontructor?
On Friday, 5 March 2021 at 20:18:44 UTC, Max Haughton wrote: On Friday, 5 March 2021 at 20:13:54 UTC, Jack wrote: On Friday, 5 March 2021 at 20:10:39 UTC, Max Haughton wrote: On Friday, 5 March 2021 at 20:03:58 UTC, Jack wrote: On Friday, 5 March 2021 at 09:23:29 UTC, Mike Parker wrote: On Friday, 5 March 2021 at 05:31:38 UTC, Jack wrote: [...] https://dlang.org/blog/2021/03/04/symphony-of-destruction-structs-classes-and-the-gc-part-one/ thanks for such good article. So if the object was allocated on heap, there's no guarantee that the object's destrutor will be called at all? do destrutor allocate at stack are guarantee to be run? Destructors of structs on the stack will always run deterministically. But the ones heap may never run at all, is that right? You can't rely on the garbage collector for deterministic destruction, no. Are there some kind of replacement or I have to make my own finalize-like method, once I determine somewhat the application no longer need those resources? aside from destructor for memory allocated on stack, what are uses for destrutors?
Re: Can't I allocate at descontructor?
On Friday, 5 March 2021 at 20:10:39 UTC, Max Haughton wrote: On Friday, 5 March 2021 at 20:03:58 UTC, Jack wrote: On Friday, 5 March 2021 at 09:23:29 UTC, Mike Parker wrote: On Friday, 5 March 2021 at 05:31:38 UTC, Jack wrote: The following code returns a memory error. I did notice it did happens whenever I did a memory allocation. Is this not possible in the descontrutor? if so, why? https://dlang.org/blog/2021/03/04/symphony-of-destruction-structs-classes-and-the-gc-part-one/ thanks for such good article. So if the object was allocated on heap, there's no guarantee that the object's destrutor will be called at all? do destrutor allocate at stack are guarantee to be run? Destructors of structs on the stack will always run deterministically. But the ones heap may never run at all, is that right?
Re: Can't I allocate at descontructor?
On Friday, 5 March 2021 at 09:23:29 UTC, Mike Parker wrote: On Friday, 5 March 2021 at 05:31:38 UTC, Jack wrote: The following code returns a memory error. I did notice it did happens whenever I did a memory allocation. Is this not possible in the descontrutor? if so, why? https://dlang.org/blog/2021/03/04/symphony-of-destruction-structs-classes-and-the-gc-part-one/ thanks for such good article. So if the object was allocated on heap, there's no guarantee that the object's destrutor will be called at all? do destrutor allocate at stack are guarantee to be run?
Re: Can't I allocate at descontructor?
On Friday, 5 March 2021 at 05:42:03 UTC, evilrat wrote: On Friday, 5 March 2021 at 05:31:38 UTC, Jack wrote: The following code returns a memory error. I did notice it did happens whenever I did a memory allocation. Is this not possible in the descontrutor? if so, why? GC prohibits allocation during collection, since this dtor is likely called by GC this is what happens. If you REALLY need this just allocate using other mechanisms. I didn't know that, it seems even if I use other allocation mechanism there's no guarantee the deconstructor will be called so it seems the native descontrutor will not be of help at all
Re: Is there any generic iteration function that stops at first match?
On Friday, 5 March 2021 at 04:22:23 UTC, Steven Schveighoffer wrote: On Friday, 5 March 2021 at 02:13:39 UTC, Jack wrote: something like filter[1] but that stops at first match? are there any native functions for this in D or I have to write one? just making sure to not reinvent the wheel [1]: https://devdocs.io/d/std_algorithm_iteration#filter std.algorithm.searching.until -Steve thanks, totally overlooked this searching section
Re: Is there any generic iteration function that stops at first match?
On Friday, 5 March 2021 at 02:43:36 UTC, H. S. Teoh wrote: On Fri, Mar 05, 2021 at 02:13:39AM +, Jack via Digitalmars-d-learn wrote: something like filter[1] but that stops at first match? are there any native functions for this in D or I have to write one? just making sure to not reinvent the wheel [...] Why not just .front? E.g.: int[] data = [ 1,2,3,4,5 ]; auto r = data.filter!(v => v % 2 == 0); assert(r.front == 2); T it loops over the entire array then returns, I'd like to stop as soon as the predicate return true
Can't I allocate at descontructor?
The following code returns a memory error. I did notice it did happens whenever I did a memory allocation. Is this not possible in the descontrutor? if so, why? core.exception.InvalidMemoryOperationError@src\core\exception.d(647): Invalid memory operation import std.stdio; int main() { auto a = new A; return 0; } class A { this() { } ~this() { f(); } } void f() { auto str = new string[100]; }
Is there any generic iteration function that stops at first match?
something like filter[1] but that stops at first match? are there any native functions for this in D or I have to write one? just making sure to not reinvent the wheel [1]: https://devdocs.io/d/std_algorithm_iteration#filter
What's the default implementation of opCmp/opEquals for structs?
the one that the compiler defaults to when you don't provide one?
How can I tell if the give parameter can be run at compile time?
bool g(T)(T) { return __traits(compiles, mixin("{ enum a = t; }")); } int a; enum s = ""; // both return false but g(s) is expected to return true pragma(msg, g(s)); pragma(msg, g(a));
Re: Does reserve() preallocate for futher appends too?
On Monday, 1 March 2021 at 03:12:42 UTC, Adam D. Ruppe wrote: On Monday, 1 March 2021 at 03:07:19 UTC, Jack wrote: isn't clear for me if reserve() does preallocate memory so that that operator like arr ~= x can use previously allocate memory by reserve() or it's just used in slices like b = arr[x .. y]? Slicing never allocates memory. reserve extends the capacity for the ~= operator. thanks
Does reserve() preallocate for futher appends too?
isn't clear for me if reserve() does preallocate memory so that that operator like arr ~= x can use previously allocate memory by reserve() or it's just used in slices like b = arr[x .. y]?
Re: How do I check if a type is assignable to null at compile time?
On Saturday, 27 February 2021 at 01:23:06 UTC, H. S. Teoh wrote: On Sat, Feb 27, 2021 at 01:03:56AM +, Jack via Digitalmars-d-learn wrote: On Friday, 26 February 2021 at 23:37:18 UTC, Murilo wrote: > On Friday, 26 February 2021 at 05:25:14 UTC, Jack wrote: > > I started with: > > > > enum isAssignableNull(T) = is(T : Object) || isPointer(T); > > > > but how do I cover all cases? > > You can check if it's null with this `variable is null` and > you can test it with assert as in `assert(variable is null);` I mean a give type T not variablee Why not just: enum isAssignableNull(T) = is(typeof((T t){ t = null; })); ? T works too, thanks but I ended up using Nathan S. solution which is quite fine too: enum bool isAssignableNull(T) = is(typeof(null) : T);
How can I make this work?
I'm using a windows callback function where the user-defined value is passed thought a LPARAM argument type. I'd like to pass my D array then access it from that callback function. How is the casting from LPARAM to my type array done in that case? for example, I need something like this to work: int[] arr = [1, 2, 3]; long l = cast(long) cast(void*) arr.ptr; int[] a = cast(int[]) cast(void*) l;
Re: How do I check if a type is assignable to null at compile time?
On Friday, 26 February 2021 at 23:37:18 UTC, Murilo wrote: On Friday, 26 February 2021 at 05:25:14 UTC, Jack wrote: I started with: enum isAssignableNull(T) = is(T : Object) || isPointer(T); but how do I cover all cases? You can check if it's null with this `variable is null` and you can test it with assert as in `assert(variable is null);` I mean a give type T not variablee
Re: How can I get the variable name passed as parameter from within a function?
On Friday, 26 February 2021 at 19:37:34 UTC, Adam D. Ruppe wrote: On Friday, 26 February 2021 at 19:32:52 UTC, Jack wrote: I managed to do this with alias parameter in a template: this is the only way, it needs to be an alias template Also, can I short this template function somehow to syntax f!(a) omitting the g? rename g to f. If the function inside the template's name matches the template's own name, the compiler combines them. of course at that point you can also just write it void f(alias var)() { // do your magic } thanks! i was confused about where put alias in the function parameters but of course it's in the first () meant to be used as template parameters
How can I get the variable name passed as parameter from within a function?
int a = 10; f(a); // print "a" int b = 10; f(b); // print "b" I managed to do this with alias parameter in a template: template f(alias s, string file = __FILE__, size_t line = __LINE__) { import std.exception : enforce; import std.string : format; void g() { writeln(__traits(identifier, s)); } } so I can call like this: f!(a).g; // print "a" Are there other way to do this? Also, can I short this template function somehow to syntax f!(a) omitting the g? I couldn't find a way to set the template's body like it's a function
Re: How do I check if a type is assignable to null at compile time?
On Friday, 26 February 2021 at 05:45:39 UTC, Nathan S. wrote: On Friday, 26 February 2021 at 05:34:26 UTC, Paul Backus wrote: On Friday, 26 February 2021 at 05:25:14 UTC, Jack wrote: I started with: enum isAssignableNull(T) = is(T : Object) || isPointer(T); but how do I cover all cases? Something like this should work: enum isAssignableNull(T) = __traits(compiles, (T t) => t = null); `isAssignableNull!(immutable void*)` is true with his definition but false with yours. Of course you are correct that you cannot assign to an immutable pointer. yep, it must be true for pointers too. Thank you all guys. is(typeof(null) : T) works like a charm
How do I check if a type is assignable to null at compile time?
I started with: enum isAssignableNull(T) = is(T : Object) || isPointer(T); but how do I cover all cases?
Is this a good way to do lazy evaluation?
I have a base class that loads a value and if it isn't net, load a default value. Since the value can be set, I'd like to do lazy evaluation of this default value until it's really needed. So rather have a C defValue = xxx, that makes xxx to be loaded even if defValue doesn't get used. So I thought I would use property and override it from the derived class, to archive the lazy evaluation effect that I'd like. Is this a good approach? are there better ways to do that? here's a sample code of what I'm talking about (I'm using int just to make it simple but the class in the real code is bigger and can have many instances, hence my attempt to optimize that): class A { C defValue() { return C.a; } C value; void doSomething() { // doSomething gets called from all derived classes // but value is set often, loading defValue right away // would waste time and resources if(!value) { value = defValue; } } } class B : A { // use propety to have a lazy evaluation of value override C defValue() { return C.b; } void foo() { // loadDefvalue, if value not set, lazily... doSomething(); // do something else... } } class C { int n; this(int v) { n = v; } static this() { a = new C(10); b = new C(11); } void load() { // do something with n } static { C a; C b; } }
Re: Is this the proper way to do it?
On Saturday, 13 February 2021 at 07:08:58 UTC, mw wrote: On Saturday, 13 February 2021 at 05:52:34 UTC, Jack wrote: I have a base class A, where I make specific operator depending on the derived class type. Currently I'm using something like this: c is a class derived from A bool shouldDoX = (cast(X)c) !is null || (cast(Y)c) !is null || (cast(K)c) !is null ... ; as the number of cast(C) !is null is growing, I'm afraid of this being a inelegant or even poor performance approach. How would you do that? Isn't that what virtual function is designed for? ``` class Base { bool shouldDoX() {return false;} } class Derived: Base { bool shouldDoX() {return true;} } class Derived2: Derived { bool shouldDoX() {return false;} } ... ``` sounds a better approach, I ended up using this. Lots of cast(X), cast(Y), etc is probably slow and gets messy with time.
Re: Is this the proper way to do it?
On Saturday, 13 February 2021 at 19:40:43 UTC, frame wrote: On Saturday, 13 February 2021 at 05:52:34 UTC, Jack wrote: I have a base class A, where I make specific operator depending on the derived class type. Currently I'm using something like this: c is a class derived from A bool shouldDoX = (cast(X)c) !is null || (cast(Y)c) !is null || (cast(K)c) !is null ... ; as the number of cast(C) !is null is growing, I'm afraid of this being a inelegant or even poor performance approach. How would you do that? I would just use an (empty) interface on that classes and do test for that. i did consider that too but ended up with virtual functions
Re: Is this the proper way to do it?
On Saturday, 13 February 2021 at 09:54:28 UTC, Rumbu wrote: On Saturday, 13 February 2021 at 05:52:34 UTC, Jack wrote: I have a base class A, where I make specific operator depending on the derived class type. Currently I'm using something like this: c is a class derived from A bool shouldDoX = (cast(X)c) !is null || (cast(Y)c) !is null || (cast(K)c) !is null ... ; as the number of cast(C) !is null is growing, I'm afraid of this being a inelegant or even poor performance approach. How would you do that? Option 1, reverse the condition, && op will shortcut boolean conditions bool shouldNotDoX = cast(X)c && cast(Y)c && cast(K)c && ... Option 2, reverse the condition by testing the classes that are not supposed to "do" it, if you have less classes in that category. bool shoudldNotDoX = cast(P)c || cast(Q)c I ended up using virtual functions, this cast and conditions would get too big, ugly and messy with time
Re: how to make this function nothrow?
On Tuesday, 16 February 2021 at 00:39:33 UTC, Steven Schveighoffer wrote: On 2/15/21 4:04 PM, Jack wrote: I have to make my function nothrow because the function that calls it (not written by me) is nothrow. So I need to wrap my code in a try-catch() but how will I report the error message, if the toString() from Throwable isn't nothrow? how do I get out this circular dependence? void f() nothrow { import std.conv : to; try { // do something } catch(Throwable th) { auto err = th.toString; } } I can't use err variable, it result in error: function object.Throwable.toString is not nothrow obviously, insert a try-catch() within catch() is a circular dependence and doesn't solve the problem either (even if it, I think it would be quite ugly) https://dlang.org/phobos/std_exception.html#assumeWontThrow import std.exception; auto err = assumeWontThrow(th.toString, "oops, toString threw something!"); -Steve I didn't know about that function, I'll be using this one from now. Thanks! Adam and Ali thank you guys too, helpful always
Re: Foo Foo = new Foo();
Why doesn't this compiles? class Baa { Foo Foo = new Foo(); }
Re: How can I get this UDA at compile time?
On Sunday, 21 February 2021 at 09:30:14 UTC, Jacob Carlborg wrote: On 2021-02-21 07:12, Jack wrote: I've had a struct like this: struct Attr { string value; } struct Foo { @(Attr("a attr")) enum a = Foo(10); @(Attr("b attr")) enum b = Foo(11); int x; int y; bool doY = true; int value() { return x; } } I'd like to get that atrribute's value at compile time, something like this: enum s = Foo.a.baa; enum s2 = Foo.b.baa; writeln(s); // a attr writeln(s2); // b attr I did this: string baa() { import std.traits : getUDAs, hasUDA; static foreach(field; __traits(allMembers, Foo)) {{ alias m = __traits(getMember, Foo, field); static if(is(typeof(m) == Foo)) { if(m.value == this.value) return getUDAs!(m, Attr)[0].value; } }} return null; } that was working fine, but I needed to switch value property from Foo struct, so that I can't read this value at CTFE anymore, so this fails now: if(m.value == this.value) return getUDAs!(m, Attr)[0].value; How can I solve this? You can't look at the value when trying to find the correct member. It doesn't work when the value is unique and know at compile-time, as it was previously. So this worked: static foreach(field; __traits(allMembers, Foo)) {{ alias m = __traits(getMember, Foo, field); static if(is(typeof(m) == Foo)) { if(m.value == this.value) return getUDAs!(m, Attr)[0].value; } }} This could retrieve the attribute at compile time by value but i did changes in the struct and the member value wasn't know at compile time anymore. You need to look at the name. That's I'm looking for. Is there a way to get the idenfifier of the current instance, from within the class? for example: struct Foo { enum x = Foo(10); enum y = Foo(11); string myID() { eum s = some magic with traits? return s; } } writeln(Foo.x.myID); // x writeln(Foo.y.myID); // y that would solve my problem, I would just pass that idenfifier to __traits(getMember, Foo, x) then get what I want with getUDAs() I don't think it's possible to solve that with the exact same API as you have used above. The simplest solution would be to just use `__traits(getAttributes)` and wrap that in a help function: string getAttribute(T, string name)() { return __traits(getAttributes, mixin(T.stringof, ".", name))[0].value; } void main() { writeln(getAttribute!(Foo, "a")); } the main isssue is get "a" identifier, as I mentioned previously. Or you can create a proxy struct and use opDispatch like this, to get something a bit closer to your original example: // add this to the Foo struct static Proxy attributes() { return Proxy(); } struct Proxy { string opDispatch(string name)() { return __traits(getAttributes, mixin("Foo.", name))[0].value; } } void main() { writeln(Foo.attributes.a); } your proxy struct and opDispatch() give me a good idea how do that, something like this: void main() { writeln(P.Foo); } struct S { string name; } struct P { static auto ref opDispatch(string member)() { writeln("member = ", member); // save this somewhere alias m = __traits(getMember, A, member); return m; } } struct A { @(S("attr foo")) enum Foo = A(10); @(S("attr baa")) enum Baa = A(11); int v; } now I got the member string but I still need to figure out where to salve it to use from within the A struct. add a string id to struct A wouldn't work for Foo and Baa because they are enum. I have to save it somewhere else. I static array doesn't work either because it isn't run at CTFE.
How can I get this UDA at compile time?
I've had a struct like this: struct Attr { string value; } struct Foo { @(Attr("a attr")) enum a = Foo(10); @(Attr("b attr")) enum b = Foo(11); int x; int y; bool doY = true; int value() { return x; } } I'd like to get that atrribute's value at compile time, something like this: enum s = Foo.a.baa; enum s2 = Foo.b.baa; writeln(s); // a attr writeln(s2); // b attr I did this: string baa() { import std.traits : getUDAs, hasUDA; static foreach(field; __traits(allMembers, Foo)) {{ alias m = __traits(getMember, Foo, field); static if(is(typeof(m) == Foo)) { if(m.value == this.value) return getUDAs!(m, Attr)[0].value; } }} return null; } that was working fine, but I needed to switch value property from Foo struct, so that I can't read this value at CTFE anymore, so this fails now: if(m.value == this.value) return getUDAs!(m, Attr)[0].value; How can I solve this?
Re: How do I enable visual styles?
if someone happens to be looking to do that in the future: I didn't find a way to do this with a linker but managed to find a way to do this with code only. The code goes like this: // source: https://stackoverflow.com/a/10444161/800123 #include // NOTE: It is recommended that you delay-load ComCtl32.dll (/DelayLoad:ComCtl32.dll) // and that you ensure this code runs before GUI components are loaded. // Otherwise, you may get weird issues, like black backgrounds in icons in image lists. ULONG_PTR EnableVisualStyles(VOID) { TCHAR dir[MAX_PATH]; ULONG_PTR ulpActivationCookie = FALSE; ACTCTX actCtx = { sizeof(actCtx), ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_SET_PROCESS_DEFAULT | ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID, TEXT("shell32.dll"), 0, 0, dir, (LPCTSTR)124 }; UINT cch = GetSystemDirectory(dir, sizeof(dir) / sizeof(*dir)); if (cch >= sizeof(dir) / sizeof(*dir)) { return FALSE; /*shouldn't happen*/ } dir[cch] = TEXT('\0'); ActivateActCtx(CreateActCtx(), ); return ulpActivationCookie; } it's C as code but can be translated to D easy.
how to make this function nothrow?
I have to make my function nothrow because the function that calls it (not written by me) is nothrow. So I need to wrap my code in a try-catch() but how will I report the error message, if the toString() from Throwable isn't nothrow? how do I get out this circular dependence? void f() nothrow { import std.conv : to; try { // do something } catch(Throwable th) { auto err = th.toString; } } I can't use err variable, it result in error: function object.Throwable.toString is not nothrow obviously, insert a try-catch() within catch() is a circular dependence and doesn't solve the problem either (even if it, I think it would be quite ugly)
Is there other way to do that?
I need to check if an instance is of a specific type derived from my base class but this class has template parameter and this type isn't available at time I'm checking it. Something like: class B { } class A(T) : B { } class X : B { } class Z : B { } auto c = can be any derived class from B bool isX = cast(A!???) c !is null; assert(isX); an interface would work: interface IA { } class A(T) : B, IA { } bool isX = cast(IA) c !is null; assert(isX); but I would have create one just for that. It feels a bit hacky? also, does an empty interface like that increase the A class memory size at all?
Is this the proper way to do it?
I have a base class A, where I make specific operator depending on the derived class type. Currently I'm using something like this: c is a class derived from A bool shouldDoX = (cast(X)c) !is null || (cast(Y)c) !is null || (cast(K)c) !is null ... ; as the number of cast(C) !is null is growing, I'm afraid of this being a inelegant or even poor performance approach. How would you do that?
Re: how to properly compare this type?
helpful always,thank you guys