"IndexType" for ranges

monarch_dodra monarchdodra at gmail.com
Tue Oct 2 10:27:46 PDT 2012


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


More information about the Digitalmars-d mailing list