"isDroppable" range trait for slicing to end

Dmitry Olshansky dmitry.olsh at gmail.com
Wed Oct 31 15:14:19 PDT 2012


10/31/2012 10:37 AM, monarch_dodra пишет:
> On Wednesday, 31 October 2012 at 08:58:18 UTC, Jonathan M Davis wrote:
>>
>> I agree, but for that to be realistic, I think that issue# 7177 needs
>> to be
>> implemented first. You should check out the pull request that I have for
>> improving hasSlicing. I just updated it according to some of the
>> discussion
>> here, and it now checks the behavior of opDollar when it works with
>> the range
>> being sliced. For finite ranges, it essentially enforces that they
>> function
>> like arrays do, and for infinite ranges, it comes as close to that as
>> it can:
>>
>> https://github.com/D-Programming-Language/phobos/pull/854
>>
>> As of the latest state of that pull request, hasSlicing looks like
>>
>> template hasSlicing(R)
>> {
>>     enum bool hasSlicing = !isNarrowString!R && is(typeof(
>>     (inout int _dummy=0)
>>     {
>>         R r = void;
>>
>>         static if(isInfinite!R)
>>             typeof(take(r, 1)) s = r[1 .. 2];
>>         else
>>             R s = r[1 .. 2];
>>
>>         s = r[1 .. 2];
>>
>>         static if(is(typeof(r[0 .. $])))
>>         {
>>             R t = r[0 .. $];
>>             t = r[0 .. $];
>>
>>             static if(!isInfinite!R)
>>             {
>>                 R u = r[0 .. $ - 1];
>>                 u = r[0 .. $ - 1];
>>             }
>>         }
>>
>>         static assert(isForwardRange!(typeof(r[1 .. 2])));
>>         static assert(hasLength!(typeof(r[1 .. 2])));
>>     }));
>> }
>>
>>
>> - Jonathn M Davis
>
> I'm not a huge fan of the "opDollar" check, because essentially, it
> doesn't really buy you anything: if hasSlicing!R, then is "r = r[1..$]"
> legal? Who knows! You as a developer need to check manually that "r[0 ..
> $]" is legal first anyways...

That's a temporary thing because otherwise it'll break all of current 
RA. The idea is that if there is $ then it's tested

> Under those circumstances, why not cleanly splice the two notions?
>
> //----
> template hasSlicing(R)
> {
>      enum bool hasSlicing = !isNarrowString!R && is(typeof(
>      (inout int _dummy=0)
>      {
>          R r = void;
>
>          static if(isInfinite!R)
>              typeof(take(r, 1)) s = r[1 .. 2];
>          else
>              R s = r[1 .. 2];
>
>          s = r[1 .. 2];
>
>          static assert(isForwardRange!(typeof(r[1 .. 2])));
>          static assert(hasLength!(typeof(r[1 .. 2])));
>      }));
> }
>
> template hasSlicingToEnd(R)
> {
>      enum bool hasSlicingToEnd = !isNarrowString!R && is(typeof(
>      (inout int _dummy=0)
>      {
>          R r = void;
>
>          static if(is(typeof(r[0 .. $])))
>          {
>              R t = r[0 .. $];
>              t = r[0 .. $];
>
>              static if(!isInfinite!R)
>              {
>                  R u = r[0 .. $ - 1];
>                  u = r[0 .. $ - 1];
>              }
>          }
>      }));
> }
> //----
>
> IMO, this makes a clean distinction between both "types" of slicing. An
> added bonus is that (for now) it also correctly supports finite RA
> ranges that don't define opDollar.

Jonathon's version also supports RA without opDollar.

>
> //----
> PS: Do we really have to force that infinite slice to be of a type of
> "take"? Does that mean we can't imagine an infinite range that defines
> it's own finite slice type?
>
> if we change the code to:
>
> //----
>          static if(isInfinite!R)
>              auto s = r[1 .. 2]; //HERE1
>          else
>              R s = r[1 .. 2];
>
>          s = r[1 .. 2]; //HERE2
> //----
>
> Then we force nothing on the slice's type (HERE1), but do verify that
> subsequent slices will be assignable back to the original slice (HERE2)...

Well I'd rather never check that infinite range has 1..2 form of slicing 
to begin with. If we have some that do then we'd have to keep it.

-- 
Dmitry Olshansky


More information about the Digitalmars-d mailing list