Re: How to loop through characters of a string in D language?

2021-12-11 Thread Ola Fosheim Grøstad via Digitalmars-d-learn

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?

2021-12-11 Thread Ola Fosheim Grøstad via Digitalmars-d-learn
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?

2021-12-11 Thread forkit via Digitalmars-d-learn
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?

2021-12-11 Thread Ola Fosheim Grøstad via Digitalmars-d-learn

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?

2021-12-11 Thread Stanislav Blinov via Digitalmars-d-learn
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?

2021-12-11 Thread Ola Fosheim Grøstad via Digitalmars-d-learn
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?

2021-12-11 Thread Ola Fosheim Grøstad via Digitalmars-d-learn

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?

2021-12-11 Thread Ola Fosheim Grøstad via Digitalmars-d-learn
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?

2021-12-11 Thread Stanislav Blinov via Digitalmars-d-learn
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?

2021-12-11 Thread Ola Fosheim Grøstad via Digitalmars-d-learn
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?

2021-12-11 Thread russhy via Digitalmars-d-learn

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?

2021-12-11 Thread Matheus via Digitalmars-d-learn
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?

2021-12-11 Thread Matheus via Digitalmars-d-learn

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?

2021-12-11 Thread Rumbu via Digitalmars-d-learn

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?

2021-12-11 Thread russhy via Digitalmars-d-learn

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?

2021-12-11 Thread frame via Digitalmars-d-learn

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?

2021-12-11 Thread Paul Backus via Digitalmars-d-learn

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

2021-12-11 Thread ManKey via Digitalmars-d-learn
What implementations of the C standard library does importC 
support?


Re: ImportC std support

2021-12-11 Thread forkit via Digitalmars-d-learn

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?

2021-12-11 Thread apz28 via Digitalmars-d-learn

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?

2021-12-11 Thread Adam Ruppe via Digitalmars-d-learn

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?

2021-12-11 Thread Stanislav Blinov via Digitalmars-d-learn

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?

2021-12-11 Thread Adam Ruppe via Digitalmars-d-learn
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?

2021-12-11 Thread Stanislav Blinov via Digitalmars-d-learn

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

2021-12-11 Thread 9il via Digitalmars-d-learn
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?

2021-12-11 Thread apz28 via Digitalmars-d-learn
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?]

2021-12-11 Thread Chris Katko via Digitalmars-d-learn

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

2021-12-11 Thread ManKey via Digitalmars-d-learn

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?