#-- vec.p7i # #-- a growing vector, like java.util.Vector p7source testing.p7i p7class Vec { (TYPE*)v (int)len } p7proc (Vec)vnew { } { vnew 8 } p7proc (Vec)vnew { (int)capacity } { new (Vec)z set z(v) [new (TYPE*) $capacity] return $z } p7proc (int)vlen { (Vec)this } { return $len } p7proc (void)vsetlen { (Vec)this (int)n } { vgrowatleast $this $n set len $n } p7proc (tcl)vget { (Vec)this (int)i } { vchecklen $this $i return $v($i) } p7proc (void)vset { (Vec)this (int)i (TYPE)x } { vchecklen $this $i set v($i) $x } p7proc (void)vappend { (Vec)this (TYPE)x } { vsetlen $this (len+1) set v(len-1) $x ;# len changed, but (len-1) is always the last } p7proc (TYPE)vpop { (Vec)this (TYPE)x } { if { len==0 } { error "cannot pop from empty Vec" } set (TYPE)z $v(len-1) vsetlen $this (len-1) return $z } p7proc (tcl)vpop { (Vec)this (TYPE)x } { vpop $this $x } p7proc (void)vchecklen { (Vec)this (int)i } { if ( i < 0 ) { error "Vec index cannot be negative: $i" } if ( len <= i ) { error "Vec index too big: index is $i but len is $len" } } p7proc (void)vgrow { (Vec)this (int)newCapacity } { if ( [len v] >= newCapacity ) {return} ;# already big enough new (TYPE*)z $newCapacity loop (int)i [len $v] { set z(i) $v(i) } set v $z } p7proc (void)vgrowatleast { (Vec)this (int)requirement } { set (int)n [len v] if ( n >= requirement ) {return} ;# already big enough vgrow $this ( n+n > requirement ? n+n : requirement ) ;# at least double len } ####### TESTS ############ p7test Empty1 { set (Vec)vec [ vnew ] k ( 0 == [vlen $vec] ) } p7test Empty2 { set (tcl)vec [ vnew ] k ( 0 == [vlen $vec] ) } p7test Append1 { set (Vec)vec [ vnew ] vappend $vec null k ( 1 == [vlen $vec] ) } p7test Append2 { set (tcl)vec [ vnew ] vappend $vec null k ( 1 == [vlen $vec] ) }