Thread overview
Ranges and Library and toir.c internal error
Nov 01, 2012
bearophile
Nov 01, 2012
Ellery Newcomer
October 31, 2012
There may be a better way to solve this but I'm trying to learn Phobos and parameter typing and anonymous function, etc.  So this is probably more of an academic question but I've got the following code:

int countBetween(T)(T[] x, T low, T high)
{
   auto k = count!( (x){return ((x >= low) && (x <= high));} ) (x);
   return k;
}

int[] a = [ 9, 77, 1, 13, 76, 17, 4, 27, 99, 5 ];

auto m = countBetween!(int)(a, 1, 25);      // works!


char[] b = ['h', 'e', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'];
	
auto n = countBetween!(char)(b, 'c', 'k');  // fails



The integer call compiles and runs correctly.

The char call doesn't compile and I get a toir.c internal error.


The library definition says count is
size_t count(alias pred = "true", Range)(Range r);


I'm still trying to get my head around Ranges. Is a int array a valid range but a character array not?

Any enlightenment is welcome.


November 01, 2012
StupidIsAsStupidDoes:

> The char call doesn't compile and I get a toir.c internal error.

Such internal errors are compiler bugs that should be added to Bugzilla.

But I have compiled the following program with the latest DMD GIT-head 32 bit Windows, and I see no compiler bugs:


import std.algorithm: count;

int countBetween(T)(T[] x, T low, T high) {
    return x.count!(x => x >= low && x <= high)();
}

void main() {
    int[] a = [9, 77, 1, 13, 76, 17, 4, 27, 99, 5];
    auto m = countBetween(a, 1, 25);

    char[] b = ['h', 'e', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'];
    auto n = countBetween(b, 'c', 'k');
}

Bye,
bearophile
November 01, 2012
On 10/31/2012 04:35 PM, StupidIsAsStupidDoes wrote:
>
> The char call doesn't compile and I get a toir.c internal error.
>

On a recent dmd  build from github, I don't get any ICE, so it may have been fixed. I do get some disconcerting type deduction failures, though...

> I'm still trying to get my head around Ranges. Is a int array a valid
> range but a character array not?

All arrays are valid ranges, but char[], wchar[], and const variations thereof are special. They are treated as ranges of dchar so that you are guaranteed to get complete unicode characters out of them.

your code, modified:

import std.traits;

size_t countBetween(Range)(Range arr, ElementType!Range low, ElementType!Range high) {
    return count!( (x){return ((x >= low) && (x <= high)); })(arr);
}

ought to handle both int[] and char[] properly.