Re: Expanding CTFE code during compilation
On Saturday, 23 July 2022 at 00:56:39 UTC, Steven Schveighoffer wrote: On 7/22/22 3:22 PM, Azi Hassan wrote: Oh, interesting syntax. I was thinking something along the lines of ```D template printEnum(...) { version(debug) { ... // everything we already did } else { enum printEnum(alias x) = x; } } ``` But I like yours better. `version(debug)` isn't valid syntax, `debug` is a keyword. -Steve I stand corrected, I must've got it confused with version(unittest)
Re: Expanding CTFE code during compilation
On Wednesday, 20 July 2022 at 14:11:52 UTC, Dennis wrote: On Wednesday, 20 July 2022 at 00:33:06 UTC, Azi Hassan wrote: Where did you find it though ? I checked dmd --help and man dmd before making this thread, but to no avail. It was implemented as an internal debugging tool, not a documented feature: https://github.com/dlang/dmd/pull/6556 It turned out to be useful for users as well though, and got exposure through the "AST" button on https://run.dlang.io/ Maybe it's time to document it, currently there's only this: https://wiki.dlang.org/DMD_Source_Guide#View_emitted_templates_instances_and_string.2Fmixins I see, thanks. I'll be sure to check the wiki next time.
Re: Expanding CTFE code during compilation
On Wednesday, 20 July 2022 at 01:15:44 UTC, Steven Schveighoffer wrote: On 7/19/22 8:57 PM, Steven Schveighoffer wrote: There's a slight bloat in the compiler symbol table when but other than that it should be effective. Obviously I didn't finish that thought... "when `-debug` isn't used on the command line" -Steve Oh, interesting syntax. I was thinking something along the lines of ```D template printEnum(...) { version(debug) { ... // everything we already did } else { enum printEnum(alias x) = x; } } ``` But I like yours better.
Re: Expanding CTFE code during compilation
On Tuesday, 19 July 2022 at 22:41:43 UTC, Steven Schveighoffer wrote: On 7/19/22 5:43 PM, Azi Hassan wrote: Just in case this is a consequence of the XY problem, the reason why I'm looking for this is to make sure that the code I wrote did evaluate to what I'm expecting it to. Right now I do this with an enum assignment followed by static asserts, but I'd love it for there to be some sort of visual feedback. Thanks in advance ```d template printEnum(alias x, string file = __FILE__, size_t line = __LINE__) { enum printEnum = x; pragma(msg, file, "(", int(line), "): ", printEnum); } enum x = printEnum!(iota(1, 5).reduce!"a * b"); ``` This will spit out the file, line, and value for the declaration. Assuming this is useful for your double-checking you could do this, and then switch it back when you have verified that it's correct. -Steve Nice, a compile time console.log. Thanks a lot, this will come in handy. I wonder if it can be combined with version(debug) to only run the pragma line if compiled with -g, this way we can keep the printEnum! line as it is. Then again, the code would become polluted by debugging logic
Re: Expanding CTFE code during compilation
On Tuesday, 19 July 2022 at 22:27:56 UTC, Dennis wrote: On Tuesday, 19 July 2022 at 21:43:01 UTC, Azi Hassan wrote: I'm wondering if the offers has the option of executing the parts that can be evaluated at compile time and then replacing them with the result of this evaluation. Try the `-vcg-ast` flag: ```D import object; import std; void main() { enum int x = 24; writeln(24); return 0; } // ... and a bunch of template instances ``` Thanks a lot, this is exactly what I had in mind. Where did you find it though ? I checked dmd --help and man dmd before making this thread, but to no avail.
Expanding CTFE code during compilation
Hello, Apologies in advance if this has been asked before. I can't find the right words to express what I'm looking for, but essentially, I'm wondering if the offers has the option of executing the parts that can be evaluated at compile time and then replacing them with the result of this evaluation. The C equivalent would be compiling with the -E flag as explained here : https://stackoverflow.com/questions/4900870/can-gcc-output-c-code-after-preprocessing For example : ``` //main.d import std; void main() { enum x = iota(1, 5).reduce!"a * b"; x.writeln(); } ``` Then after running something like ``` dmd --expand-ctfe main.d -o expanded.d cat expanded.d ``` We'd get : ``` //expanded.d import std; void main() { 24.writeln(); } ``` Just in case this is a consequence of the XY problem, the reason why I'm looking for this is to make sure that the code I wrote did evaluate to what I'm expecting it to. Right now I do this with an enum assignment followed by static asserts, but I'd love it for there to be some sort of visual feedback. Thanks in advance
Re: enforce (i > 0) for i = int.min does not throw
On Saturday, 27 January 2018 at 14:13:49 UTC, kdevel wrote: I would expect this code enforce3.d --- import std.exception; void main () { int i = int.min; enforce (i > 0); } --- to throw an "Enforcement failed" exception, but it doesn't: $ dmd enforce3.d $ ./enforce3 [nothing] I wonder if it's caused by a comparison between signed and unsigned integers. import std.stdio; void main () { int zero = 0; writeln(int.min > 0u); writeln(int.min > zero); } $ rdmd test.d true false The same behavior can be observed in C : #include #include int main(void) { int zero = 0; printf("%d\n", INT_MIN > 0u); printf("%d\n", INT_MIN > zero); return 0; } $ gcc test.c && ./a.out 1 0
Re: Struct initialization syntax
On Thursday, 18 January 2018 at 03:50:15 UTC, arturg wrote: On Wednesday, 17 January 2018 at 17:37:07 UTC, H. S. Teoh wrote: On Wed, Jan 17, 2018 at 05:31:03PM +, Azi Hassan via Digitalmars-d-learn wrote: The D tour for structs uses a syntax similar to that of C++ in order to initialize a Person struct : Person p(30, 180). Is this syntax supported in D ? Running that part of the code neither works on the playground nor on my machine (dmd v2.076.0). You're probably looking for this syntax: auto p = Person(30, 180); T looks like a bug in the 3rd example. That's what I was wondering about, thanks.
Struct initialization syntax
The D tour for structs uses a syntax similar to that of C++ in order to initialize a Person struct : Person p(30, 180). Is this syntax supported in D ? Running that part of the code neither works on the playground nor on my machine (dmd v2.076.0).
Re: AssocArray to string is ok,but how to get the AssocArray from string? Thanks
On Tuesday, 12 December 2017 at 17:32:15 UTC, Frank Like wrote: Hi,everyone, who can help me,about the "AssocArray to string is ok,but how to get the AssocArray from string? ". For example: SysTime[][string] AATimes; AATimes["a1"] =[SysTime(DateTime(2017, 1, 1, 12, 33, 33)),SysTime(DateTime(2017, 1, 2, 12, 33, 33))]; AATimes["a2"] =[SysTime(DateTime(2017, 1, 2, 12, 33, 33)),SysTime(DateTime(2017, 1, 3, 12, 33, 33))]; ubyte[] ua = cast(ubyte[])AATimes.to!string; writeln("ua is ",ua); string strTimes = cast(string)ua; writeln("strTimes is ",strTimes); But now,how to get the AATimes from string? Thanks. Frank. Serialization seems to be the answer. Unfortunately I could neither get it to work with Cereal nor with Orange. If all else fails, you could still attempt to manually parse it ot of its string representation (AATimes.to!string).
Re: Get pointer or reference of an element in Array(struct)
On Saturday, 9 December 2017 at 06:46:27 UTC, Arun Chandrasekaran wrote: On Saturday, 9 December 2017 at 06:38:46 UTC, anonymous wrote: On Saturday, 9 December 2017 at 06:15:16 UTC, Arun Chandrasekaran wrote: Is there a way to get the pointer or reference of an element in Array(T)? [...] auto d2 = gallery[0]; auto d2 = [0]; Thanks. Just curious why reference can't be obtained here. Saves nasty null checks in most places. In D, structs are passed by value unless otherwise specified. Using a class will yield the expected result.
Re: What the hell is wrong with D?
A general rule of thumb when it comes to operator precedence is that when in doubt, add parenthesis. On Wednesday, 20 September 2017 at 02:16:16 UTC, EntangledQuanta wrote: Your an idiot, Your Huh.
Re: Binary serialization of a struct
On Saturday, 16 September 2017 at 03:30:51 UTC, Joseph wrote: Are there any simple direct serialization libraries where I can mark elements of a class or struct that I want serialized with an attribute and it will take care of all the rest(including recursive structures, arrays, etc) then deserialize back in to the structs? I want something straight forward without allot of plumbing on my end. Have you checked Cerealed ? From the looks of it, it supports a @NoCereal attribute which does the opposite of what you're looking for. Not sure how it handles nested structs, but there are examples in the test/directory : https://github.com/atilaneves/cerealed/
Re: Ranges seem awkward to work with
On Tuesday, 12 September 2017 at 01:13:29 UTC, Hasen Judy wrote: Now, a lot of library functions seem to expect ranges as inputs and return ranges as output. Unless I'm mistaken, it was done on purpose to reduce the amount of memory allocations in the standard library so that it becomes @nogc-friendly. But yes, you can use std.array.array to turn it into an array, but keep in mind that it does allocate so you might need to watch out if you're dealing with large CSV files.
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 Array Output: ["C:\\Temp\\TEST2\\BACKUP\\dir1", "34", "C:\\Temp\\TEST2\\BACKUP\\dir2", "36", "C:\\Temp\\TEST3\\BACKUP\\dir1", "69"] ["C:\\Temp\\TEST2\\PROD_TEAM\\dir1", "34", "C:\\Temp\\TEST2\\PROD_TEAM\\DND1", "34"] ["C:\\Temp\\TEST2\\TEAM\\DND1", "34"] Required output: C:\Temp\TEST2\BACKUP\dir1 34 C:\Temp\TEST2\BACKUP\dir2 36 C:\Temp\TEST3\BACKUP\\dir1 69 C:\Temp\TEST2\PROD_TEAM\\dir1 34 C:\Temp\TEST2\PROD_TEAM\\DND1 34 C:\Temp\TEST2\TEAM\\DND134 From, Vino.B You can also use leftJustifier (or the eager version, leftJustify) from std.string to make the output formatted like that : import std.stdio; import std.string; import std.range; void main() { auto a1 = ["C:\\Temp\\TEST2\\BACKUP\\dir1", "34", "C:\\Temp\\TEST2\\BACKUP\\dir2", "36", "C:\\Temp\\TEST3\\BACKUP\\dir1", "69"]; auto a2 = ["C:\\Temp\\TEST2\\PROD_TEAM\\dir1", "34", "C:\\Temp\\TEST2\\PROD_TEAM\\DND1", "34"]; auto a3 = ["C:\\Temp\\TEST2\\TEAM\\DND1", "34"]; a1.print; a2.print; a3.print; } void print(string[] array) { foreach(i; iota(0, array.length, 2)) writeln(array[i].leftJustifier(60, ' '), array[i + 1]); } Output : C:\Temp\TEST2\BACKUP\dir1 34 C:\Temp\TEST2\BACKUP\dir2 36 C:\Temp\TEST3\BACKUP\dir1 69 C:\Temp\TEST2\PROD_TEAM\dir134 C:\Temp\TEST2\PROD_TEAM\DND134 C:\Temp\TEST2\TEAM\DND1 34
Re: Performance Issue
On Wednesday, 6 September 2017 at 18:21:44 UTC, Azi Hassan wrote: I tried to create a similar file structure on my Linux machine. Here's the result of ls -R TEST1: TEST1: BACKUP ... Upon further inspection it looks like I messed up the output. [31460] - Array 1 for folder 1(all files in Folder 1) of the FS C:\\Temp\\TEST1\\BACKUP [138] - Array 2 for folder 2(all files in Folder 2) of the FS C:\\Temp\\TEST1\\BACKUP [2277663, 2277663] - Array 3 for folder 1(all files in Folder 1) of the FS C:\\Temp\\TEST2\\EXPOR [31460] - Array 4 for folder 2(all files in Folder 2) the FS C:\\Temp\\TEST2\\EXPORT What files do these sizes correspond to ? Shouldn't there be two elements in the first array because C:\Temp\TEST1\BACKUP\FOLDER1 contains two files ?
Re: Performance Issue
On Wednesday, 6 September 2017 at 15:11:57 UTC, Vino.B wrote: On Wednesday, 6 September 2017 at 14:38:39 UTC, Vino.B wrote: Hi Azi, The required out is like below [31460] - Array 1 for folder 1(all files in Folder 1) of the FS C:\\Temp\\TEST1\\BACKUP [138] - Array 2 for folder 2(all files in Folder 2) of the FS C:\\Temp\\TEST1\\BACKUP [2277663, 2277663] - Array 3 for folder 1(all files in Folder 1) of the FS C:\\Temp\\TEST2\\EXPOR [31460] - Array 4 for folder 2(all files in Folder 2) the FS C:\\Temp\\TEST2\\EXPORT I tried to create a similar file structure on my Linux machine. Here's the result of ls -R TEST1: TEST1: BACKUP TEST1/BACKUP: FOLDER1 FOLDER2 TEST1/BACKUP/FOLDER1: file1 file2 file3 TEST1/BACKUP/FOLDER2: b1 b2 And here's the output of ls -R TEST2 : TEST2: EXPORT TEST2/EXPORT: FOLDER1 FOLDER2 TEST2/EXPORT/FOLDER1: file2_1 file2_2 file2_3 TEST2/EXPORT/FOLDER2: export1 export2 export3 export4 This codes output the sizes in the format you described : import std.algorithm: filter, map, fold, each; import std.parallelism: parallel; import std.file: SpanMode, dirEntries, DirEntry; import std.stdio: writeln; import std.typecons: tuple; import std.path: globMatch; import std.array; void main () { auto Filesys = ["TEST1/BACKUP", "TEST2/EXPORT"]; ulong[][] sizes; foreach(FFs; Filesys) { auto dFiles = dirEntries(FFs, SpanMode.shallow).filter!(a => a.isDir).map!(a => a.name); foreach (d; dFiles) { sizes ~= dirEntries(d, SpanMode.depth).map!(a => a.size).array; } } sizes.each!writeln; } It outputs the sizes : [6, 6, 6] [8, 8] [8, 8, 8] [9, 9, 9, 9] Note that there's no need to store them in ulong[][] sizes, you can display them inside the loop by replacing `sizes ~= dirEntries(d, SpanMode.depth).map!(a => a.size).array;` with `dirEntries(d, SpanMode.depth).map!(a => a.size).joiner(", ").writeln;` To make sure that it calculates the correct sizes, I made it display the paths instead by making "sizes" string[][] instead of ulong[][] and by replacing map!(a => a.size) with map!(a => a.name) in the second foreach loop : import std.algorithm: filter, map, each; import std.file: SpanMode, dirEntries, DirEntry; import std.stdio: writeln; import std.array : array; void main () { auto Filesys = ["TEST1/BACKUP", "TEST2/EXPORT"]; string[][] sizes; foreach(FFs; Filesys) { auto dFiles = dirEntries(FFs, SpanMode.shallow).filter!(a => a.isDir).map!(a => a.name); foreach (d; dFiles) { sizes ~= dirEntries(d, SpanMode.depth).map!(a => a.name).array; } } sizes.each!writeln; } It outputs the paths as expected : ["TEST1/BACKUP/FOLDER1/file1", "TEST1/BACKUP/FOLDER1/file2", "TEST1/BACKUP/FOLDER1/file3"] ["TEST1/BACKUP/FOLDER2/b1", "TEST1/BACKUP/FOLDER2/b2"] ["TEST2/EXPORT/FOLDER1/file2_3", "TEST2/EXPORT/FOLDER1/file2_1", "TEST2/EXPORT/FOLDER1/file2_2"] ["TEST2/EXPORT/FOLDER2/export2", "TEST2/EXPORT/FOLDER2/export3", "TEST2/EXPORT/FOLDER2/export1", "TEST2/EXPORT/FOLDER2/export4"]
Re: Performance Issue
On Wednesday, 6 September 2017 at 08:10:35 UTC, Vino.B wrote: in the next line of the code i say to list only folders that are greater than 10 Mb but this now is listing all folder (folder whose size is less than 10 MB are getting listed, not sure why. Is the size in GB ? If so, then subdirTotalGB = (subdirTotal/1024/1024); needs to become subdirTotalGB = (subdirTotal/1024/1024/1024); for it to take effect. But do correct me if I'm wrong, I still haven't had my morning coffee.
Re: Problem with std.string.strip(): Can't use result in format routine
On Tuesday, 5 September 2017 at 12:38:54 UTC, Ky-Anh Huynh wrote: Hi, I read line from STDIN , and strip them [code] auto line_st = line.strip(); [/code] However, I can't use result in another format routine. Assume my input line is "foobar": [code] writeln("Stripped line is %s", line_st); [/code] This code only prints "Stripped line is ". If I use instead [code] writeln("Stripped line is %s", line.strip()); [/code] the result is "Stripped line is foobar". What're the difference between the two uses? I'm using `dmd v2.075.1`. Thanks a lot. Maybe it has something to do with how you read from STDIN. Can you show that part of the code to see if I can reproduce the issue ?
Struct with float members in betterC
Hi, I'm trying to create the following struct in betterC but I keep getting undefined reference errors when I try to compile the code : import core.stdc.stdio; struct Foo { float x; float y; float z; }; extern(C) int main(int argc, char** argv) { /*auto foo = Foo(10, 2.0, 3.0); printf("%f %f %f\n", foo.x, foo.y, foo.z);*/ puts("foo"); return 0; } Note that the mere presence of such a struct causes the compilation to fail. The same problem occurs with a single float member, or with double members. $ dmd -betterC structbug.d structbug.o:(.data._D13TypeInfo_xAya6__initZ+0x0) : référence indéfinie vers « _D14TypeInfo_Const6__vtblZ » structbug.o:(.data._D13TypeInfo_xAya6__initZ+0x8) : référence indéfinie vers « _D12TypeInfo_Aya6__initZ » collect2: error: ld returned 1 exit status Error: linker exited with status 1 I'm aware that betterC is still experimental at this point, but I thought I'd ask here to make sure it is indeed a bug before filing a bug report. Thanks in advance.
Re: Performance Issue
On Tuesday, 5 September 2017 at 09:44:09 UTC, Vino.B wrote: Hi, The below code is consume more memory and slower can you provide your suggestion on how to over come these issues. You can start by dropping the .array conversions after dirEntries. That way your algorithm will become lazy (as opposed to eager), meaning that it won't allocate an entire array of DirEntry[]. It will, instead, treat the DirEntries one at a time, resulting in less memory consumption. I didn't understand the join(["?\\", d[0]]) part, maybe you meant to write join("?\\", d[0]) ? If appender is too slow, you can experiment with a dynamic array whose capacity was preallocated : string[][] Subdata; Subdata.reserve(1); In this case Subdata will hold enough space for 1 string[]s, which will result in better performance. Here's the updated code (sans .array) in case any one wants to reproduce the issue : import std.stdio; import std.conv; import std.typecons; import std.array; import std.path; import std.container; import std.file; import std.parallelism; import std.algorithm; void main() { ".".csizeDirList(1024).each!writeln; } string[][] csizeDirList (string FFs, int SizeDir) { ulong subdirTotal = 0; ulong subdirTotalGB; auto Subdata = appender!(string[][]); auto dFiles = dirEntries(FFs, SpanMode.shallow) .filter!(a => a.isDir && !globMatch(a.baseName, "*DND*")) .map!(a => tuple(a.name, a.size)); foreach (d; dFiles) { auto SdFiles = dirEntries(join(["?\\", d[0]]), SpanMode.depth) .map!(a => tuple(a.size)); foreach (f; parallel(SdFiles,1)) { subdirTotal += f[0]; } subdirTotalGB = (subdirTotal/1024/1024); if (subdirTotalGB > SizeDir) { Subdata ~= [d[0], to!string(subdirTotalGB)]; } subdirTotal = 0; } return Subdata.data; }
Re: Using closure causes GC allocation
On Monday, 4 September 2017 at 05:45:18 UTC, Vino.B wrote: In order to resolve the issue "Using closure causes GC allocation" it was stated that we need to use delegates Alternatively you can drop the functional style and use a foreach loop that doesn't require delegates, but you'd still need the GC to store the result in an array. And even then you could still use Array (from std.container).
Re: Returning multiple values from a function
On Monday, 4 September 2017 at 09:22:25 UTC, Vino.B wrote: Output : 1 2 ["C:\\Temp\\TEAM1\\BACKUP", "C:\\Temp\\TEAM2\\ARCHIVE"] Required Output: Test1 = 1 Test2 = 2 Path = ["C:\\Temp\\TEAM1\\BACKUP", "C:\\Temp\\TEAM2\\ARCHIVE"] From, Vino.B If you just need it to be displayed then you can add it to the writeln call : writeln("Test 1 = ", Params[0]); But if you want to do it dynamically then maybe you should be using an associative array or a tuple of tuples : import std.stdio; import std.array; import std.typecons; alias Result = Tuple!( Tuple!(string, int), Tuple!(string, int), Tuple!(string, string[]) ); Result Params () { int Test1; int Test2; string[] File1; string[] File2; auto Path = appender!(string[]); //string[] path; path.reserve(2) ? Test1 = 1; Test2 = 2; File1 = ["C:\\Temp\\TEAM1\\BACKUP"]; File2 = ["C:\\Temp\\TEAM2\\ARCHIVE"]; Path ~= File1; Path ~= File2; return tuple( tuple("Test1", Test1), tuple("Test2", Test2), tuple("Path", Path.data) ); } void main (){ auto res = Params(); writeln(res[0][0], " = ", res[0][1]); writeln(res[1][0], " = ", res[1][1]); writeln(res[2][0], " = ", res[2][1]); } You can also loop through res : void main (){ auto res = Params(); foreach(r; res) writeln(r[0], " = ", r[1]); }
Re: -betterC not working
On Friday, 1 September 2017 at 22:13:53 UTC, SrMordred wrote: On Wednesday, 30 August 2017 at 23:12:07 UTC, SrMordred wrote: On Wednesday, 30 August 2017 at 22:45:27 UTC, Adam D. Ruppe wrote: On Wednesday, 30 August 2017 at 22:18:07 UTC, SrMordred wrote: DMD64 D Compiler v2.075.1 -betterC as described recently is not yet released. https://dlang.org/changelog/2.076.0_pre.html is where it gets the new behavior, and that isn't scheduled for formal release until the end of the week. (it seriously bothers me that Walter has been advertising this so much when the little bit that is implemented isn't even released yet, and what is implemented is barely usable.) The betterC switch itself is not new, but it does virtually nothing until that latest prerelease compiler. ooops, little missed detail ;) At least its near. Hello again. Downloaded last version. //fail at my example, so its working as intended dmd -betterC source/app.d app.d //compiles. so problem with dub only dub run --config=application --arch=x86_64 --build=debug --compiler=dmd Running dub run with --verbose indicates that dub is actually running both the "dmd -g -c -betterC source/app.d -ofd_betterc.o" and the "dmd -ofd_betterc d_betterc.o -g" commands. Note that the second dmd call doesn't include the -betterC flag. Running the second dmd command manually with the -betterC flag does give the expected undefined reference errors.
Re: Help required on Array appender
On Saturday, 2 September 2017 at 12:54:48 UTC, Nicholas Wilson wrote: If you're wanting to use appender just make an appender and replace the ~= to calls to appender.put(data); Just making Subdata an Appender!(string[][]) (or Appender!(Tuple!(string, string)[])) is enough since it already overloads the ~= operator. Performance aside, a small nitpick is that it's possible to write filter!isFile instead of filter!(a => a.isFile) since isFile only accepts one argument.