Built-in range type

bearophile bearophileHUGS at lycos.com
Wed Apr 28 10:04:32 PDT 2010


Lionello Lunesu:

>Wouldn't it be nice to introduce a built-in for these int..int ranges?<

It was discussed in the past, but there are some design problems.

In theory it can be used to define overload of slices operator as:
opSliceAssign(int v, Slice s)

A problem is that slices can have more than just size_t indices, this code works and 'i' is of type long:

import std.stdio: writeln;
void main() {
    foreach (i; (long.max - 10) .. (long.max - 1))
        writeln(typeid(typeof(i)), " ", i);
}

So the (immutable) Slice struct has to be a template:
opSliceAssign(int v, Slice!size_t s)


struct Slice(TIndex) {
    immutable TIndex start, stop;
    immutable int stride; // simplified
    immutable SliceType type;
    this(...) {...}
    // few methods: in operator, length, subslicing, etc.
}

So it's usually 4 CPU words long on 32 bit CPUs (it can be just 3 words long on 64 bit CPUs if stride and type are presented in 32 bit each).

The stride is the third optional value, usually it's 1, its syntax can be:
start .. stop : stride

The stride is an int because it can be negative. If start and stop are long, you can't have a stride larger than an int min-max values.

'type' is a bitfield that encodes the kind of Slice. I think the cases are:

1 .. 7
0 .. $
0 .. $-10
1 .. 7 : 2
0 .. $ : 2
0 .. $-10 : 2
  .. 7
  .. $
  .. $-10
  .. 7 : 2
  .. $ : 2
  .. $-10 : 2


(The cases with no start are meant to be useful for intervals infinite on the left. I am not sure this is an important group of cases.)


The Chapel language generalizes this idea into the idea of "domain", a first-class index set.
I have explained it here, and I think it's an useful idea:
http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=87311

Bye,
bearophile



More information about the Digitalmars-d mailing list