// Index types: // all // end // end-5 // range(2,6) // range(1,end) // range(1,end-5) // range(end-5,end) // range(end-5,end-2) struct All {} All all; struct End { EndRel opSub(uint x) { return EndRel(x); } } End end; struct EndRel { uint x; static EndRel opCall(uint x) { EndRel r; r.x = x; return r; } } struct Range { uint start,end; } struct RangeEnd { uint start; EndRel end; } struct RangeToEnd { uint start; } struct RangeEndEnd { EndRel start; EndRel end; } struct RangeEndToEnd { EndRel start; } Range range(uint start, uint end) { Range r; r.start = start; r.end = end; return r; } RangeEnd range(uint start, EndRel end) { RangeEnd r; r.start = start; r.end = end; return r; } RangeToEnd range(uint start, End end) { RangeToEnd r; r.start = start; return r; } RangeEndEnd range(EndRel start, EndRel end) { RangeEndEnd r; r.start = start; r.end = end; return r; } RangeEndToEnd range(EndRel start, End end) { RangeEndToEnd r; r.start = start; return r; } template IsRange(T) { const IsRange = is(T == All) || is(T == Range) || is(T == RangeEnd) || is(T == RangeToEnd) || is(T == RangeEndEnd) || is(T == RangeEndToEnd); }