Thread overview
Re: count until predicate returns false
Aug 15, 2011
Jonathan M Davis
Aug 15, 2011
David Nadlinger
Aug 15, 2011
Jonathan M Davis
Aug 15, 2011
Andrej Mitrovic
Aug 15, 2011
Jonathan M Davis
Aug 15, 2011
Andrej Mitrovic
Aug 15, 2011
bearophile
Aug 15, 2011
Andrej Mitrovic
August 15, 2011
On Monday, August 15, 2011 12:53 Andrej Mitrovic wrote:
> This will print the count of whitespace chars in a line:
> 
> writeln(count!isWhite(line));
> 
> What I need is the count of whitspace chars until the first non-whitespace char is found, essentially I need a "countWhile" template:
> 
> writeln(countWhile!isWhite(line));
> 
> Can I do this with existing templates somehow?

writeln(count!(not!isWhite)(line));

- Jonathan M Davis
August 15, 2011
On 8/15/11 11:00 PM, Jonathan M Davis wrote:
> On Monday, August 15, 2011 12:53 Andrej Mitrovic wrote:
>> This will print the count of whitespace chars in a line:
>>
>> writeln(count!isWhite(line));
>>
>> What I need is the count of whitspace chars until the first
>> non-whitespace char is found, essentially I need a "countWhile"
>> template:
>>
>> writeln(countWhile!isWhite(line));
>>
>> Can I do this with existing templates somehow?
>
> writeln(count!(not!isWhite)(line));
>
> - Jonathan M Davis

Wouln't this rather count the total number of whitespace characters in a line? Did you mean writeln(countUntil!(not!isWhite)(line))?

David
August 15, 2011
On Monday, August 15, 2011 14:09 David Nadlinger wrote:
> On 8/15/11 11:00 PM, Jonathan M Davis wrote:
> > On Monday, August 15, 2011 12:53 Andrej Mitrovic wrote:
> >> This will print the count of whitespace chars in a line:
> >> 
> >> writeln(count!isWhite(line));
> >> 
> >> What I need is the count of whitspace chars until the first non-whitespace char is found, essentially I need a "countWhile" template:
> >> 
> >> writeln(countWhile!isWhite(line));
> >> 
> >> Can I do this with existing templates somehow?
> > 
> > writeln(count!(not!isWhite)(line));
> > 
> > - Jonathan M Davis
> 
> Wouln't this rather count the total number of whitespace characters in a
> line? Did you mean writeln(countUntil!(not!isWhite)(line))?

You're right. I misunderstood what count did.

- Jonathan M Davis
August 15, 2011
That doesn't work:

import std.algorithm;
import std.stdio;
import std.functional;
import std.uni;

void main()
{
    auto line = "  foo";
    writeln(countUntil!(not!isWhite)(line));
}

test.d(9): Error: template std.algorithm.countUntil(alias pred = "a ==
b",R1,R2) if (is(typeof(startsWith!(pred)(haystack,needle)))) does not
match any function template declaration
test.d(9): Error: template std.algorithm.countUntil(alias pred = "a ==
b",R1,R2) if (is(typeof(startsWith!(pred)(haystack,needle)))) cannot
deduce template function from argument types !(not)(string)
test.d(9): Error: template instance errors instantiating template
August 15, 2011
On Monday, August 15, 2011 15:15 Andrej Mitrovic wrote:
> That doesn't work:
> 
> import std.algorithm;
> import std.stdio;
> import std.functional;
> import std.uni;
> 
> void main()
> {
> auto line = " foo";
> writeln(countUntil!(not!isWhite)(line));
> }
> 
> test.d(9): Error: template std.algorithm.countUntil(alias pred = "a ==
> b",R1,R2) if (is(typeof(startsWith!(pred)(haystack,needle)))) does not
> match any function template declaration
> test.d(9): Error: template std.algorithm.countUntil(alias pred = "a ==
> b",R1,R2) if (is(typeof(startsWith!(pred)(haystack,needle)))) cannot
> deduce template function from argument types !(not)(string)
> test.d(9): Error: template instance errors instantiating template

No, it doesn't. Because the currently released countUntil requires a second range to compare against (the predicate defaulting to "a == b"). However, there _is_ a new overload for countUntil on github which takes the predicate and one range like you're trying to do. And _that_ should work. If it doesn't, then it needs to be fixed.

I'd actually added it the other day and then thought that I'd figured out that count did it already and so I reverted it - but I'd misread what count did, not realizing that it counted the _whole_ range not just until the predicate failed. So, I've reverted my revert, and if you use Phobos from github, you should get the version of countUntil that you want.

- Jonathan M Davis
August 15, 2011
Thanks, but I'll wait for the next release before I use it. In the meantime I guess I'll use this monster:

array(until!(not!isWhite)(line)).length
August 15, 2011
Andrej Mitrovic:

> In the meantime I guess I'll use this monster:
> 
> array(until!(not!isWhite)(line)).length

This is better:

import std.algorithm, std.range, std.ascii, std.functional;

void main() {
    string line = "   foo ";
    size_t n = walkLength(until!(not!isWhite)(line));
    assert(n == 3);
}

Bye,
bearophile
August 15, 2011
Thanks!