Custom list class
Posted: Tue Aug 21, 2012 7:30 pm
Stimulated by recent discussion regarding inclusive/exclusive for loops, ranges, etc., I made a custom list class to play around with "going against the grain" with a base index of 1. I also wanted to play with creating a .change method so the elements could be transformed in place without even needing a for loop. Other than that, I haven't used it for anything or fleshed it out completely. Here it is for you to review or play around with if you like:
"""
test with:
cobra -test MyList.cobra
"""
class MyList<of T> implements IEnumerable<of T>
# to-do? implements IList<of T>
"""
Allows for a custom base index and
also has an inclusive range readily available through .maxIndex.
"""
var _items as T[]
var _count = 0
var _capacity = 8
var _minIndex = 1 # fixed for now. always 1
invariant
.minIndex >= 0
(.count == 0) == (.maxIndex < .minIndex)
cue init
base.init
_items = T[](_capacity)
get minIndex from var
get maxIndex as int
ensure result >= 0
return _minIndex + _count - 1
get count from var
pro [index as int] as T
get
require index >= .minIndex and index <= .maxIndex
return _items[index - _minIndex]
set
require index >= .minIndex and index <= .maxIndex
_items[index - _minIndex] = value
def add(item as T)
ensure
this[.maxIndex] == item
.count == old .count + 1
.maxIndex >= .minIndex
body
if _count == _capacity
_capacity <<= 1
newItems = T[](_capacity)
_items.copyTo(newItems, 0)
_items = newItems
_items[_count] = item
_count += 1
def getEnumerator as IEnumerator<of T>
for i in _count, yield _items[i]
def getEnumerator as System.Collections.IEnumerator
implements System.Collections.IEnumerable
return .getEnumerator
def change(changer as ChangeMethod)
"""
Change each element in the list. By using this method you don't even have to loop
through the indexes.
"""
ensure .count == old .count
for i in _count, _items[i] = changer(_items[i]) to T
sig ChangeMethod(item) as dynamic # to-do: put this in MyList and make strongly typed
class TestMyList
test basics
t = MyList<of int>()
assert t.count == 0
assert t.minIndex == 1
assert t.maxIndex == 0
counter = 0
for item in t, counter += 1
assert counter == 0
test add
t = MyList<of int>()
t.add(3)
assert t.count == 1
assert t[1] == 3
expect Exception, assert t[0] == 3
expect Exception, assert t[2] == 3
counter = 0
for x in t
assert x == 3
counter += 1
assert counter == 1
test exceedCapacity
t = MyList<of int>()
for i in 1 : 16+1, t.add(i)
assert t.count == 16
for i in t.minIndex : t.maxIndex+1, assert t[i] == i
test toList
t = MyList<of String>()
t.add('a')
t.add('b')
assert t.toList == ['a', 'b']
test change
t = MyList<of String>()
t.add('a')
t.add('b')
t.change(do(item)=item.toUpper)
assert t.toList == ['A', 'B']
t.change(do(item))
return item.toLower
assert t.toList == ['a', 'b']