Re: What's the proper way to use std.getopt?
On Wednesday, December 13, 2017 06:55:46 bauss via Digitalmars-d-learn wrote: > On Tuesday, 12 December 2017 at 18:34:26 UTC, Mike Wey wrote: > > On 12-12-17 00:35, Seb wrote: > >> D style would be to use sth. like this (instead of try/catch): > >> > >> ``` > >> scope(failure) { > >> > >>e.msg.writeln; > >>1.exit; > >> > >> } > >> ``` > > > > I might have missed something, but where is `e` defined in this > > case? > > I was thinking the same and can't find anything in the > documentation that states you can retrieve the exception that > caused the failure by an "e" variable. > > All I could find is that in case you need to use the exception > you'd have to do a try/catch. > > So ultimately that code wouldn't work, according to the language > specs. > > I haven't tested it, so I don't know if it's some hidden feature, > but if it is, then I'm against it. If it works, it's a bug related to code lowering (since scope statements are always lowered to try-catch-finally blocks). You're not supposed to have access to the exception in a scope statement. - Jonathan M Davis
Re: Date Formating
On Wednesday, December 13, 2017 02:34:12 codephantom via Digitalmars-d-learn wrote: > On Tuesday, 12 December 2017 at 15:56:59 UTC, Vino wrote: > > Hi All, > > > > Request out help on date formatting, I have code which output > > > > the date and time as below , i we need it without the last few > > numbers.,ie "-MMM-DD HH:MM:SI" > > > > Output : 2017-Sep-06 16:06:42.7223837 > > Required Output : 2017-Sep-06 16:06:42 > > > > From, > > Vino.B > > just playing with this... > > // -- > > module test; > > void main() > { > import std.stdio; > > writeln( GetFmtDate() ); // e.g: 2017-Dec-13 13:30:23 > > } > > > string GetFmtDate() > { > import std.datetime; > import std.ascii : toUpper; > import std.conv : to; > import std.string : format; > > auto d = Clock.currTime(); > > string fmtMonth = toUpper(to!string(d.month)[0]) ~ >to!string(d.month)[1..$]; > > return > format("%04s-%s-%02s %02s:%02s:%02s", > (d.year), > fmtMonth, > (d.day), > (d.hour), > (d.minute), > (d.second) > ); > } > > // -- In general, you probably want to cast the SysTime to a DateTime if you're going to do something like that. There's a lot of duplicate work being done if you get each of those properties individually, whereas if you cast to DateTime, then it does the work once, and the properties for DateTime just return the correspending member variables. Sometimes, I think that putting year, month, etc. on SysTime was a mistake, because using thoes properties almost always the wrong thing to do given how much work is duplicated when using them, but at the same time, there are cases where the efficiency doesn't really matter and the simplicity of just grabbing the properties from SysTime is nice. - Jonathan M Davis
Re: What's the proper way to use std.getopt?
On Tuesday, 12 December 2017 at 18:34:26 UTC, Mike Wey wrote: On 12-12-17 00:35, Seb wrote: D style would be to use sth. like this (instead of try/catch): ``` scope(failure) { e.msg.writeln; 1.exit; } ``` I might have missed something, but where is `e` defined in this case? I was thinking the same and can't find anything in the documentation that states you can retrieve the exception that caused the failure by an "e" variable. All I could find is that in case you need to use the exception you'd have to do a try/catch. So ultimately that code wouldn't work, according to the language specs. I haven't tested it, so I don't know if it's some hidden feature, but if it is, then I'm against it.
Re: how would I go about creating a Socket receiveAll method?
On 12/12/2017 10:21 PM, bauss wrote: > On Tuesday, 12 December 2017 at 22:11:37 UTC, Adam D. Ruppe wrote: >> On Tuesday, 12 December 2017 at 21:52:57 UTC, Ali Çehreli wrote: >>> The same buffer is used for all segments and socket.receive should be >>> inside while. >> >> The buffer is copied by the ~= operator, but indeed you're right that >> I forgot to receive again inside the loop! That would just spin until >> it ran out of memory lol. >> >> But I did put receive outside the loop for a reason: it just needs to >> prime the return value before it gets checked the first time. But >> then, of course, it should receive again at the end of the loop to >> advance to the next chunk. > > do while would work better. It's a bummer that the loop variable must be defined outside of do-while: bool done = false;// Can't be inside do { // ... } while(!done); That's why I think an unconditional loop with an explicit break is better in such situations: while (true) { // ... everything inside ... if (!got) { break; } // ... } Here is a short program that I played with: import std.stdio; import std.range; import std.algorithm; int[] makeData(int len) { return iota(len).array; } struct SomeSource { int[] data; this(int len) { this.data = makeData(len); } // Alternatively, this can return int[] size_t read(int[] buffer) { const len = min(data.length, buffer.length); buffer[0..len] = data[0..len]; data = data[len..$];// Alternatively, popFrontN return len; } } void main() { enum len = 50; auto foo = SomeSource(len); int[] result; while (true) {// <-- UNCONDITIONAL LOOP int[17] buffer; const got = foo.read(buffer[]); if (!got) { break; } result ~= buffer[0..got]; } assert(result == makeData(len)); writeln(result); } Ali
Re: how would I go about creating a Socket receiveAll method?
On Tuesday, 12 December 2017 at 22:11:37 UTC, Adam D. Ruppe wrote: On Tuesday, 12 December 2017 at 21:52:57 UTC, Ali Çehreli wrote: The same buffer is used for all segments and socket.receive should be inside while. The buffer is copied by the ~= operator, but indeed you're right that I forgot to receive again inside the loop! That would just spin until it ran out of memory lol. But I did put receive outside the loop for a reason: it just needs to prime the return value before it gets checked the first time. But then, of course, it should receive again at the end of the loop to advance to the next chunk. do while would work better.
Re: Understanding how dub works
On Tuesday, 12 December 2017 at 22:20:41 UTC, datboi wrote: Hi, I'm learning D (obliviously) learning D in an oblivious manner can be difficult ;-)
Re: Date Formating
On Tuesday, 12 December 2017 at 15:56:59 UTC, Vino wrote: Hi All, Request out help on date formatting, I have code which output the date and time as below , i we need it without the last few numbers.,ie "-MMM-DD HH:MM:SI" Output : 2017-Sep-06 16:06:42.7223837 Required Output : 2017-Sep-06 16:06:42 From, Vino.B just playing with this... // -- module test; void main() { import std.stdio; writeln( GetFmtDate() ); // e.g: 2017-Dec-13 13:30:23 } string GetFmtDate() { import std.datetime; import std.ascii : toUpper; import std.conv : to; import std.string : format; auto d = Clock.currTime(); string fmtMonth = toUpper(to!string(d.month)[0]) ~ to!string(d.month)[1..$]; return format("%04s-%s-%02s %02s:%02s:%02s", (d.year), fmtMonth, (d.day), (d.hour), (d.minute), (d.second) ); } // --
Re: Date Formating
On Tuesday, December 12, 2017 15:56:59 Vino via Digitalmars-d-learn wrote: > Hi All, > >Request out help on date formatting, I have code which output > the date and time as below , i we need it without the last few > numbers.,ie "-MMM-DD HH:MM:SI" > > Output : 2017-Sep-06 16:06:42.7223837 > Required Output : 2017-Sep-06 16:06:42 If you want to strip off the fractional seconds, then just zero them out. e.g. sysTime.fracSecs = Duration.zero; The to*String functions of SysTime don't display trailing zeroes and don't display the decimal point if the fractional seconds are zero. - Jonathan M Davis
Re: Understanding how dub works
On Wednesday, 13 December 2017 at 00:43:31 UTC, rikki cattermole wrote: You don't need to change this and if you think you do, you're wrong :) Except when you need to: https://github.com/dlang/dub/issues/1305 dub build --compiler=ldmd2 overwrites files in ~/.dub written by dub build #1305
Re: Understanding how dub works
On 12/12/2017 10:20 PM, datboi wrote: Hi, I'm learning D (obliviously) and I can't understand how exactly dependencies work. I haven't found answers to my questions in documentation (or i did't understand it), so can someone answer to mine questions? 1. Does dub compile dependencies as separate binaries? And if yes how to specify where should be they placed? Object/static files, but yes. Where they go: Windows: %APPDATA%/roaming/dub Posix: ~/.dub You don't need to change this and if you think you do, you're wrong :) 2. It is possible to compile subpackage as a dynamic or static library and link it to main binary file? Or just better create separate dub package and use it as dependency? Static yes, dynamic it won't link against (some bug last I heard). Have to do that manually. "dependencies": { "mypackage:subpackage": "*" } Change as required for SDL.
Re: What's the proper way to use std.getopt?
On Tuesday, 12 December 2017 at 20:57:28 UTC, Jon Degenhardt wrote: On Monday, 11 December 2017 at 20:58:25 UTC, Jordi Gutiérrez Hermoso wrote: What's the proper style, then? Can someone show me a good example of how to use getopt and the docstring it automatically generates? [snip] See: https://github.com/eBay/tsv-utils-dlang/blob/master/tsv-sample/src/tsv-sample.d Oh, thanks! This is more or less what I wanted. I suppose showing all of the docstring when the arguments are bad is possibly stupid and I shouldn't be doing that to begin with. I'll adopt this style to only show which argument was bad.
Understanding how dub works
Hi, I'm learning D (obliviously) and I can't understand how exactly dependencies work. I haven't found answers to my questions in documentation (or i did't understand it), so can someone answer to mine questions? 1. Does dub compile dependencies as separate binaries? And if yes how to specify where should be they placed? 2. It is possible to compile subpackage as a dynamic or static library and link it to main binary file? Or just better create separate dub package and use it as dependency? For all answers thank You in advance. Also sorry for mine English. I'm still learning it. So if I made some grammatic mistakes point them :)
Re: how would I go about creating a Socket receiveAll method?
On Tuesday, 12 December 2017 at 21:52:57 UTC, Ali Çehreli wrote: The same buffer is used for all segments and socket.receive should be inside while. The buffer is copied by the ~= operator, but indeed you're right that I forgot to receive again inside the loop! That would just spin until it ran out of memory lol. But I did put receive outside the loop for a reason: it just needs to prime the return value before it gets checked the first time. But then, of course, it should receive again at the end of the loop to advance to the next chunk.
Re: how would I go about creating a Socket receiveAll method?
On 12/12/2017 01:52 PM, Ali Çehreli wrote: > > ubyte[] result; > > ubyte[1024] buffer; > > result ~= buffer[0 .. got]; > The same buffer is used for all segments Not! Ok, I better go take a nap. :) Ali
Re: how would I go about creating a Socket receiveAll method?
On 12/12/2017 01:14 PM, Adam D. Ruppe wrote: > On Tuesday, 12 December 2017 at 21:03:54 UTC, Unazed Spectaculum wrote: >> I've decided to go for the run-time approach to this, it works fine >> with all of my tests so you have my greatest gratitude. > > the way I'd do it btw is simply: I know you normally do it much better. :) > ubyte[] result; > ubyte[1024] buffer; > auto got = socket.receive(buffer[]); > while(got > 0) { > result ~= buffer[0 .. got]; > } There are a couple of bugs in that code. The same buffer is used for all segments and socket.receive should be inside while. Ali
Re: how would I go about creating a Socket receiveAll method?
On Tuesday, 12 December 2017 at 21:14:30 UTC, Adam D. Ruppe wrote: On Tuesday, 12 December 2017 at 21:03:54 UTC, Unazed Spectaculum wrote: I've decided to go for the run-time approach to this, it works fine with all of my tests so you have my greatest gratitude. the way I'd do it btw is simply: ubyte[] result; ubyte[1024] buffer; auto got = socket.receive(buffer[]); while(got > 0) { result ~= buffer[0 .. got]; } if(got < 0) throw new Exception(lastSocketError()); return result; so it uses the one static buffer to receive the stuff one block at a time but just copies it over to the dynamic array with the ~= operator Oh, thanks; it's definitely shorter however I do enjoy the ability to generalize/ambiguate functions by providing optional parameters, however thanks for showing another way; I enjoy knowing multiple ways of performing one task so anything helps :)
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: how would I go about creating a Socket receiveAll method?
On Tuesday, 12 December 2017 at 21:03:54 UTC, Unazed Spectaculum wrote: I've decided to go for the run-time approach to this, it works fine with all of my tests so you have my greatest gratitude. the way I'd do it btw is simply: ubyte[] result; ubyte[1024] buffer; auto got = socket.receive(buffer[]); while(got > 0) { result ~= buffer[0 .. got]; } if(got < 0) throw new Exception(lastSocketError()); return result; so it uses the one static buffer to receive the stuff one block at a time but just copies it over to the dynamic array with the ~= operator
Re: how would I go about creating a Socket receiveAll method?
On Tuesday, 12 December 2017 at 20:27:04 UTC, Ali Çehreli wrote: On 12/12/2017 12:10 PM, Unazed Spectaculum wrote: > string receiveAll(T)(T socket, int segment_size = 1024) > { > char[segment_size][] data; Unrelated, you most likely want to use ubyte. (char is for UTF-8.) The problem is, char[segment_size] is a static array, where the length must be known at compile time because length is a part of its type. So, depending on what you need you have two options: a) Use dynamic array if the length is known at run time b) Although (a) will work just fine, use template parameter for length if the length is known at compile time and you want to avoid dynamic allocation. However, too large arrays won't fit on the stack. (Further however, your 'data' is a slice anyway, just the elements are static.) The following program shows the two options with one-dimensional arrays: // Size is known at run time void foo(T)(T t, size_t size = 1024) { auto data = new ubyte[](size); } // Size is known at compile time void bar(size_t size = 1024, T)(T t) { ubyte[size] data; } void main() { int i; foo(i, 10); bar!20(i); } Here is one with two-dimensional arrays: import std.stdio; size_t counter = 0; bool done() { return (++counter % 4) == 0; } // Size is known at run time void foo(T)(T t, size_t size = 1024) { ubyte[][] data; while (!done) { data ~= new ubyte[size]; // Use data[$-1] writeln("a) Will read here: ", data[$-1]); } } // Size is known at compile time void bar(size_t size = 1024, T)(T t) { ubyte[size][] data; while (!done) { ++data.length; writeln("b) Will read here: ", data[$-1]); } } void main() { int i; foo(i, 10); bar!20(i); } Ali string receiveAll(T)(T socket, size_t segment_size = 1024) { ubyte[][] data; size_t count = 0; while (true) { data ~= new ubyte[segment_size]; auto received = socket.receive(data[count]); data[count] = data[count][0 .. received]; if (!received) break; else if (received < segment_size) break; /* early exit */ ++count; } char[] stringData; foreach (elem; data) stringData ~= elem; return to!string(stringData); } I've decided to go for the run-time approach to this, it works fine with all of my tests so you have my greatest gratitude. I might have created some weird inefficiencies but don't worry take time telling me about them unless they're going to blow up my program since I think you've explained enough already :D. Since I'm only a few days into D I wouldn't expect much of my code, I'm moreover from the generic Python and thereabouts C-ish background. again, thanks.
Re: What's the proper way to use std.getopt?
On Monday, 11 December 2017 at 20:58:25 UTC, Jordi Gutiérrez Hermoso wrote: What's the proper style, then? Can someone show me a good example of how to use getopt and the docstring it automatically generates? The command line tools I published use the approach described in a number of the replies, but with a tad more structure. It's hardly perfect, but may be useful if you want more examples. See: https://github.com/eBay/tsv-utils-dlang/blob/master/tsv-sample/src/tsv-sample.d. See the main() routine and the TsvSampleOptions struct. Most of the tools have a similar pattern. --Jon
Re: Why is there no std.stream anymore?
On 12/11/17 6:33 PM, Seb wrote: Though if you need superb performance, iopipe or similar will be faster. Since iopipe was mentioned several times, I will say a couple things: 1. iopipe is not made for processing one element at a time, it focuses on buffers. The reason for this is because certain tasks (i.e. parsing) are much more efficient with buffered data than when using the range API. Even with FILE *, using fgetc for every character is going to suck when compared to fread, and processing the resulting array in-memory. 2. If you do want to process by element, I recommend the following chain: // an example that uses iopipe's file stream and assumes it's UTF8 text. // other mechanisms are available. auto mypipe = openDev("somefile") // open a file .bufd // buffer it .assumeText // assume it's utf-8 text .ensureDecodeable;// ensure there are no partial code-points in the window // convert to range of "chunks", and then join into one large range foreach(c; mypipe.asInputRange.joiner) { process(c); } Note, due to Phobos's auto-decoding, joiner is going to auto-decode all of the data. This means typeof(c) is going to be dchar, and not char, and everything needs to be proper utf-8. If you want to process the bytes raw, you can omit the .assumeText.ensureDecodeable part, and the data will be ubytes. -Steve
Re: Date Formating
On 12/12/17 10:56 AM, Vino wrote: Hi All, Request out help on date formatting, I have code which output the date and time as below , i we need it without the last few numbers.,ie "-MMM-DD HH:MM:SI" Output : 2017-Sep-06 16:06:42.7223837 Required Output : 2017-Sep-06 16:06:42 You need to extract the date components and print them separately. There is no mechanism to format a SysTime (and it's a hairy subject to be sure, every locale is different). -Steve
Re: how would I go about creating a Socket receiveAll method?
On 12/12/2017 12:10 PM, Unazed Spectaculum wrote: > string receiveAll(T)(T socket, int segment_size = 1024) > { > char[segment_size][] data; Unrelated, you most likely want to use ubyte. (char is for UTF-8.) The problem is, char[segment_size] is a static array, where the length must be known at compile time because length is a part of its type. So, depending on what you need you have two options: a) Use dynamic array if the length is known at run time b) Although (a) will work just fine, use template parameter for length if the length is known at compile time and you want to avoid dynamic allocation. However, too large arrays won't fit on the stack. (Further however, your 'data' is a slice anyway, just the elements are static.) The following program shows the two options with one-dimensional arrays: // Size is known at run time void foo(T)(T t, size_t size = 1024) { auto data = new ubyte[](size); } // Size is known at compile time void bar(size_t size = 1024, T)(T t) { ubyte[size] data; } void main() { int i; foo(i, 10); bar!20(i); } Here is one with two-dimensional arrays: import std.stdio; size_t counter = 0; bool done() { return (++counter % 4) == 0; } // Size is known at run time void foo(T)(T t, size_t size = 1024) { ubyte[][] data; while (!done) { data ~= new ubyte[size]; // Use data[$-1] writeln("a) Will read here: ", data[$-1]); } } // Size is known at compile time void bar(size_t size = 1024, T)(T t) { ubyte[size][] data; while (!done) { ++data.length; writeln("b) Will read here: ", data[$-1]); } } void main() { int i; foo(i, 10); bar!20(i); } Ali
how would I go about creating a Socket receiveAll method?
string receiveAll(T)(T socket, int segment_size = 1024) { char[segment_size][] data; int cnt = 0; while(true) { auto received = socket.receive(data[cnt]); if (received < segment_size) break; /* early exit */ else if (!received) break; ++cnt; } return data; } This is my theoretical function, it errors at `char[segment_size][] data;` with the painful `app.d(20): Error: variable segment_size cannot be read at compile time` and I recall having an issue similar to this earlier (yesterday) but I don't think any of my solutions seemed valid for this situation. I understand it's to do with CTFE or some form of compile-time checking but that's really the only thing that annoys me about D, perhaps somebody could link to some resource that explains (not shortly) how to make the D compiler evaluate some things at run-time opposed to compile time. Perhaps somebody can link some resources e.g. socket servers in D so I can learn how it's implemented by somebody with a bit more experience, or some resources on how to use sockets properly ¯\_(ツ)_/¯
Re: operator overload
On Tuesday, 12 December 2017 at 17:13:55 UTC, Biotronic wrote: On Tuesday, 12 December 2017 at 16:54:17 UTC, Biotronic wrote: There is no way in C++ to set the format the way you want it. If you want binary output, you need to call a function like your binario function. Of course this is not entirely true - there is a way, but it's ugly and probably not what you want: struct BinStream { std::ostream& os; BinStream(std::ostream& os) : os(os) {} template BinStream& operator<<(T&& value) { os << value; return *this; } BinStream& operator<<(int value) { os << binario(value); return *this; } std::ostream& operator<<(std::ios_base& (__cdecl *_Pfn)(std::ios_base&)) { return os << _Pfn; } }; struct Bin { friend BinStream operator<<(std::ostream& os, const Bin& f); } bin; BinStream operator<<(std::ostream& os, const Bin& f) { return BinStream(os); } int main() { std::cout << "\n\t127 em binario: " << binario(127) << "\n\t127 em binario: " << bin << 127 << "\n\t127 em octal: " << std::oct << 127 << "\n\t127 em binario: " << bin << 127 << "\n\t127 em hexadecimal: " << std::hex << 127 << "\n\t127 em binario: " << bin << 127 << "\n\t127 em decimal: " << std::dec << 127 << "\n\t127 em binario: " << bin << 127 << "\n\n"; } What is this black magic? Instead of overriding how std::ostream does formatting, Bin::Operator<< now returns a wrapper around a std::ostream, which special cases ints. If it gets any other format specifiers, it returns the ostream again, and the binary formatting is gone. All in all, I think the conclusion is: Stay with D. -- Biotronic I tried to execute with this part of the code std::ostream& operator<<(std::ios_base& (__cdecl *_Pfn)(std::ios_base&)) { return os <<_Pfn; } and it returns me this error below what is the include? bin2.cxx:44:43: error: expected ‘,’ or ‘...’ before ‘(’ token std::ostream& operator<<(std::ios_base& (__cdecl *_Pfn)(std::ios_base&)) ^ bin2.cxx: In member function ‘std::ostream& BinStream::operator<<(std::ios_base&)’: bin2.cxx:46:16: error: ‘_Pfn’ was not declared in this scope return os <<_Pfn;
Re: Static array as immutable
On Tue, Dec 12, 2017 at 06:06:48PM +, Ivan Trombley via Digitalmars-d-learn wrote: > On Tuesday, 12 December 2017 at 15:30:01 UTC, Nathan S. wrote: > > While what you're saying is true, exponentiation not being runnable > > at compile-time is a defect and I would assume a regression. [...] > FWIW, if the exponent is an integer, I don't get an error. I don't think exponentiation with non-integer exponents have ever been supported at compile-time. It requires evaluating exp(x) for non-integer x, which, AFAIK, has never been supported at compile-time because the implementation of exp(x) requires constructs that the current CTFE engine doesn't support, namely, inline asm in older versions of std.math, or more recently, the need to access the binary representation of floats/doubles. Perhaps when Stefan Koch's new CTFE engine is ready for public consumption, we will be able to finally have std.math runnable in CTFE. T -- Latin's a dead language, as dead as can be; it killed off all the Romans, and now it's killing me! -- Schoolboy
Re: Tuple Array Sorting
On Tuesday, 12 December 2017 at 15:19:35 UTC, Vino wrote: import std.algorithm: filter, map, sort; import std.container.array; import std.file: SpanMode, dirEntries, isDir ; import std.stdio: writefln; import std.typecons: Tuple, tuple; import std.datetime.systime: SysTime; void main () { auto FFs = ["C:\\Temp\\sapnas2\\BACKUP", "C:\\Temp\\sapnas2\\EXPORT", "C:\\Temp\\sapnas2\\PROD_TEAM"]; Array!(Tuple!(string, SysTime)) Result; foreach(d; FFs[]) { auto dFiles = Array!(Tuple!(string, SysTime))(dirEntries(d, SpanMode.shallow).filter!(a => a.isDir).map!(a => tuple(a.name, a.timeCreated))); foreach(e; dFiles) { Result ~= e; } } writefln("%(%-(%-63s %.20s %)\n%)", Result[].sort!((a, b) => a[1] < b[1])); } Since there's little need to extract timeCreated and name before sorting, here's a version that doesn't: import std.algorithm : map, filter, sort; import std.array : array; import std.range : join; import std.file : SpanMode, dirEntries, isDir; import std.stdio : writefln; import std.typecons : tuple; void main() { auto folders = [`C:\Windows`, `C:\Program Files`, `C:\Users`]; auto sorted = folders .map!(f => f.dirEntries(SpanMode.shallow)) .join .filter!(e => e.isDir) .array .sort!((a,b) => a.timeCreated < b.timeCreated) .map!(e => tuple(e.name, e.timeCreated.toSimpleString[0 .. 20])); writefln("%(%-(%-63s %s %)\n%)", sorted); } And a version with normal loops, since the heavily range-based version above can be a bit dense. These programs do essentially the same thing: import std.algorithm : sort; import std.array : array; import std.file : SpanMode, dirEntries, DirEntry, isDir; import std.stdio : writefln; import std.typecons : tuple, Tuple; void main() { auto folders = [`C:\Windows`, `C:\Program Files`, `C:\Users`]; DirEntry[] subFolders; foreach (folder; folders) { auto children = dirEntries(folder, SpanMode.shallow); foreach (child; children) { if (child.isDir) subFolders ~= child; } } subFolders.sort!((a,b) => a.timeCreated < b.timeCreated); Tuple!(string, string)[] interestingParts; foreach (subFolder; subFolders) { interestingParts ~= tuple(subFolder.name, subFolder.timeCreated.toSimpleString[0..20]); } writefln("%(%-(%-63s %s %)\n%)", interestingParts); } As you can see, I'm just chopping off the parts I don't like from toSimpleString. It seems a good format function for dates does not exist in Phobos. -- Biotronic
Re: operator overload
On Tuesday, 12 December 2017 at 17:13:55 UTC, Biotronic wrote: On Tuesday, 12 December 2017 at 16:54:17 UTC, Biotronic wrote: There is no way in C++ to set the format the way you want it. If you want binary output, you need to call a function like your binario function. Of course this is not entirely true - there is a way, but it's ugly and probably not what you want: struct BinStream { std::ostream& os; BinStream(std::ostream& os) : os(os) {} template BinStream& operator<<(T&& value) { os << value; return *this; } BinStream& operator<<(int value) { os << binario(value); return *this; } std::ostream& operator<<(std::ios_base& (__cdecl *_Pfn)(std::ios_base&)) { return os << _Pfn; } }; struct Bin { friend BinStream operator<<(std::ostream& os, const Bin& f); } bin; BinStream operator<<(std::ostream& os, const Bin& f) { return BinStream(os); } int main() { std::cout << "\n\t127 em binario: " << binario(127) << "\n\t127 em binario: " << bin << 127 << "\n\t127 em octal: " << std::oct << 127 << "\n\t127 em binario: " << bin << 127 << "\n\t127 em hexadecimal: " << std::hex << 127 << "\n\t127 em binario: " << bin << 127 << "\n\t127 em decimal: " << std::dec << 127 << "\n\t127 em binario: " << bin << 127 << "\n\n"; } What is this black magic? Instead of overriding how std::ostream does formatting, Bin::Operator<< now returns a wrapper around a std::ostream, which special cases ints. If it gets any other format specifiers, it returns the ostream again, and the binary formatting is gone. All in all, I think the conclusion is: Stay with D. -- Biotronic I understand is basically this now I will see the necessity of this basically the example I wanted to do is to understand how it would be done in the most correct way, now I will study to do other cases if nescessarios but primarily is to convert only integers but you did exactly the that I wanted I did some studies in the D language and it already has a way to convert to binary without any work just using% b as in printf you use% X or% x to convert to exa ... and that was the reason that made me interested in understand this was looking at some older glibc and the way printf understands these very interesting conversion operators
Re: What's the proper way to use std.getopt?
On 12-12-17 00:35, Seb wrote: D style would be to use sth. like this (instead of try/catch): ``` scope(failure) { e.msg.writeln; 1.exit; } ``` I might have missed something, but where is `e` defined in this case? -- Mike Wey
Re: Static array as immutable
On Tuesday, 12 December 2017 at 15:30:01 UTC, Nathan S. wrote: While what you're saying is true, exponentiation not being runnable at compile-time is a defect and I would assume a regression. I'll file a bug report. FWIW when trying to run the following with DMD v2.077.1 I get: ``` void main(string[] args) { import std.stdio; enum e = (1.0 / 255.0f) ^^ (1 / 2.2f); writeln("e = ", e); } ``` => [...]/dmd/std/math.d(440): Error: y.vu[4] is used before initialized [...]/dmd/std/math.d(413):originally uninitialized here [...]/dmd/std/math.d(4107):called from here: floorImpl(x) [...]/dmd/std/math.d(2373):called from here: floor(x + 0.5L) [...]/dmd/std/math.d(2110):called from here: exp2Impl(x) [...]/dmd/std/math.d(6743):called from here: exp2(yl2x(x, y)) [...]/dmd/std/math.d(6756):called from here: impl(cast(real)x, cast(real)y) FWIW, if the exponent is an integer, I don't get an error.
AssocArray to string is ok, but how to get the AssocArray from string? Thanks
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.
Re: operator overload
On Tuesday, 12 December 2017 at 16:54:17 UTC, Biotronic wrote: There is no way in C++ to set the format the way you want it. If you want binary output, you need to call a function like your binario function. Of course this is not entirely true - there is a way, but it's ugly and probably not what you want: struct BinStream { std::ostream& os; BinStream(std::ostream& os) : os(os) {} template BinStream& operator<<(T&& value) { os << value; return *this; } BinStream& operator<<(int value) { os << binario(value); return *this; } std::ostream& operator<<(std::ios_base& (__cdecl *_Pfn)(std::ios_base&)) { return os << _Pfn; } }; struct Bin { friend BinStream operator<<(std::ostream& os, const Bin& f); } bin; BinStream operator<<(std::ostream& os, const Bin& f) { return BinStream(os); } int main() { std::cout << "\n\t127 em binario: " << binario(127) << "\n\t127 em binario: " << bin << 127 << "\n\t127 em octal: " << std::oct << 127 << "\n\t127 em binario: " << bin << 127 << "\n\t127 em hexadecimal: " << std::hex << 127 << "\n\t127 em binario: " << bin << 127 << "\n\t127 em decimal: " << std::dec << 127 << "\n\t127 em binario: " << bin << 127 << "\n\n"; } What is this black magic? Instead of overriding how std::ostream does formatting, Bin::Operator<< now returns a wrapper around a std::ostream, which special cases ints. If it gets any other format specifiers, it returns the ostream again, and the binary formatting is gone. All in all, I think the conclusion is: Stay with D. -- Biotronic
Re: operator overload
On Tuesday, 12 December 2017 at 15:52:09 UTC, dark777 wrote: I know that this community is not of c ++, but some time I have been studying how to do overload of ostream operators in c ++ and I even managed to get to this result but the same is not converting to binary only presents zeros as output to any number already tried to pass parameter of variable and yet he is not getting the number for conversion how to solve it so that it works correctly? PS: if I use the same conversion algorithm in a function it converts normally it is not only converting to the output of the operator .. https://pastebin.com/BXGXiiRk This line: << "\n\t127 em binario: " << bin << 127 << "\n\n"; Your hope is that the '<< bin' part should behave just like std::hex does, except binary instead of hex. Right? I'm afraid that's not how C++ formatting works. You can see a hint of what happens in the output you get: 127 em binario: 127 The zeroes are from the uninitialized int in your Bin struct, and the '127' is from the 127 you pass right after passing bin. Translating to code that does not use operators, the behavior you expect is something like this: std::cout.print("\n\t127 em binario: "); std::cout.setFormat(bin); std::cout.print(127); // Should use bin for formatting std::cout.print("\n\n"); The actual behavior is something like this: std ::cout.print("\n\t127 em binario: "); std::cout.print(bin); // Prints the value stored in bin. That is, 0. std::cout.print(127); // Prints 127 just the way it would otherwise print it. std::cout.print("\n\n"); There is no way in C++ to set the format the way you want it. If you want binary output, you need to call a function like your binario function. The point of overloading operator<<(std::ostream&, MyType) is not to format another type, but to be able to print MyType in a given way. Basically like toString() in D, C# or Java. -- Biotronic
Re: Date Formating
On Tuesday, 12 December 2017 at 16:01:49 UTC, Adam D. Ruppe wrote: On Tuesday, 12 December 2017 at 15:56:59 UTC, Vino wrote: Request out help on date formatting, I have code which output the date and time as below , i we need it without the last few numbers.,ie "-MMM-DD HH:MM:SI" Just slice it off. x[0 .. x.lastIndexOf("."]; Hi, I tried it but no luck, as the output is a function return in type SysTime. From, Vino.B
Re: Date Formating
On Tuesday, 12 December 2017 at 15:56:59 UTC, Vino wrote: Request out help on date formatting, I have code which output the date and time as below , i we need it without the last few numbers.,ie "-MMM-DD HH:MM:SI" Just slice it off. x[0 .. x.lastIndexOf("."];
Date Formating
Hi All, Request out help on date formatting, I have code which output the date and time as below , i we need it without the last few numbers.,ie "-MMM-DD HH:MM:SI" Output : 2017-Sep-06 16:06:42.7223837 Required Output : 2017-Sep-06 16:06:42 From, Vino.B
operator overload
I know that this community is not of c ++, but some time I have been studying how to do overload of ostream operators in c ++ and I even managed to get to this result but the same is not converting to binary only presents zeros as output to any number already tried to pass parameter of variable and yet he is not getting the number for conversion how to solve it so that it works correctly? PS: if I use the same conversion algorithm in a function it converts normally it is not only converting to the output of the operator .. https://pastebin.com/BXGXiiRk
Re: Processing Function of return type(Real and SysTime)
On Tuesday, 12 December 2017 at 14:25:22 UTC, Vino wrote: Hi All, Request your help on the below code, as i ma getting the below error message [...] Hi All, Was able to resolve this issue, it was my mistake, sorry. From, Vino.B
Re: Static array as immutable
On Tuesday, 12 December 2017 at 11:37:40 UTC, Jonathan M Davis wrote: On Tuesday, December 12, 2017 10:35:15 Ivan Trombley via Digitalmars-d-learn wrote: On Tuesday, 12 December 2017 at 09:48:09 UTC, Jonathan M Davis wrote: > On Tuesday, December 12, 2017 07:33:47 Ivan Trombley via > > Digitalmars-d-learn wrote: >> Is there some way that I can make this array immutable? >> >>static float[256] ga = void; >>static foreach (i; 0 .. 256) >> >>ga[i] = (i / 255.0f) ^^ (1 / 2.2f); > > If you want anything to be immutable, you either have to > initialize it directly or give it a value in a static > constructor (and the static constructor solution won't work > for local variables). So, you'd need to do something like > > static immutable float[256] ga = someFuncThatGeneratesGA(); > > If the function is pure, and there's no way that the return > value was passed to the function, then its return value can > be assigned to something of any mutability, since the > compiler knows that there are no other references to it, and > it can implicitly cast it, or if the type is a value type > (as in this case), then you just get a copy, and mutability > isn't an issue. Alternatively to using a pure function, you > can use std.exception.assumeUnique to cast to immutable, but > that relies on you being sure that there are no other > references to the data, and it may not work at compile-time, > since casting is a lot more restrictive during CTFE. So, in > general, using a pure function is preferable to assumeUnique. > > - Jonathan M Davis Ah, it doesn't work. I get this error using the ^^ operator: /usr/include/dmd/phobos/std/math.d(5724,27): Error: cannot convert &real to ubyte* at compile time /usr/include/dmd/phobos/std/math.d(6629,24):called from here: signbit(x) /usr/include/dmd/phobos/std/math.d(6756,16):called from here: impl(cast(real)x, cast(real)y) :( Well, if the code you need to initialize a variable can't be run at compile time, then that variable can't be a variable that needs to be initialized at compile time and be immutable. - Jonathan M Davis While what you're saying is true, exponentiation not being runnable at compile-time is a defect and I would assume a regression. I'll file a bug report. FWIW when trying to run the following with DMD v2.077.1 I get: ``` void main(string[] args) { import std.stdio; enum e = (1.0 / 255.0f) ^^ (1 / 2.2f); writeln("e = ", e); } ``` => [...]/dmd/std/math.d(440): Error: y.vu[4] is used before initialized [...]/dmd/std/math.d(413):originally uninitialized here [...]/dmd/std/math.d(4107):called from here: floorImpl(x) [...]/dmd/std/math.d(2373):called from here: floor(x + 0.5L) [...]/dmd/std/math.d(2110):called from here: exp2Impl(x) [...]/dmd/std/math.d(6743):called from here: exp2(yl2x(x, y)) [...]/dmd/std/math.d(6756):called from here: impl(cast(real)x, cast(real)y)
Re: Tuple Array Sorting
On Monday, 11 December 2017 at 20:58:31 UTC, Biotronic wrote: On Monday, 11 December 2017 at 19:46:04 UTC, Vino wrote: import std.algorithm; import std.container.array; import std.file: SpanMode, dirEntries, isDir ; import std.stdio: writefln, writeln; import std.typecons: Tuple, tuple; import std.range: chain; void main () { auto FFs = ["C:\\Temp\\BACKUP", "C:\\Temp\\EXPORT", "C:\\Temp\\PROD_TEAM"]; foreach(d; FFs[]) { auto dFiles = Array!(Tuple!(string, SysTime))(dirEntries(d, SpanMode.shallow).filter!(a => a.isDir).map!(a => tuple(a.name, a.timeCreated))); writefln("%(%-(%-63s %s %)\n%)", chain(dFiles[]).sort!((a, b) => a[1] < b[1])); } } So let's go through this code then, shall we? Edited a bit for clarity: // For each directory (*one at a time*), foreach(d; FFs[]) { // List all the folders auto dFiles = Array!(Tuple!(string, SysTime))( dirEntries(d, SpanMode.shallow) // Not the files, .filter!(a => a.isDir) // Grab only the information we want, .map!(a => tuple(a.name, a.timeCreated))); // And print a sorted list of the subfolders of the current folder. writefln("%(%-(%-63s %s %)\n%)", chain(dFiles[]).sort!((a, b) => a[1] < b[1])); } This will go through C:\Temp\BACKUP, and display a sorted list of all the subfolders in that folder. Then it will do the same for C:\Temp\EXPORT, and then for C:\Temp\PROD_TEAM. No subfolder of C:\Temp\PROD_TEAM will be displayed before anything in C:\Temp\BACKUP, because you're sorting only one set of subfolders at a time. What you're essentially doing, is sorting [6,2,4] and [3,5,1] separately, and printing them separately, giving the illusion of having sorted them into the array [2,4,6,1,3,5]. As you correctly point out, this is not what you wanted. The code I presented avoids this by joining the lists for all the folders. Your code could also be simplified a bit - there's no need for the call to chain, and calling dirEntries.filter.map.array is easier to read and write than having Array!(Tuple!(string, SysTime)) at the front. In case my code from earlier was hard to understand, here's another version~, more closely modeled to your code: import std.algorithm : map, filter, sort; import std.array : array; import std.file : SpanMode, dirEntries, isDir; import std.stdio : writefln; import std.typecons : Tuple, tuple; import std.datetime : SysTime; void main() { // The folders we want to look in. auto folders = [`C:\Windows`, `C:\Program Files`, `C:\Users`]; // We'll put all the subfolders we find here, so we can sort them in the end. Tuple!(string, SysTime)[] subFolders; // Look through each folder in turn. foreach (folder; folders) { // Get all entries in the folder, auto entries = dirEntries(folder, SpanMode.shallow); // Get rid of files, auto folderEntries = entries.filter!(a => a.isDir); // Grab the interesting parts, auto interestingParts = folderEntries.map!(a => tuple(a.name, a.timeCreated)); // And add it to the array. subFolders ~= interestingParts.array; } // Sort the entire array. auto sorted = subFolders.sort!((a, b) => a[1] < b[1]); // And print it! writefln("%(%-(%-63s %s %)\n%)", sorted); } Hi, Thank you very much , was able to resolve the issue using your logic with a bit of addition and not i am getting the sorted output as expected, except that the date and time are displayed as "2017-Sep-05 14:31:00.7037169" so may i know how do we get the output as "2017-Sep-05 14:31:00". Program: import std.algorithm: filter, map, sort; import std.container.array; import std.file: SpanMode, dirEntries, isDir ; import std.stdio: writefln; import std.typecons: Tuple, tuple; import std.datetime.systime: SysTime; void main () { auto FFs = ["C:\\Temp\\sapnas2\\BACKUP", "C:\\Temp\\sapnas2\\EXPORT", "C:\\Temp\\sapnas2\\PROD_TEAM"]; Array!(Tuple!(string, SysTime)) Result; foreach(d; FFs[]) { auto dFiles = Array!(Tuple!(string, SysTime))(dirEntries(d, SpanMode.shallow).filter!(a => a.isDir).map!(a => tuple(a.name, a.timeCreated))); foreach(e; dFiles) { Result ~= e; } } writefln("%(%-(%-63s %.20s %)\n%)", Result[].sort!((a, b) => a[1] < b[1])); } From, Vino.B
Processing Function of return type(Real and SysTime)
Hi All, Request your help on the below code, as i ma getting the below error message Error: C:\D\dmd2\windows\bin\..\..\src\phobos\std\container\array.d(739): Error: template std.container.array.Array!(Tuple!(string, real)).Array.insertBack cannot dedu ce function from argument types !()(RangeT!(Array!(Tuple!(string, SysTime, candidates are: C:\D\dmd2\windows\bin\..\..\src\phobos\std\container\array.d(805): std.container.array.Array!(Tuple!(string, real)).Array.insertBack(Stuff)(Stuff stuff) if (isImplicitlyConvertible!(Stuff, T) || isInputRange!Stuff && isImplicitlyConvertible!(ElementType!Stuff, T)) SFtest.d(28): Error: template instance std.container.array.Array!(Tuple!(string, real)).Array.opOpAssign!("~", RangeT!(Array!(Tuple!(string, SysTime error i nstantiating SFtest.d(33):instantiated from here: MN1!(Array!(Tuple!(string, SysTime))) C:\D\dmd2\windows\bin\..\..\src\phobos\std\container\array.d(739): Error: template std.container.array.Array!(Tuple!(string, SysTime)).Array.insertBack cannot d educe function from argument types !()(RangeT!(Array!(Tuple!(string, real, candidates are: C:\D\dmd2\windows\bin\..\..\src\phobos\std\container\array.d(805): std.container.array.Array!(Tuple!(string, SysTime)).Array.insertBack(Stuff)(Stuff stuf f) if (isImplicitlyConvertible!(Stuff, T) || isInputRange!Stuff && isImplicitlyConvertible!(ElementType!Stuff, T)) SFtest.d(25): Error: template instance std.container.array.Array!(Tuple!(string, SysTime)).Array.opOpAssign!("~", RangeT!(Array!(Tuple!(string, real error i nstantiating SFtest.d(34):instantiated from here: MN1!(Array!(Tuple!(string, real))) Failed: ["dmd", "-v", "-o-", "SFtest.d", "-I."] Program: import std.stdio: writefln, writeln; import std.traits: ReturnType; import std.file: SpanMode, dirEntries, isDir, isFile; import std.algorithm: filter, map, sort; import std.typecons: Tuple, tuple; import std.parallelism: parallel, taskPool; import std.container.array; import std.datetime.systime: SysTime; import std.string; auto FN1(string FFs) { auto dFiles = Array!(Tuple!(string, SysTime))(dirEntries(FFs, SpanMode.depth).filter!(a => a.isFile).map!(a => tuple(a.name, a.timeCreated))); return dFiles; } auto FN2(string FFs) { auto dFiles = Array!(Tuple!(string, real))(dirEntries(FFs, SpanMode.depth).filter!(a => a.isFile).map!(a => tuple(a.name, a.size.to!real))); return dFiles; } void MN1(T)(T function(string) coRoutine, Array!string Dirlst) { alias scRType = typeof(coRoutine(string.init)); auto PFresult = taskPool.workerLocalStorage!scRType(); foreach (string FFs; parallel(Dirlst[0 .. $],1)) { PFresult.get ~= coRoutine(FFs.strip); } /* ### Function Call 1 ### */ //If this works the below Function does not work ReturnType!FN1 rFN1data; foreach(i; PFresult.toRange) { rFN1data ~= i[][]; } if (!rFN1data[].empty) { writefln("%(%-(%-63s %s %)\n%)", rFN1data[].sort!((a,b) => a[1] > b[1])); } /* ### Function Call 2 ### */ //If this works the above Function does not work ReturnType!FN2 rFN2data; foreach(i; PFresult.toRange) { rFN2data ~= i[][]; } if (!rFN2data[].empty) { writefln("%(%-(%-63s %s %)\n%)", rFN2data[].sort!((a,b) => a[1] > b[1])); } } void main () { auto Dirlst = Array!string ("C:\\Temp\\BACKUP", "C:\\Temp\\EXPORT"); MN1(&FN1, Dirlst); MN1(&FN2, Dirlst); } From, Vino.B
Re: No line numbers in stack trace (again)
On Tuesday, 5 December 2017 at 13:43:38 UTC, Nordlöw wrote: If I get the following stack trace ___without line numbers___ (instead ??:?) what's missing? and using DMD 2.077.1 https://issues.dlang.org/show_bug.cgi?id=18068
Re: Static array as immutable
On Tuesday, December 12, 2017 10:35:15 Ivan Trombley via Digitalmars-d-learn wrote: > On Tuesday, 12 December 2017 at 09:48:09 UTC, Jonathan M Davis > > wrote: > > On Tuesday, December 12, 2017 07:33:47 Ivan Trombley via > > > > Digitalmars-d-learn wrote: > >> Is there some way that I can make this array immutable? > >> > >>static float[256] ga = void; > >>static foreach (i; 0 .. 256) > >> > >>ga[i] = (i / 255.0f) ^^ (1 / 2.2f); > > > > If you want anything to be immutable, you either have to > > initialize it directly or give it a value in a static > > constructor (and the static constructor solution won't work for > > local variables). So, you'd need to do something like > > > > static immutable float[256] ga = someFuncThatGeneratesGA(); > > > > If the function is pure, and there's no way that the return > > value was passed to the function, then its return value can be > > assigned to something of any mutability, since the compiler > > knows that there are no other references to it, and it can > > implicitly cast it, or if the type is a value type (as in this > > case), then you just get a copy, and mutability isn't an issue. > > Alternatively to using a pure function, you can use > > std.exception.assumeUnique to cast to immutable, but that > > relies on you being sure that there are no other references to > > the data, and it may not work at compile-time, since casting is > > a lot more restrictive during CTFE. So, in general, using a > > pure function is preferable to assumeUnique. > > > > - Jonathan M Davis > > Ah, it doesn't work. I get this error using the ^^ operator: > > /usr/include/dmd/phobos/std/math.d(5724,27): Error: cannot > convert &real to ubyte* at compile time > /usr/include/dmd/phobos/std/math.d(6629,24):called from > here: signbit(x) > /usr/include/dmd/phobos/std/math.d(6756,16):called from > here: impl(cast(real)x, cast(real)y) > > :( Well, if the code you need to initialize a variable can't be run at compile time, then that variable can't be a variable that needs to be initialized at compile time and be immutable. - Jonathan M Davis
Re: Static array as immutable
On Tuesday, 12 December 2017 at 09:48:09 UTC, Jonathan M Davis wrote: On Tuesday, December 12, 2017 07:33:47 Ivan Trombley via Digitalmars-d-learn wrote: Is there some way that I can make this array immutable? static float[256] ga = void; static foreach (i; 0 .. 256) ga[i] = (i / 255.0f) ^^ (1 / 2.2f); If you want anything to be immutable, you either have to initialize it directly or give it a value in a static constructor (and the static constructor solution won't work for local variables). So, you'd need to do something like static immutable float[256] ga = someFuncThatGeneratesGA(); If the function is pure, and there's no way that the return value was passed to the function, then its return value can be assigned to something of any mutability, since the compiler knows that there are no other references to it, and it can implicitly cast it, or if the type is a value type (as in this case), then you just get a copy, and mutability isn't an issue. Alternatively to using a pure function, you can use std.exception.assumeUnique to cast to immutable, but that relies on you being sure that there are no other references to the data, and it may not work at compile-time, since casting is a lot more restrictive during CTFE. So, in general, using a pure function is preferable to assumeUnique. - Jonathan M Davis Ah, it doesn't work. I get this error using the ^^ operator: /usr/include/dmd/phobos/std/math.d(5724,27): Error: cannot convert &real to ubyte* at compile time /usr/include/dmd/phobos/std/math.d(6629,24):called from here: signbit(x) /usr/include/dmd/phobos/std/math.d(6756,16):called from here: impl(cast(real)x, cast(real)y) :(
Re: Static array as immutable
On Tuesday, December 12, 2017 07:33:47 Ivan Trombley via Digitalmars-d-learn wrote: > Is there some way that I can make this array immutable? > >static float[256] ga = void; >static foreach (i; 0 .. 256) >ga[i] = (i / 255.0f) ^^ (1 / 2.2f); If you want anything to be immutable, you either have to initialize it directly or give it a value in a static constructor (and the static constructor solution won't work for local variables). So, you'd need to do something like static immutable float[256] ga = someFuncThatGeneratesGA(); If the function is pure, and there's no way that the return value was passed to the function, then its return value can be assigned to something of any mutability, since the compiler knows that there are no other references to it, and it can implicitly cast it, or if the type is a value type (as in this case), then you just get a copy, and mutability isn't an issue. Alternatively to using a pure function, you can use std.exception.assumeUnique to cast to immutable, but that relies on you being sure that there are no other references to the data, and it may not work at compile-time, since casting is a lot more restrictive during CTFE. So, in general, using a pure function is preferable to assumeUnique. - Jonathan M Davis
Re: No line numbers in stack trace (again)
On 12/05/2017 08:43 AM, Nordlöw wrote: If I get the following stack trace ___without line numbers___ (instead ??:?) what's missing? Linux stack trace line numbers have disappeard for me, too. Used to work. Very frustrating, and a royal PITA when dealing with unittests. Help would be appreciated. Could it be a PIC thing?
Re: Static array as immutable
On Tuesday, 12 December 2017 at 07:44:55 UTC, Radu wrote: On Tuesday, 12 December 2017 at 07:33:47 UTC, Ivan Trombley wrote: Is there some way that I can make this array immutable? static float[256] ga = void; static foreach (i; 0 .. 256) ga[i] = (i / 255.0f) ^^ (1 / 2.2f); Check https://dlang.org/phobos/std_exception.html#assumeUnique Thanks.
Re: Debugging a druntime issue found by AutoTester
I would go with some VM and install 32bit system on it. Dne 12. 12. 2017 8:55 dop. napsal uživatel "Ali Çehreli via Digitalmars-d-learn" : > The automatic tests for a PR failed for a target that I could not test > myself: 32-bit build on Darwin_64_32. > > > https://auto-tester.puremagic.com/show-run.ghtml?projectid=1 > &runid=2940199&dataid=20802787&isPull=true > > Testing attach_detach > timelimit -t 10 ./generated/osx/debug/32/attach_detach > attach_detach(32762,0xb0103000) malloc: *** error for object 0x1000: > pointer being freed was not allocated > *** set a breakpoint in malloc_error_break to debug > make[2]: *** [generated/osx/debug/32/attach_detach.done] Error 134 > make[1]: *** [test/thread/.run] Error 2 > make: *** [unittest-debug] Error 2 > > How can I reproduce the issue perhaps on my Ubuntu-based 64-bit laptop? > I'm hoping that the problem will be obvious if I can build a 32-bit target > and "set a breakpoint in malloc_error_break to debug". > > I tried to build a 32-bit dmd on my system but failed with dependency > issues. Is the following right way? > > $ MODEL=32 make -f posix.mak -j8 AUTO_BOOTSTRAP=1 > [...] > /usr/bin/ld: skipping incompatible > /usr/lib/gcc/x86_64-linux-gnu/5/libstdc++.so > when searching for -lstdc++ > /usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/5/libstdc++.a > when searching for -lstdc++ > /usr/bin/ld: cannot find -lstdc++ > collect2: error: ld returned 1 exit status > > Ali >