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: Array fill performance differences between for, foreach, slice
On Wednesday, 1 April 2020 at 06:48:09 UTC, Jacob Carlborg wrote: I you care about performance you should really compile using LDC (with `-O5 -release -flto=full -defaultlib=phobos2-ldc-lto,druntime-ldc-lto`), which usually produces much better code: Slice: Mean time(usecs): 50.58, Standard Deviation: 46.2621 Foreach: Mean time(usecs): 53.92, Standard Deviation: 19.8039 For: Mean time(usecs): 39.89, Standard Deviation: 7.80041 Slice: Mean time(usecs): 76.62, Standard Deviation: 73.0014 Foreach: Mean time(usecs): 49.63, Standard Deviation: 24.5672 For: Mean time(usecs): 40.02, Standard Deviation: 7.67388 The benchmark is highly flawed, the results for LDC are completely meaningless. LDC produces identical code for every case and the filling procedures are all elided.
Re: "register int n" alternative
On Sunday, 16 February 2020 at 15:15:44 UTC, Stefan Koch wrote: The register keyword as been deprecated for ages in C. Since the compiler cannot actually guarantee that the variable will be a register. As a result D does not have the register keyword. That only applies for C++, where it doesn't (or rather didn't) even do the same thing as in C. In C it's an optimization aid with actual semantic implications. A register storage-class variable cannot be aliased, in fact, any attempt should cause compilation failure. Whether it actually helps modern compilers with optimization is of course another matter ;)
Re: bindbc-opengl: Now drawing triangle
On Saturday, 25 January 2020 at 19:52:25 UTC, Luhrel wrote: Hello, I made a simple OpenGL file using bindbc-opengl and glfw (https://pastebin.com/ehmcHwxj) based on https://github.com/SonarSystems/Modern-OpenGL-Tutorials/blob/master/%5BGETTING%20STARTED%5D/%5B1%5D%20Triangle/main.cpp The cpp project compiles and runs fine (g++ main.cpp -lGL -lglfw -o gl_test && ./gl_test), but my d-translated file not: the triangle isn't shown. Do you have any idea ? In line 146 glBufferData(GL_ARRAY_BUFFER, vertices.sizeof, vertices.ptr, GL_STATIC_DRAW); you are calculating the size of `vertices` incorrectly. As `vertices` is a dynamic array, .sizeof will only give you the size of the array reference (size_t.sizeof * 2, note that .sizeof will always give you a compile-time constant in D). Change it to glBufferData(GL_ARRAY_BUFFER, vertices.length * GLfloat.sizeof, vertices.ptr, GL_STATIC_DRAW); and the data will be correctly copied into the buffer.
Re: Fetching an element using find
On Monday, 13 January 2020 at 17:58:57 UTC, Steven Schveighoffer wrote: On 1/13/20 12:47 PM, H. S. Teoh wrote: Why not write your own convenience wrapper? auto firstElement(R)(R r) if (isInputRange!R) { if (r.empty) throw new Exception(...); return r.front; } auto e = myData.find!(e => blah(e)).firstElement; I certainly can (and did). I was wondering if there was something in Phobos to do it. -Steve `adjoin` can be used to run an inline lambda: auto answer = arr.find!((item,x) => item.id == x)(id).adjoin!((n){enforce(!n.empty); return n.front;}); Using a simple alias you can have a flexible and nice to read solution: alias ensure(alias pred) = (n, const(char)[] msg = "`ensure` failed"){enforce(pred(n), msg); return n;}; // module scope for UFCS! auto answer = arr.find!((item,x) => item.id == x)(id).ensure!(n => !n.empty).front; or with custom message: auto answer = arr.find!((item,x) => item.id == x)(id).ensure!(n => !n.empty)("element with id not found").front;
Re: Speed of Random Numbers
On Saturday, 3 August 2019 at 16:35:34 UTC, Giovanni Di Maria wrote: Do you know other faster functions or methods to generate random numbers? For me the "goodness of random" is NOT important. Thank you very much GIovanni Di Maria First off you could try to use a faster RNG engine than the default. The easiest way is to define a variable containing it and passing it to the functions each time. auto rng = Xorshift(1234); randomNumber = uniform!uint(rng); This basic change approximately halved the 5 seconds your original example needs on my computer. Another simple approach that I have tried is simply hashing the iterator using a fast hash function. With xxHash32 I got the time down to 0.25 seconds. I also tried xxHash64 and FNV1a but they were not faster in my quick test.
Re: There is a computer languages benchmark compare site, but no Dlang benchmark. I think they should support D.
On Saturday, 22 June 2019 at 01:27:31 UTC, lili wrote: A nick site, has a lot of languages, unfortunately no dlang in there. https://benchmarksgame-team.pages.debian.net/benchmarksgame/ This page frequently pops up in this forum, please refer to existing posts: https://forum.dlang.org/search?q=benchmarksgame=forum In particular the last thread: https://forum.dlang.org/post/rcrhjgnskiuzzhrnz...@forum.dlang.org TL;DR: not happening.
Re: Range violation error when reading from a file
On Sunday, 16 June 2019 at 23:44:49 UTC, Samir wrote: On Sunday, 16 June 2019 at 23:03:04 UTC, aliak wrote: stripping the last line could result in an empty line if it just has strippable characters? The last line of the file is just text but without a newline (\n) character or any other whitespace character at the end. I get the same error when I remove the strip function from the readln line. There is *very* likely to be a terminating new-line at the end of the file (many editors add one without asking!). If that the case, the last line seen by the loop will be empty and you must not attempt to access any elements.
Re: Compiler/Phobos/Types problem — panic level due to timing.
On Sunday, 5 May 2019 at 18:53:08 UTC, Russel Winder wrote: Hi, I had merrily asumed I could implement nth Fibonacci number with: takeOne(drop(recurrence!((a, n) => a[n-1] + a[n-2])(zero, one), n)).front where zero and one are of type BigInt, and n is of type size_t. However both dmd and ldc2 complain saying: […] I am now at the WTF stage – how can I show this example on Thursday in my DevoxxUK presentation? I am close to giving up and imbibing of too much Pernod. `recurrence` takes the `CommonType` of the initial values and declares its internal state as an array of this type, however when at least one of the values is const or immutable, the `CommonType` is const too, or even immutable in the case when all values are immutable. The state being const/immutable means that the following step, initializing it, can't work, since, well, the array cannot be modified (hence the errors). I'd say this can be considered to be a bug with `recurrence`. You can solve this issue by constructing and passing mutable versions of `one` and `zero` to `recurrence`.
Re: == comparison of string literals, and their usage
On Saturday, 6 April 2019 at 15:35:22 UTC, diniz wrote: So, I still could store and use and compare string pointers myself [1], and get valid results, meaning: pointer equality implies (literal) string equality. Or am I wrong? The point is, the parser, operating on an array of prescanned lexemes, will constantly check whether a valid lexeme is present simply by checking the lexeme "class". I don't want that to be a real string comp, too expesensive and for no gain. [1] As in the second comp of your example: void main() { auto c2 = "one" == "two"; auto c1 = "one".ptr is "two".ptr; } Not quite. D-strings strictly consist of pointer *and* length, so you need to compare the .length properties as well to correctly conclude that the strings equal. You can concisely do that in one go by simply `is` comparing the array references as in string a = "hello"; string b = a; assert(a is b); assert(a[] is b[]); Of course, if the strings are never sliced, you can just compare the pointers and be done, just make sure to document how it operates. Depending on the circumstances I'd throw in some asserts that do actual strings comparison to verify the program logic.
Re: template with enum parameter doesn't compile
On Friday, 5 April 2019 at 14:47:42 UTC, Sjoerd Nijboer wrote: So the following code doesn't compile for some reason, and I can't figure out why. The error: Error: template instance `MyClass!(MyEnum)` does not match template declaration `MyClass(MyEnum myEnum)` pops up, no matter what I do. I'm quite puzzled actually You are just having a little issue with operator precedence there. Your code attempts to get the member `A` from `MyClass!MyEnum`, if you add braces around it, it'll work just fine `MyClass!(MyEnum.A)`.
Re: question about bitfields to decode websocket header
On Wednesday, 7 November 2018 at 13:05:49 UTC, test wrote: I am confused about the bitfields order. mixin(bitfields!( bool, "fin",1, bool, "rsv1", 1, bool, "rsv2", 1, bool, "rsv3", 1, Opcode, "opcode", 4, bool, "mask", 1, ubyte, "_size", 7, )); output for first byte is 1001 , the 2st byte 1011 my code output: opcode=8 mask=true size=65 the real size is 3 byte, and opcode is 1; how to fix this ? The bitfields start with the least significant bits: fin -> 1 rsv1 -> 0 rsv2 -> 0 rsv3 -> 0 opcode -> 1000 = 8 mask -> 1 _size -> 101 = 65 This order will likely be what you want: mixin(bitfields!( opcode, "opcode", 4, bool, "rsv3", 1, bool, "rsv2", 1, bool, "rsv1", 1, bool, "fin",1, ubyte, "_size", 7, bool, "mask", 1, )); Also beware of endianness when mapping bytes to it.
Re: Why use while if only iterating once ?
On Saturday, 3 November 2018 at 21:03:16 UTC, Venkat wrote: The last break statement prevents the loop from returned for a second iteration. Then why use a while ? The continue statement may abort the current iteration and start the next, causing the final break to not necessarily be executed every iteration.
Re: Struct template cannot deduce function from argument types
On Wednesday, 27 June 2018 at 16:19:56 UTC, Luka Aleksic wrote: […] I am getting the following error: scratch.d(14): Error: struct scratch.pair cannot deduce function from argument types !()(char, int), candidates are: scratch.d(2):scratch.pair(T, U) Failed: ["/usr/bin/dmd", "-v", "-o-", "scratch.d", "-I."] Changing the offending line to: pair!(char, uint) p1 = pair!(char, uint)('a', 1); fixes the issue. However I am interested to know why the first code couldn't deduce the types-- and why does it even have to try to deduce them, when I explicitly stated that p1 was of the type "pair of char and uint"? Thanks, L. Aleksic Type inference does not work for struct construction. There are some technical problems with allowing that, such as this() having the capability of being a separate template itself. Relevant issue tracker entry: https://issues.dlang.org/show_bug.cgi?id=6082 Your construction call does not work because the right hand side determines its type using only information present on the right hand side, in that sense you're not explicitly providing types at all. In order to still be able to make concise construction calls, you can define a factory function: struct Pair(A, B) { A a; B b; this(A a, B b) { this.a = a; this.b = b; } } Pair!(A, B) pair(A, B)(A a, B b) { return Pair!(A, B)(a, b); } void main() { auto p = pair(1, "test"); pragma(msg, typeof(p)); //Pair!(int, string) }
Re: For fun: Expressive C++ 17 Coding Challenge in D
On Wednesday, 4 October 2017 at 15:30:08 UTC, Ali Çehreli wrote: the hidden \r characters at the ends Those got me too! Here's my less than optimal solution: int main(string[] args) { import std.stdio; import std.algorithm.iteration : map, splitter, joiner, each; import std.algorithm.searching : countUntil; import std.range : enumerate; import std.string : chomp; if (args.length != 5 && args.length != 4) { stderr.writeln("Something went wrong and it's obviously your fault."); return 1; } immutable columnID = args[2]; immutable substitute = args[3]; auto data = File(args[1], "r").byLine.map!chomp; if (data.empty) { stderr.writeln("input file missing\n\n(actually it exists, it's just " ~ "empty)\n\n(your fault regardless)"); return 1; } File output; if (args.length == 5) output = File(args[4], "w"); else output = stdout; immutable matchedColumn = data.front.splitter(",").countUntil(columnID); if (matchedColumn < 0) { stderr.writeln("column name doesn’t exist in the input file\n\n(and " ~ "it's your fault)"); return 1; } output.writeln(data.front); data.popFront; data.map!(line => line .splitter(",") .enumerate .map!(a => a.index == matchedColumn ? substitute : a.value) .joiner(",")).each!(a => output.writeln(a)); return 0; } I think the biggest problem is the lack of support for quoted content.
Re: Array Printing
On Tuesday, 12 September 2017 at 06:29:53 UTC, Vino.B wrote: Hi All, Request your help in printing the below array output as per the below required output As a fan of stuffing as much as possible into one line: void main() { import std.stdio; import std.range; import std.algorithm.iteration; auto a = ["C:\\Temp\\TEST2\\BACKUP\\dir1", "34", "C:\\Temp\\TEST2\\BACKUP\\dir2", "36", "C:\\Temp\\TEST3\\BACKUP\\dir1", "69"]; auto b = ["C:\\Temp\\TEST2\\PROD_TEAM\\dir1", "34", "C:\\Temp\\TEST2\\PROD_TEAM\\DND1", "34"]; auto c = ["C:\\Temp\\TEST2\\TEAM\\DND1", "34"]; chain(a, b, c).chunks(2).each!(e => writefln!"%-60s %s"(e[0], e[1])); }
Re: string to character code hex string
On Saturday, 2 September 2017 at 17:41:34 UTC, Ali Çehreli wrote: You're right but I think there is no intention of interpreting the result as UTF-8. "f62026" is just to be used as "f62026", which can be converted byte-by-byte back to "ö…". That's how understand the requirement anyway. Ali That is not possible, because you cannot know whether "f620" and "26" or "f6" and "2026" (or any other combination) should form a code point each. Additional padding to constant width (8 hex chars) is needed.