struct T* TV_init(struct TV *vecv, struct T *vec, struct Slice *slc, BOOL isSub) { test_assert( Slice_first(slc) < vec->size && Slice_last (slc) < vec->size, "slice out of range" ); struct T* vw = &vecv->T; vw->value = Slice_start (slc)*vec->stride + vec->value; vw->size = Slice_size (slc); vw->stride = isSub ? Slice_stride(slc) : Slice_stride(slc)*vec->stride; vecv->ref = vec; return vw; }
defmethod(OBJ, gputAt, Array, Int, Object) U32 i = Range_index(self2->value, self->size); test_assert( i < self->size, "index out of range" ); OBJ *dst = self->object + i*self->stride; assign(dst, _3); retmethod(_1); endmethod defmethod(OBJ, gputAt, Array, Slice, Object) PRE test_assert( Slice_first(self2) < self->size && Slice_last (self2) < self->size, "slice out of range" ); BODY U32 dst_n = Slice_size (self2); I32 dst_s = Slice_stride(self2)*self->stride; OBJ *dst = Slice_start (self2)*self->stride + self->object; OBJ *end = dst + dst_s*dst_n; while (dst != end) { assign(dst, _3); dst += dst_s; } retmethod(_1); endmethod // move to sequence?
void ut_slice(void) { useclass(Slice); UTEST_START("Slice") // equality and default args UTEST( Slice_isEqual(atSlice(10) , atSlice(0,10, 1)) ); UTEST( Slice_isEqual(atSlice(0,10), atSlice(0,10, 1)) ); UTEST(!Slice_isEqual(atSlice(0,10), atSlice(0,10,-1)) ); UTEST( Slice_isEqual(atSlice(0,10), atSlice(0,10, 0)) ); UTEST( gisEqual(aSlice(10) , aSlice(0,10, 1)) == True ); UTEST( gisEqual(aSlice(0,10), aSlice(0,10, 1)) == True ); UTEST( gisEqual(aSlice(0,10), aSlice(0,10,-1)) == False ); // new vs auto UTEST( isEq(gnewSlc(Slice, 0, 10, 1), aSlice(0,10,1)) ); UTEST(!isEq(gnewSlc(Slice, 0, 10, 1), aSlice(0,10,-1)) ); // clone vs auto UTEST( isEq(gclone(aSlice(10)), aSlice(10)) ); UTEST( isEq(gclone(aSlice(0,10)), aSlice(0,10)) ); UTEST( isEq(gclone(aSlice(0,10,-1)), aSlice(0,10,-1)) ); // eval UTEST( Slice_eval(atSlice(10),0) == 0 ); UTEST( Slice_eval(atSlice(10),1) == 1 ); UTEST( Slice_eval(atSlice(10),10) == 10 ); UTEST( Slice_eval(atSlice(1,10),0) == 1 ); UTEST( Slice_eval(atSlice(1,10),1) == 2 ); UTEST( Slice_eval(atSlice(1,10),10) == 11 ); UTEST( Slice_eval(atSlice(1,10,2),0) == 1 ); UTEST( Slice_eval(atSlice(1,10,2),1) == 3 ); UTEST( Slice_eval(atSlice(1,10,2),10) == 21 ); UTEST( Slice_eval(atSlice(10,1,-2),0) == 10 ); UTEST( Slice_eval(atSlice(10,1,-2),1) == 8 ); UTEST( Slice_eval(atSlice(10,1,-2),10) == -10 ); // first UTEST( Slice_first(atSlice(10)) == 0 ); UTEST( Slice_first(atSlice(1,10)) == 1 ); UTEST( Slice_first(atSlice(-1,10)) == (U32)-1 ); UTEST( Slice_first(atSlice(-1,-10)) == (U32)-1 ); // last UTEST( Slice_last(atSlice(10)) == 9 ); UTEST( Slice_last(atSlice(1,10)) == 10 ); UTEST( Slice_last(atSlice(1,10,2)) == 19 ); UTEST( Slice_last(atSlice(0,-10)) == (U32)-11 ); UTEST( Slice_last(atSlice(-1,-10)) == (U32)-12 ); // size UTEST( Slice_size(atSlice(0,9,1)) == 9 ); UTEST( Slice_size(atSlice(1,10,1)) == 10 ); UTEST( Slice_size(atSlice(1,10,2)) == 10 ); UTEST( Slice_size(atSlice(1,10,3)) == 10 ); UTEST( Slice_size(atSlice(1,9,3)) == 9 ); UTEST( Slice_size(atSlice(9,0,-1)) == 0 ); UTEST( Slice_size(atSlice(10,1,-1)) == 1 ); UTEST( Slice_size(atSlice(10,1,-2)) == 1 ); UTEST( Slice_size(atSlice(10,1,-3)) == 1 ); UTEST( Slice_size(atSlice(9,1,-3)) == 1 ); // slice vs range UTEST( eq(Slice_fromRange(atSlice(0), atRange(-1,1,1), 0), atSlice(-1,3,1)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(-1,1,2), 0), atSlice(-1,2,2)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(-1,5,3), 0), atSlice(-1,3,3)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(-1,4,3), 0), atSlice(-1,2,3)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange( 1,5,3), 0), atSlice( 1,2,3)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(9,0,-1), 0), atSlice(9,10,-1)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(9,1,-2), 0), atSlice(9,5,-2)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(9,0,-3), 0), atSlice(9,4,-3)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(9,3,-3), 0), atSlice(9,3,-3)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(0,9,1) , 0), atSlice(0,10,1)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(1,10,1), 0), atSlice(1,10,1)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(1,9,2) , 0), atSlice(1,5,2)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(1,10,3), 0), atSlice(1,4,3)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(1,7,3) , 0), atSlice(1,3,3)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(9,0,-1) , 0), atSlice(9,10,-1)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(10,1,-1), 0), atSlice(10,10,-1)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(10,2,-2), 0), atSlice(10,5,-2)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(10,1,-3), 0), atSlice(10,4,-3)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(9,3,-3) , 0), atSlice(9,3,-3)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(-1,-10,-1), 0), atSlice(-1,10,-1)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(-1,-9,-2) , 0), atSlice(-1,5,-2)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(-1,-10,-3), 0), atSlice(-1,4,-3)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(-1,-7,-3) , 0), atSlice(-1,3,-3)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(-10,-1,1), 0), atSlice(-10,10,1)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(-10,-2,2), 0), atSlice(-10,5,2)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(-10,-1,3), 0), atSlice(-10,4,3)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(-9,-3,3) , 0), atSlice(-9,3,3)) ); UTEST_END }