Re: How to loop through characters of a string in D language?
On Saturday, 11 December 2021 at 00:39:15 UTC, forkit wrote: On Friday, 10 December 2021 at 22:35:58 UTC, Arjan wrote: "abc;def;ghi".tr(";", "", "d" ); I don't think we have enough ways of doing the same thing yet... so here's one more.. "abc;def;ghi".substitute(";", ""); Using libraries can trigger hidden allocations. ``` import std.stdio; string garbagefountain(string s){ if (s.length == 1) return s == ";" ? "" : s; return garbagefountain(s[0..$/2]) ~ garbagefountain(s[$/2..$]); } int main() { writeln(garbagefountain("abc;def;ab")); return 0; } ```
Re: How to loop through characters of a string in D language?
On Friday, 10 December 2021 at 18:47:53 UTC, Stanislav Blinov wrote: Threshold could be relative for short strings and absolute for long ones. Makes little sense reallocating if you only waste a couple bytes, but makes perfect sense if you've just removed pages and pages of semicolons ;) Scanning short strings twice is not all that expensive as they will stay in the CPU cache when you run over them a second time. ``` import std.stdio; @safe: string stripsemicolons(string s) @trusted { int i,n; foreach(c; s) n += c != ';'; // premature optimization auto r = new char[](n); foreach(c; s) if (c != ';') r[i++] = c; return cast(string)r; } int main() { writeln(stripsemicolons("abc;def;ab")); return 0; } ```
Re: How to loop through characters of a string in D language?
On Saturday, 11 December 2021 at 08:05:01 UTC, Ola Fosheim Grøstad wrote: Using libraries can trigger hidden allocations. ok. fine. no unnecessary, hidden allocations then. // -- module test; import core.stdc.stdio : putchar; nothrow @nogc void main() { string str = "abc;def;ab"; ulong len = str.length; for (ulong i = 0; i < len; i++) { if (cast(int) str[i] != ';') putchar(cast(int) str[i]); } } // --
Re: How to loop through characters of a string in D language?
On Saturday, 11 December 2021 at 08:46:32 UTC, forkit wrote: On Saturday, 11 December 2021 at 08:05:01 UTC, Ola Fosheim Grøstad wrote: Using libraries can trigger hidden allocations. ok. fine. no unnecessary, hidden allocations then. // -- module test; import core.stdc.stdio : putchar; nothrow @nogc void main() { string str = "abc;def;ab"; ulong len = str.length; for (ulong i = 0; i < len; i++) { if (cast(int) str[i] != ';') putchar(cast(int) str[i]); } } // -- ```putchar(…)``` is too slow! ``` @safe: extern (C) long write(long, const void *, long); void donttrythisathome(string s, char stripchar) @trusted { import core.stdc.stdlib; char* begin = cast(char*)alloca(s.length); char* end = begin; foreach(c; s) if (c != stripchar) *(end++) = c; write(0, begin, end - begin); } @system void main() { string str = "abc;def;ab"; donttrythisathome(str, ';'); }
Re: How to loop through characters of a string in D language?
On Friday, 10 December 2021 at 23:53:47 UTC, Ola Fosheim Grøstad wrote: ```d char[] dontdothis(string s, int i=0, int skip=0){ if (s.length == i) return new char[](i - skip); if (s[i] == ';') return dontdothis(s, i+1, skip+1); auto r = dontdothis(s, i+1, skip); r[i-skip] = s[i]; return r; } ``` That is about 500% not what I meant. At all. Original code in question: - duplicates string unconditionally as mutable storage - uses said mutable storage to gather all non-semicolons - duplicates said mutable storage (again) as immutable I suggested to make the second duplicate conditional, based on amount of space freed by skipping semicolons. What you're showing is... indeed, don't do this, but I fail to see what that has to do with my suggestion, or the original code. Scanning short strings twice is not all that expensive as they will stay in the CPU cache > when you run over them a second time. ```d import std.stdio; @safe: string stripsemicolons(string s) @trusted { int i,n; foreach(c; s) n += c != ';'; // premature optimization auto r = new char[](n); foreach(c; s) if (c != ';') r[i++] = c; return cast(string)r; } ``` Again, that is a different algorithm than what I was responding to. But sure, short strings - might as well. So long as you do track the distinction somewhere up in the code and don't simply call this on all strings.
Re: How to loop through characters of a string in D language?
On Saturday, 11 December 2021 at 09:26:06 UTC, Stanislav Blinov wrote: What you're showing is... indeed, don't do this, but I fail to see what that has to do with my suggestion, or the original code. You worry too much, just have fun with differing ways of expressing the same thing. (Recursion can be completely fine if the compiler supports it well. Tail recursion that is, not my example.) Again, that is a different algorithm than what I was responding to. Slightly different, but same idea. Isn't the point of this thread to present N different ways of doing the same thing? :-)
Re: How to loop through characters of a string in D language?
On Saturday, 11 December 2021 at 08:46:32 UTC, forkit wrote: On Saturday, 11 December 2021 at 08:05:01 UTC, Ola Fosheim Grøstad wrote: Using libraries can trigger hidden allocations. ok. fine. no unnecessary, hidden allocations then. // -- module test; import core.stdc.stdio : putchar; nothrow @nogc void main() { string str = "abc;def;ab"; ulong len = str.length; for (ulong i = 0; i < len; i++) { if (cast(int) str[i] != ';') putchar(cast(int) str[i]); } } // -- ```putchar(…)``` is too slow! ``` @safe: extern (C) long write(long, const void *, long); void donttrythisathome(string s, char stripchar) @trusted { import core.stdc.stdlib; char* begin = cast(char*)alloca(s.length); char* end = begin; foreach(c; s) if (c != stripchar) *(end++) = c; write(0, begin, end - begin); } @system void main() { string str = "abc;def;ab"; donttrythisathome(str, ';'); }
Re: How to loop through characters of a string in D language?
On Saturday, 11 December 2021 at 09:34:17 UTC, Ola Fosheim Grøstad wrote: @system Shouldn't be there. Residual leftovers… (I don't want to confuse newbies!)
Re: How to loop through characters of a string in D language?
On Saturday, 11 December 2021 at 09:34:17 UTC, Ola Fosheim Grøstad wrote: void donttrythisathome(string s, char stripchar) @trusted { import core.stdc.stdlib; char* begin = cast(char*)alloca(s.length); A function with that name, and calling alloca to boot, cannot be @trusted ;)
Re: How to loop through characters of a string in D language?
On Saturday, 11 December 2021 at 09:40:47 UTC, Stanislav Blinov wrote: On Saturday, 11 December 2021 at 09:34:17 UTC, Ola Fosheim Grøstad wrote: void donttrythisathome(string s, char stripchar) @trusted { import core.stdc.stdlib; char* begin = cast(char*)alloca(s.length); A function with that name, and calling alloca to boot, cannot be @trusted ;) :-) But I am very trustworthy person! PROMISE!!!
Re: How to loop through characters of a string in D language?
Here is mine - 0 allocations - configurable - let's you use it how you wish - fast ```D import std; void main() { string a = "abc;def;ab"; writeln("a => ", a); foreach(item; split(a, ';')) writeln("\t", item); string b = "abc;def ;ab"; writeln("a => ", b); foreach(item; split(b, ';', SplitOption.TRIM)) writeln("\t", item); string c= "abc;; ;def ;ab"; writeln("a => ",c); foreach(item; split(c, ';', SplitOption.TRIM | SplitOption.REMOVE_EMPTY)) writeln("\t", item); } SplitIterator!T split(T)(const(T)[] buffer, const(T) delimiter, SplitOption option = SplitOption.NONE) { return SplitIterator!T(buffer, delimiter, option); } struct SplitIterator(T) { const(T)[] buffer; const(T) delimiter; SplitOption option; int index = 0; int count() { int c = 0; foreach(line; this) { c++; } index = 0; return c; } const(T) get(int index) { return buffer[index]; } int opApply(scope int delegate(const(T)[]) dg) { auto length = buffer.length; for (int i = 0; i < length; i++) { if (buffer[i] == '\0') { length = i; break; } } int result = 0; for (int i = index; i < length; i++) { int entry(int start, int end) { // trim only if we got something if ((end - start > 0) && (option & SplitOption.TRIM)) { for (int j = start; j < end; j++) if (buffer[j] == ' ') start += 1; else break; for (int k = end; k >= start; k--) if (buffer[k - 1] == ' ') end -= 1; else break; // nothing left if(start >= end) return 0; } //printf("%i to %i :: %i :: total: %lu\n", start, end, index, buffer.length); return dg(buffer[start .. end]) != 0; } auto c = buffer[i]; if (c == delimiter) { if (i == index && (option & SplitOption.REMOVE_EMPTY)) { // skip if we keep finding the delimiter index = i + 1; continue; } if ((result = entry(index, i)) != 0) break; // skip delimiter for next result index = i + 1; } // handle what's left if ((i + 1) == length) { result = entry(index, i + 1); } } return result; } // copy from above, only replace if above has changed int opApply(scope int delegate(int, const(T)[]) dg) { auto length = buffer.length; for (int i = 0; i < length; i++) { if (buffer[i] == '\0') { length = i; break; } } int n = 0; int result = 0; for (int i = index; i < length; i++) { int entry(int start, int end) { // trim only if we got something if ((end - start > 0) && (option & SplitOption.TRIM)) { for (int j = start; j < end; j++) if (buffer[j] == ' ') start += 1; else break; for (int k = end; k >= start; k--) if (buffer[k - 1] == ' ') end -= 1; else break; // nothing left if(start >= end) return 0; } //printf("%i to %i :: %i :: total: %lu\n", start, end, index, buffer.length); return dg(n++, buffer[start .. end]) != 0; } auto c = buffer[i]; if (c == delimiter) { if (i == index && (option & SplitOption.REMOVE_EMPTY)) { // skip if we keep finding the delimiter index = i + 1; continue; } if ((result = entry(index, i)) != 0) break; // skip delimiter for next result index = i + 1;
Re: Wouldn't the compiler be smart with this shadowing variable?
On Friday, 10 December 2021 at 21:55:17 UTC, Siarhei Siamashka wrote: ... 2. reuse the existing "j" variable. Yes. But only one of them is a correct description of what actually happens when the compiler processes this code. So it's a good thing that the compiler is smart enough to reject ambiguous code and prevent humans from making mistakes. Hmm I see your point. And I just thought in cases like this the reuse should be the way, but I can see that this is a small snippet and in a big code this may hurt someone. Matheus.
Re: Wouldn't the compiler be smart with this shadowing variable?
On Saturday, 11 December 2021 at 01:02:36 UTC, frame wrote: ... You probably want this: ```d int j; for({int i=0; j=0;} i<10; ++i){} ``` Beware, this syntax comes directly from hell Well this works! :) I'm just a bit intrigued by your last sentence. Is there anything evil this may result or anything that I should be aware of? Matheus.
Re: How to loop through characters of a string in D language?
On Saturday, 11 December 2021 at 14:42:53 UTC, russhy wrote: Here is mine - 0 allocations - configurable - let's you use it how you wish - fast You know that this is already in phobos? ``` "abc;def;ghi".splitter(';').joiner ```
Re: How to loop through characters of a string in D language?
On Saturday, 11 December 2021 at 18:51:12 UTC, Rumbu wrote: On Saturday, 11 December 2021 at 14:42:53 UTC, russhy wrote: Here is mine - 0 allocations - configurable - let's you use it how you wish - fast You know that this is already in phobos? ``` "abc;def;ghi".splitter(';').joiner ``` you need to import a 8k lines of code module that itself imports other modules, and then the code is hard to read https://github.com/dlang/phobos/blob/v2.098.0/std/algorithm/iteration.d#L2917
Re: Wouldn't the compiler be smart with this shadowing variable?
On Saturday, 11 December 2021 at 15:15:06 UTC, Matheus wrote: I'm just a bit intrigued by your last sentence. Is there anything evil this may result or anything that I should be aware of? Besides it looks like an error, you may think that it just introduces a scope which can be referenced by the for-loop but this only works in the initialization section. See what happens if you want to do more steps at iteration for this fancy looking syntax: ```d // iteration works, but scope behind does nothing for({int i=0; j=0;} i<10; ++i, {++i; ++j;} ){} // endless loop for({int i=0; j=0;} i<10; {++i; ++j;} ){} ``` Not sure if bug or feature but it is inconsistent for me and thus a reason to avoid it.
Re: Wouldn't the compiler be smart with this shadowing variable?
On Saturday, 11 December 2021 at 20:22:13 UTC, frame wrote: ```d // iteration works, but scope behind does nothing for({int i=0; j=0;} i<10; ++i, {++i; ++j;} ){} // endless loop for({int i=0; j=0;} i<10; {++i; ++j;} ){} ``` Not sure if bug or feature but it is inconsistent for me and thus a reason to avoid it. That's because `{++i; ++j;}` in an expression context is shorthand syntax for `delegate void () {++i; ++j;}`. If you look at the [grammar for the `for` statement][1], you'll see that the "initialize" part allows a *statement*, but the "test" and "increment" parts only allow *expressions*. [1]: https://dlang.org/spec/statement.html#ForStatement
ImportC std support
What implementations of the C standard library does importC support?
Re: ImportC std support
On Saturday, 11 December 2021 at 21:42:49 UTC, ManKey wrote: What implementations of the C standard library does importC support? umm... the site has search function you know ;-) https://dlang.org/spec/importc.html
Why code failed to compile for foo2?
void foo1(ubyte x) {} void foo1(ushort x) {} void foo1(uint x) {} void foo1(ulong x) {} import std.traits : isUnsigned, Unqual; void foo2(T)(Unqual!T x) if(isUnsigned!T) {} void main() { import std.math; int s = 1; foo1(abs(s)); foo2(abs(s)); //failed? } /* onlineapp.d(15): Error: template `onlineapp.foo2` cannot deduce function from argument types `!()(int)` onlineapp.d(7):Candidate is: `foo2(T)(Unqual!T x)` */
Re: Why code failed to compile for foo2?
On Saturday, 11 December 2021 at 22:50:45 UTC, apz28 wrote: void foo2(T)(Unqual!T x) if(isUnsigned!T) {} This means it treats foo2 as if it doesn't exist unless T is unsigned... onlineapp.d(15): Error: template `onlineapp.foo2` cannot deduce function from argument types `!()(int)` onlineapp.d(7):Candidate is: `foo2(T)(Unqual!T x)` */ And this is telling you it had a signed value - int - which means it doesn't match. For the other ones, the functions still exist, so it does whatever conversion it needs. Whereas with the template that constraint means the compiler acts like it doesn't exist at all and thus doesn't even attempt an automatic conversion.
Re: Why code failed to compile for foo2?
On Saturday, 11 December 2021 at 22:59:52 UTC, Adam Ruppe wrote: On Saturday, 11 December 2021 at 22:50:45 UTC, apz28 wrote: void foo2(T)(Unqual!T x) if(isUnsigned!T) {} This means it treats foo2 as if it doesn't exist unless T is unsigned... onlineapp.d(15): Error: template `onlineapp.foo2` cannot deduce function from argument types `!()(int)` onlineapp.d(7):Candidate is: `foo2(T)(Unqual!T x)` */ And this is telling you it had a signed value - int - which means it doesn't match. For the other ones, the functions still exist, so it does whatever conversion it needs. Whereas with the template that constraint means the compiler acts like it doesn't exist at all and thus doesn't even attempt an automatic conversion. ? No. If it was unsatisfied constraint, the error would've shown that. What's going on here is that the argument being passed is an int, when the parameter is an Unqual!T. So, https://dlang.org/spec/template.html#ifti would fail because there is no way of figuring out a T from an Unqual!T. Hence the message: cannot deduce function.
Re: Why code failed to compile for foo2?
On Saturday, 11 December 2021 at 23:17:17 UTC, Stanislav Blinov wrote: ? No. If it was unsatisfied constraint, the error would've shown that. And if you try to instantiate it, you'll see it is an unsatisfied constraint anyway. There's two layers of failure here. Using Unqual there is pretty iffy, i wouldn't bother with it at all, but if you do anything, instead qualify it const. But either way, then the constraint still fails since int isn't unsigned. I'd really recommend simplifying this a lot.
Re: Why code failed to compile for foo2?
On Saturday, 11 December 2021 at 23:44:59 UTC, Adam Ruppe wrote: On Saturday, 11 December 2021 at 23:17:17 UTC, Stanislav Blinov wrote: ? No. If it was unsatisfied constraint, the error would've shown that. And if you try to instantiate it, you'll see it is an unsatisfied constraint anyway. There's two layers of failure here. Using Unqual there is pretty iffy, i wouldn't bother with it at all, but if you do anything, instead qualify it const. But either way, then the constraint still fails since int isn't unsigned. I'd really recommend simplifying this a lot. ??? There is no unsatisfied constraint, it doesn't get there :) unq.d(6): Error: template `unq.foo2` cannot deduce function from argument types `!()(int)` unq.d(2):Candidate is: `foo2(T)(Unqual!T x)` ...because passed argument - `int` - becomes `Unqual!T`, making `T` unknown - template arg list is empty. Deduction fails :) If `int` is an `Unqual!T`, what is `T`? The constraint is testing `T`. Now, if you explicitly instantiate - sure, you'd get unsatisfied constraint. But the OP seems to want IFTI, which simply can't work here. @apz28, I can't figure out the intent here. To convert result of abs to an unsigned?
Re: I need some help for my DCV update
On Saturday, 27 November 2021 at 12:16:39 UTC, Ferhat Kurtulmuş wrote: On Saturday, 27 November 2021 at 11:35:21 UTC, Salih Dincer wrote: I also found similar errors but couldn't solve them. I think it has to do with mir.slice.kind. Exactly Kind Topology... I won't use parallel for it as a workaround until it is solved in the mir-algorithm. Linker bug is a compiler bug. We can only find a workaround. The best workaround is to avoid using ndiota with std.parallelism.
Re: Why code failed to compile for foo2?
On Sunday, 12 December 2021 at 00:02:25 UTC, Stanislav Blinov wrote: @apz28, I can't figure out the intent here. To convert result of abs to an unsigned? The function logic works only for unsigned type and the parameter value can be altered in body hence Unqual. If not Unqual, must declare a local var and make a copy. Just asking if this can be done to avoid a cast by caller
unit test broken [DUB bug?]
Running 64-bit Linux ``` dmd --version DMD64 D Compiler v2.098.0-beta.2 dub --version DUB version 1.27.0-beta.2, built on Sep 7 2021 ``` the following code 'compiles' in one project. ```d unittest { gasdindgaslkdgansklnasgdlknaglkgansklsdg; } void main(){} // compiles, links, and 'runs unit tests' ``` dub [shows compiling, linking, then runs] dub test ``` Running dfile-test-library All unit tests have been run successfully. ``` Which made no sense whatsoever until I placed it into a second, different DUB project and catches it immediately using the same commands and test. In a separate dub project I get the error message: ``` widescreen ~main: building configuration "application"... source/app.d(4,1): Error: undefined identifier `gasdindgaslkdgansklnasgdlknaglkgansklsdg` /usr/bin/dmd failed with exit code 1. ``` I'm not doing anything special with DUB and made both projects within a couple weeks of each other. I tried dub clean, dub, dub test. Still broken. dub.json for broken project ```json { "authors": [ "chris" ], "copyright": "Copyright © 2021, chris", "dependencies": { "crypto": "~>0.2.16" }, "description": "A minimal D application.", "license": "proprietary", "name": "dfile" } ``` dub.json for working project ```json { "authors": [ "chris" ], "copyright": "Copyright © 2021, chris", "description": "A minimal D application.", "license": "proprietary", "name": "widescreen" } ``` dub.json.selections (for broken project only) ```json { "fileVersion": 1, "versions": { "crypto": "0.2.16", "intel-intrinsics": "1.6.1" } } ``` Other than unit testing being broken, everything seems to work fine. I even deleted 99.9% of my code and left only the bad unittest code and a main, and it still compiles. Could it be a bug where the previous unit test (at some point) was valid, and it's caching and still running that one? I have a /.dub/code/ d file I found: ```d module dub_test_root; import std.typetuple; static import notes; alias allModules = TypeTuple!(notes); import std.stdio; import core.runtime; void main() { writeln("All unit tests have been run successfully."); } shared static this() { version (Have_tested) { import tested; import core.runtime; import std.exception; Runtime.moduleUnitTester = () => true; enforce(runUnitTests!allModules(new ConsoleTestResultWriter), "Unit tests failed."); } } ``` Which doesn't appear in the "correct, not compiling" project directory which appears just empty. Possibly because it never successfully compiled a unit test suite.
Re: ImportC std support
On Saturday, 11 December 2021 at 22:28:16 UTC, forkit wrote: On Saturday, 11 December 2021 at 21:42:49 UTC, ManKey wrote: umm... the site has search function you know ;-) Dude, you see, it doesn't say anything about it. It says a little about the extension, but there is no direct answer. This is important because C Std is very dependent on the compiler and its extensions, for example msvc std c does not work with importC. So my question is, are there any implementations of the standard C library that importC supports?