Re: Non-recursive maxSizeOf
On Thursday, 6 August 2020 at 01:23:33 UTC, Per Nordlöw wrote: How does the memory usage and speed of this code compare to the variant that uses template instantiations? I haven't tested this specifically, but similar tests have come in at like 1/10th the memory and compile time cost. There is one template instance here per argument list though, and that template includes the implementation function. The eponymous version Ali posted will perform a bit better than my version because the compiler can see it will never need code generation. Still for small argument lists the Phobos one might do better, but for larger ones, the ctfe version should be much better. So on average Ali's version is almost certain to win in my experience.
Re: Non-recursive maxSizeOf
On Thursday, 6 August 2020 at 01:17:51 UTC, lithium iodate wrote: more love for phobos pls That would add a lot to the cost and bring no real benefit
Re: Non-recursive maxSizeOf
On Thursday, 6 August 2020 at 01:13:41 UTC, Adam D. Ruppe wrote: It is very easy too... just write an ordinary function: size_t maxSizeOf(T...)() { size_t max = 0; foreach(t; T) if(t.sizeof > max) max = t.sizeof; return max; } pragma(msg, maxSizeOf!(int, char, long)); How does the memory usage and speed of this code compare to the variant that uses template instantiations? In general? Any experiences on this?
Re: Non-recursive maxSizeOf
On Thursday, 6 August 2020 at 01:17:51 UTC, lithium iodate wrote: more love for phobos pls template maxSizeOf(T...) { template sizeOf(T) { // doesn't exist in phobos? enum sizeOf = T.sizeof; } enum size_t maxSizeOf = maxElement([staticMap!(sizeOf, T)]); } `std.meta.staticMap` is defined recursively
Re: Non-recursive maxSizeOf
On Thursday, 6 August 2020 at 01:13:28 UTC, Ali Çehreli wrote: Boring in D. :p template maxSizeOf(T...) { enum maxSizeOf = compute(); auto compute() { size_t result; static foreach (t; T) { if (t.sizeof > result) { result = t.sizeof; } } return result; } } I forgot to say that I was looking for a solution that used `static foreach` but doesn't trigger CTFE...
Re: Non-recursive maxSizeOf
On Thursday, 6 August 2020 at 01:13:41 UTC, Adam D. Ruppe wrote: size_t maxSizeOf(T...)() { size_t max = 0; foreach(t; T) if(t.sizeof > max) max = t.sizeof; return max; } pragma(msg, maxSizeOf!(int, char, long)); more love for phobos pls template maxSizeOf(T...) { template sizeOf(T) { // doesn't exist in phobos? enum sizeOf = T.sizeof; } enum size_t maxSizeOf = maxElement([staticMap!(sizeOf, T)]); }
Re: Non-recursive maxSizeOf
On Thursday, 6 August 2020 at 00:58:39 UTC, Per Nordlöw wrote: Is it possible to implement in a non-recursive way? It is very easy too... just write an ordinary function: size_t maxSizeOf(T...)() { size_t max = 0; foreach(t; T) if(t.sizeof > max) max = t.sizeof; return max; } pragma(msg, maxSizeOf!(int, char, long));
core.thread vs std.concurrency - which of them to use?
When to use core.thread and when std.concurrency for multithreading in applications? Is one of them a preferred way?
Re: Non-recursive maxSizeOf
On 8/5/20 5:58 PM, Per Nordlöw wrote: Is it possible to implement template maxSizeOf(T...) { static if (T.length == 1) enum size_t maxSizeOf = T[0].sizeof; else { enum size_t firstSize = T[0].sizeof; enum size_t maxSizeRest = maxSizeOf!(T[1 .. $]); enum size_t maxSizeOf = firstSize >= maxSizeRest ? firstSize : maxSizeRest; } } in a non-recursive way? Boring in D. :p template maxSizeOf(T...) { enum maxSizeOf = compute(); auto compute() { size_t result; static foreach (t; T) { if (t.sizeof > result) { result = t.sizeof; } } return result; } } void main() { pragma(msg, maxSizeOf!(double, char, string)); } Ali
Non-recursive maxSizeOf
Is it possible to implement template maxSizeOf(T...) { static if (T.length == 1) enum size_t maxSizeOf = T[0].sizeof; else { enum size_t firstSize = T[0].sizeof; enum size_t maxSizeRest = maxSizeOf!(T[1 .. $]); enum size_t maxSizeOf = firstSize >= maxSizeRest ? firstSize : maxSizeRest; } } in a non-recursive way?
Re: Invoking the compiler during runtime
On 2020-08-05 09:57, cy wrote: Well, I did find this: https://dlang.org/blog/2017/08/01/a-dub-case-study-compiling-dmd-as-a-library/ That is more for using the frontend, not the backend for generating code. But it's pretty advanced... probably just invoking dmd would be good... You can start with that at least. -- /Jacob Carlborg
Files and UTF
In my efforts to learn D I am writing some code to read files in different UTF encodings with the aim of having them end up as UTF-8 internally. As a start I have the following code: import std.stdio; import std.file; void main(string[] args) { if (args.length == 2) { if (args[1].exists && args[1].isFile) { auto f = File(args[1]); writeln(args[1]); for (auto i = 1; i <= 3; ++i) write(f.readln); } } } It works well outputting the file name and first three lines of the file properly, without any regard to the encoding of the file. The exception to this is if the file is UTF-16, with both LE and BE encodings, two characters representing the BOM are printed. I assume that write detects the encoding of the string returned by readln and prints it correctly rather than readln reading in as a consistent encoding. Is this correct? Is there a way to remove the BOM from the input buffer and still know the encoding of the file? Is there a D idiomatic way to do what I want to do? Mike
Dub can't find and download packages
Hello. I'm starting to use D, and therefore Dub. I didn't find a more suitable category than this one in the forum to ask my question, I'm sorry if it is not the most suitable. My concern is thus the following: I can't add packages to my project, Dub warns me that they are not available. For the example, I try to add this dependency (https://code.dlang.org/packages/pegged) with the following command: dub add pegged . Dub then returns an error: Failed to get versions for package pegged on provider registry at https://code.dlang.org/ (fallbacks registry at https://codemirror.dlang.org/, registry at https://dub.bytecraft.nl/, registry at https://code-mirror.dlang.io/): Failed to download https://code.dlang.org/api/packages/infos?packages=%5B%22pegged%22%5D_dependencies=true=true Could not find package 'pegged'. My project was initialized correctly with Dub (dub init... + the whole procedure). I also tried to add the dependency manually, in dub.sdl: dependency "pegged" version="~>0.4.2" But it doesn't change anything. Why doesn't it work? What do I need to do to get Dub to download and add dependencies? Thanks in advance. PS: how do you write blocks of code and insert links in forum posts? I've tried the makefile syntax, but it doesn't work. Thanks too!
Re: Invoking the compiler during runtime
On Wed, Aug 05, 2020 at 06:02:58AM +, cy via Digitalmars-d-learn wrote: > D's compile-time-execution is fantastic, but there are some times when > I'd like to examine the generated code, or produce code that needs to > pass through earlier phases before CTFE, or do AST stuff. Sometimes I > simply don't want to generate the code with every compilation, so > saving the generated code in a file some would be really neat, if I > could then invoke the compiler during runtime to build it. Plus > backtraces wouldn't just be "dlang-mixin-397." TBH, in spite of D's amazing metaprogramming capabilities, there comes a point where compile-time generated code just becomes too unwieldy. Like if you have multi-page mixin strings, or mixins nested to the n'th level, or your token strings span 10+ pages and it becomes just impossible to debug. In those cases, my standard solution is to write an auxiliary program that emits D code, and then just compile that with the main program as a second step. The nice thing about that is, as you said, you can examine the generated code, run coverage on it or whatever other analysis, or just plain debug the generating code until the output looks like it might compile before you actually try to compile it, instead of dealing with multi-page template instantiation errors that only a Klingon could decipher. [...] > In C I write a utility program in awful C to print out C code, have a > cmake custom command run that awful C as needed, and assume the > existence of that generated source in my main program. That's exactly what I'd do. The utility program, of course, would also be in D. :-D With unittests, even, that ensure the output is syntactically correct. :-P How's that for self-reference? :-P > So is that the best way to do it? Have a side program that writes D > source to a file, and then the main program simply imports the file? Yep. > Or is there some AST syntax I should be generating instead? Some way > to import the compiler itself, instead of calling it in a subprocess? IMO it's not worth the trouble to import the compiler itself, unless you want to do runtime dynamic (re)compilation. I've also done that, but generally I advise against importing the compiler, but instead just run it as a separate process (say using std.process, which is very convenient). Generate the code you want to compile in string form, spit it to a temporary file and compile it (or pipe it through stdin to `dmd -`) into a shared object, then load it dl_open on Posix (or whatever the Windows equivalent it) and run the code that way. Before the recent fiasco, dmd is fast enough that generally you won't notice the lag unless you do this in a tight loop. But I wouldn't recommend this unless you want to do it at runtime, since you'll have to ship a copy of dmd with your program, which comes with its own bag o' worms (you essentially need to ship an entire working installation of dmd for this to work). If you just need to generate some complicated D code at build time, just write a helper utility to emit D code, and call it a day. I have a project where I need to generate D code from large data files that would be too resource-intensive to do from inside CTFE, so a utility that emits D is what I went with. In the same project I also have a helper program that scans GLSL (vertex shader) code and generates D APIs for each shader (automates binding parameters, generation of wrapper functions, etc.). Possible to do with CTFE if I tried hard enough, but at the end of the day, why would I? Doing it in CTFE bloats compile-time beyond my patience, and requires onerous resources, and besides, CTFE cannot access OS functions like scanning directories; so why not just write a helper D program that has full OS access, runs faster, and does what it needs to do to generate D code that I can then import in my main program. > Is there a way in dub to specify that you run a D program contained in > X.d during the build process, to build Y.d, that Z.d imports? I don't know if the latest version of dub can do that, but the last time I checked about a year or so ago, it couldn't. Or at least, not without jumping through hoops and bending over backwards. But that's not a problem for me anyway, since I use SCons to build my projects, and SCons has no problem at all building multiple helper programs that each generate some subset of D source files, and then compiling said files into the final product. In fact, even multiple final products (in the aforementioned project, for example, my SCons script builds both an APK for Android with an LDC cross-compiler, and a Linux executable for on-PC testing at the same time with dmd :-P). This method of building generally goes against the grain of dub's design, though, so instead of fighting with dub in an uphill battle, I just went with something more flexible instead. T -- Windows 95 was a joke, and Windows 98 was the punchline.
Re: Why is time_t defined as a 32-bit type on Windows?
On Wednesday, 5 August 2020 at 16:13:19 UTC, Andrej Mitrovic wrote: ``` C:\dev> rdmd -m64 --eval="import core.stdc.time; writeln(time_t.sizeof);" 4 ``` According to MSDN this should not be the case: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/time-time32-time64?view=vs-2019 time is a wrapper for _time64 and **time_t is, by default, equivalent to __time64_t**. But in Druntime it's defined as a 32-bit type: https://github.com/dlang/druntime/blob/349d63750d55d078426d4f433cba512625f8a3a3/src/core/sys/windows/stdc/time.d#L42 It looks like this definition was there from at least 2008 (!!), and probably earlier than that but I don't have the SVN sources: https://github.com/dlang/druntime/blob/6837c0cd426f7e828aec1a2bdc941ac9b722dd14/import/stdc/time.d#L49 So basically, just around the time the first 64-bit version of Windows was released. I'm guessing it was just neglected..
Why is time_t defined as a 32-bit type on Windows?
``` C:\dev> rdmd -m64 --eval="import core.stdc.time; writeln(time_t.sizeof);" 4 ``` According to MSDN this should not be the case: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/time-time32-time64?view=vs-2019 time is a wrapper for _time64 and **time_t is, by default, equivalent to __time64_t**. But in Druntime it's defined as a 32-bit type: https://github.com/dlang/druntime/blob/349d63750d55d078426d4f433cba512625f8a3a3/src/core/sys/windows/stdc/time.d#L42
Re: D on lm32-CPU: string argument on stack instead of register
On Tuesday, 4 August 2020 at 17:36:53 UTC, Michael Reese wrote: Thanks for suggesting! I tried, and the union works as well, i.e. the function args are registered. But I noticed another thing about all workarounds so far: Even if calls are inlined and arguments end up on the stack, the linker puts code of the wrapper function in my final binary event if it is never explicitly called. So until I find a way to strip of uncalled functions from the binary (not sure the linker can do it), the workarounds don't solve the size problem. But they still make the code run faster. Try -ffunction-sections -Wl,--gc-sections. That should remove all unreferenced functions. It removes all unreferenced sections, and writes every function into a separate section.
Re: can't access an alias created inside an if statement
On Wednesday, 5 August 2020 at 09:39:47 UTC, Simen Kjærås wrote: On Wednesday, 5 August 2020 at 09:32:58 UTC, Flade wrote: Thanks! You see it should work but the thing is. I'm using it inside a function. I'm checking for one of the function's parameter (if parameter == false) and it says that "the variable `parameter` cannot be read at compile time. Do you know if there is a way to fix this? As the error message says, the value must be known at compile time. Most likely, you can simply pass it as a template parameter: void fun(bool parameter)(int arg1, string arg2) { static if (parameter) { } } void main() { fun!true(1, "foo"); fun!false(19, "bar"); } -- Simen Thanks man! Works as expected! Have a great day!
Re: can't access an alias created inside an if statement
On Wednesday, 5 August 2020 at 09:32:58 UTC, Flade wrote: Thanks! You see it should work but the thing is. I'm using it inside a function. I'm checking for one of the function's parameter (if parameter == false) and it says that "the variable `parameter` cannot be read at compile time. Do you know if there is a way to fix this? As the error message says, the value must be known at compile time. Most likely, you can simply pass it as a template parameter: void fun(bool parameter)(int arg1, string arg2) { static if (parameter) { } } void main() { fun!true(1, "foo"); fun!false(19, "bar"); } -- Simen
Re: can't access an alias created inside an if statement
On Wednesday, 5 August 2020 at 09:25:23 UTC, Simen Kjærås wrote: On Wednesday, 5 August 2020 at 09:05:36 UTC, Flade wrote: I have used an if-else statement to create an alias to avoid code duplication but it doesn't let me access it outside the if statement. Is there a way to solve this? You're probably looking for static if: static if (useAlias) { alias myAlias = getAlias!(); } myAlias foo = getFoo(); What happens is a regular if statement introduces a scope, so anything declared inside it is unavailable outside. static if does not introduce a new scope, and so its contents can be accessed. static if only works with compile-time constant conditions, but aliases are also compile-time constructs, so this should not pose a problem. -- Simen Thanks! You see it should work but the thing is. I'm using it inside a function. I'm checking for one of the function's parameter (if parameter == false) and it says that "the variable `parameter` cannot be read at compile time. Do you know if there is a way to fix this?
Re: can't access an alias created inside an if statement
On Wednesday, 5 August 2020 at 09:05:36 UTC, Flade wrote: I have used an if-else statement to create an alias to avoid code duplication but it doesn't let me access it outside the if statement. Is there a way to solve this? You're probably looking for static if: static if (useAlias) { alias myAlias = getAlias!(); } myAlias foo = getFoo(); What happens is a regular if statement introduces a scope, so anything declared inside it is unavailable outside. static if does not introduce a new scope, and so its contents can be accessed. static if only works with compile-time constant conditions, but aliases are also compile-time constructs, so this should not pose a problem. -- Simen
can't access an alias created inside an if statement
I have used an if-else statement to create an alias to avoid code duplication but it doesn't let me access it outside the if statement. Is there a way to solve this?
Re: Invoking the compiler during runtime
On Wednesday, 5 August 2020 at 06:02:58 UTC, cy wrote: Some way to import the compiler itself, instead of calling it in a subprocess? Well, I did find this: https://dlang.org/blog/2017/08/01/a-dub-case-study-compiling-dmd-as-a-library/ But it's pretty advanced... probably just invoking dmd would be good...
Invoking the compiler during runtime
D's compile-time-execution is fantastic, but there are some times when I'd like to examine the generated code, or produce code that needs to pass through earlier phases before CTFE, or do AST stuff. Sometimes I simply don't want to generate the code with every compilation, so saving the generated code in a file some would be really neat, if I could then invoke the compiler during runtime to build it. Plus backtraces wouldn't just be "dlang-mixin-397." I'm a big supporter of compiling from source and not using third party binaries, so I don't mind designing software that only works with runtime access to a D compiler. But I'm not sure how best to generate the code, or to invoke the compiler, or how to use what it compiles. In C I write a utility program in awful C to print out C code, have a cmake custom command run that awful C as needed, and assume the existence of that generated source in my main program. So is that the best way to do it? Have a side program that writes D source to a file, and then the main program simply imports the file? Or is there some AST syntax I should be generating instead? Some way to import the compiler itself, instead of calling it in a subprocess? Is there a way in dub to specify that you run a D program contained in X.d during the build process, to build Y.d, that Z.d imports?