Search code examples
d

A D range that is RandomAccess and hasLength but not hasSlicing?


In the implementation of findSplit in Phobos, we have this special case:

static if (isSomeString!R1 && isSomeString!R2
        || (isRandomAccessRange!R1 && hasSlicing!R1 && hasLength!R1 && hasLength!R2))
{
    auto balance = find!pred(haystack, needle);
    immutable pos1 = haystack.length - balance.length;
    immutable pos2 = balance.empty ? pos1 : pos1 + needle.length;
    return Result!(typeof(haystack[0 .. pos1]),
                   typeof(haystack[pos2 .. haystack.length]))(haystack[0 .. pos1],
                                                              haystack[pos1 .. pos2],
                                                              haystack[pos2 .. haystack.length]);
}

Most of the constraint makes sense here. I understand that we need a range that is random access and that both the haystack and the needle need a size. But the hasSlicing check is surprising to me.

I would expect any range that is both RandomAccess and hasLength to be able to support Slicing. Is there an example range that inherently fundamentally cannot support Slicing despite being RandomAccess and hasLength?

Or is this more of an issue of user potentially providing a range that simply chose to not implement that particular operation for whatever reason?


Solution

  • I went directly to the source with this and asked Andrei Alexandrescu on Twitter. He responded:

    I don't think there's an interesting case of a random access range without slicing (or vice versa). When we introduced ranges we wanted to be as general as possible, but that turned out to be overengineering.