Why does enumerate over range return dchar, when ranging without returns char?

rikki cattermole rikki at cattermole.co.nz
Thu May 3 05:56:26 UTC 2018


On 03/05/2018 5:44 PM, James Blachly wrote:
> I am puzzled why enumerating in a foreach returns a dchar (which forces 
> me to cast), whereas without the enumerate the range returns a char as 
> expected.
> 
> Example:
> 
> ```
> import std.stdio;
> import std.range : enumerate;
> 
> void main()
> {
>      char[] s = ['a','b','c'];
> 
>      char[3] x;
>      auto i = 0;
>      foreach(c; s) {
>          x[i] = c;
>          i++;
>      }
> 
>      writeln(x);
> }
> ```
> Above works without cast.
> 
> '''
> import std.stdio;
> import std.range : enumerate;
> 
> void main()
>      {
>      char[] s = ['a','b','c'];
> 
>      char[3] x;
>      foreach(i, c; enumerate(s)) {
>          x[i] = c;
>          i++;
>      }
> 
>      writeln(x);
> }
> ```
> Above fails without casting c to type char.
> 
> The function signature for enumerate shows "auto" return type, so that 
> does not help me understand.
> 
> Kind regards

The first example uses auto-decoding (UTF-8 codepoints into a single 
UTF-32 one). This is considered a bad thing. But the compiler can 
disable it and leave it as UTF-8 code point upon request.

The second example returns a Voldemort type (means no-name) which 
happens to be an input range. Where it can't disable anything and has 
been told that it is returning a dchar. See[0] as to where this gets 
decoded. Writing two small functions to replace it (and popFront), will 
override this behavior.

[0] https://dlang.org/phobos/std_range_primitives.html#.front


More information about the Digitalmars-d-learn mailing list