I found these quite useful for particular slicing:
    
    
    template `..>`*[T, U](a: T, b: U): untyped =
        ## Binary slice operator constructing an interval based on offsset 'a' 
and length 'b'.
        ## 'b' can always be a BackwardsIndex. When combined with [] slicing, 
'a' can also be a BackwardsIndex.
        ## When the length is BackwardsIndex then the resulting interval 
provides 'b' indeces before (excluding) 'a',
        ## otherwise the resulting interval provides 'b' indeces starting with 
(including) 'a'
        when b is BackwardsIndex:
            when a is BackwardsIndex:  ^(a.int + b.int) .. ^(succ(a.int))
            else:                            (a - T(b)) .. pred(a)
        else:
            when a is BackwardsIndex:  a .. ^(U(a) - pred(b))
            else:                      a .. pred(a + b)
    
    iterator `..>`*[T, U](a: T, b: U): T =
        # generator of 'b' indeces before or from 'a'
        when b is BackwardsIndex:
            var i = a - T(b)
            while i < a:
                yield i
                inc i
        else:
            var i = a
            while i < (a + b):
                yield i
                inc i
    
    let a = ["a0","a1","a2","a3","a4","a5","a6","a7","a8","a9"]
    echo a[5 ..> 3]    # @["a5", "a6", "a7"]
    echo a[5 ..> ^3]   # @["a2", "a3", "a4"]
    echo a[^4 ..> 3]   # @["a6", "a7", "a8"]
    echo a[^4 ..> ^6]  # @["a0", "a1", "a2", "a3", "a4", "a5"]
    
    for i in 5 ..> 3: echo i
    for i in 5 ..> ^7: echo i
    
    
    Run

Reply via email to