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).