On Tuesday, 2 October 2012 at 17:13:48 UTC, Jonathan M Davis wrote:
On Tuesday, October 02, 2012 15:17:58 monarch_dodra wrote:
You might think "just use typeof(length)" BUT:
*you aren't even guaranteed that "typeof(length)" will be
correct! Certain ranges, such as iota, will return a length
usually of type uint, but be indexed with ulong... :/
*Infinite ranges don't have length...

I'd argue that that's a bug in iota. iota's length even specifically returns
_IndexType_.

It makes no sense for length, opIndex, or opSlice to vary in type at all. They should all use the same type (ideally size_t). The fact that it's not outright required to be size_t is bad enough (though IIRC iota had some good reasons
for using ulong).

To be honest, I think I may have put too much stress on the "details". I agree we may want to enforce they have matching types (or at least, a smart hierarchy). That wasn't the root if the reason for IndexType.

The "big picture issue" here is writing wrapper ranges, such as "AssumeSorted". Or "take", or every other sweet-ass range adaptors we have in std.range. If "take" doesn't know how to index the sub-range, how can it properly work with ranges that always use ulong, AND at the same time, support that ranges that always use size_t (uint on x86)? Answer: It CAN'T.

CAN'T CAN'T CAN'T.

Keep in mind, infinite ranges don't have length, so that's out of the equation...

These are not big changes I'm proposing, but they *may* break
some existing ranges. Those ranges are arguably retarded, and
these changes would enforce correctness, but they'd break none
the less. I'd like some feedback if you think this trait is worth
pushing?

Requiring that length, opIndex, and opSlice all use the same index type would be very much the right way to go IMHO. If that's done however, I don't know if we'll really need IndexType (though it may still be a good idea to add it).

In addition, I'd argue that they should require that they all be at least as large as size_t (ideally, they'd even have to be either size_t or ulong and that's it - no signed types allowed), but that may be too strict at this point given that it could break existing code that did stupid stuff like use int
(which _way_ too many people seem inclined to do).

- Jonathan M Davis

You'd still need IndexType for the reasons mentioned above, unless you wanted to write "auto opIndex(ParameterTypeTuple(R.opIndex)[1] n)" in all your ranges. AND, you'd require the array specialization (which would default to size_t).

The actual support of things smaller than size_t, at that point, would become a non-issue. Just:

//----
static if (isRandomAccessRange!R)
    auto opIndex(IndexType!R n)
    {
        return r[n];
    }
//----

Clean, concise. Supports both size_t and ulong (and others).

Reply via email to