123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- discard """
- targets: "c js"
- """
- import std/[lists, sequtils]
- const
- data = [1, 2, 3, 4, 5, 6]
- template main =
- block SinglyLinkedListTest1:
- var L: SinglyLinkedList[int]
- for d in items(data): L.prepend(d)
- for d in items(data): L.add(d)
- doAssert($L == "[6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6]")
- doAssert(4 in L)
- block SinglyLinkedListTest2:
- var L: SinglyLinkedList[string]
- for d in items(data): L.prepend($d)
- doAssert($L == """["6", "5", "4", "3", "2", "1"]""")
- doAssert("4" in L)
- block DoublyLinkedListTest1:
- var L: DoublyLinkedList[int]
- for d in items(data): L.prepend(d)
- for d in items(data): L.add(d)
- L.remove(L.find(1))
- doAssert($L == "[6, 5, 4, 3, 2, 1, 2, 3, 4, 5, 6]")
- doAssert(4 in L)
- block SinglyLinkedRingTest1:
- var L: SinglyLinkedRing[int]
- L.prepend(4)
- doAssert($L == "[4]")
- L.prepend(4)
- doAssert($L == "[4, 4]")
- doAssert(4 in L)
- block DoublyLinkedRingTest1:
- var L: DoublyLinkedRing[int]
- L.prepend(4)
- doAssert($L == "[4]")
- L.prepend(4)
- doAssert($L == "[4, 4]")
- doAssert(4 in L)
- L.add(3)
- L.add(5)
- doAssert($L == "[4, 4, 3, 5]")
- L.remove(L.find(3))
- L.remove(L.find(5))
- L.remove(L.find(4))
- L.remove(L.find(4))
- doAssert($L == "[]")
- doAssert(4 notin L)
- block tlistsToString:
- block:
- var l = initDoublyLinkedList[int]()
- l.add(1)
- l.add(2)
- l.add(3)
- doAssert $l == "[1, 2, 3]"
- block:
- var l = initDoublyLinkedList[string]()
- l.add("1")
- l.add("2")
- l.add("3")
- doAssert $l == """["1", "2", "3"]"""
- block:
- var l = initDoublyLinkedList[char]()
- l.add('1')
- l.add('2')
- l.add('3')
- doAssert $l == """['1', '2', '3']"""
- # Copied here until it is merged into sequtils
- template take(a: untyped, max: int): untyped =
- type T = typeof(block: (for ai in a: ai))
- var ret: seq[T]
- var i = 0
- if max > 0:
- for ai in a:
- ret.add ai
- i.inc
- if i >= max: break
- ret
- template testCommon(initList, toList) =
- block: # toSinglyLinkedList, toDoublyLinkedList
- let l = seq[int].default
- doAssert l.toList.toSeq == []
- doAssert [1].toList.toSeq == [1]
- doAssert [1, 2, 3].toList.toSeq == [1, 2, 3]
- block copy:
- doAssert array[0, int].default.toList.copy.toSeq == []
- doAssert [1].toList.copy.toSeq == [1]
- doAssert [1, 2].toList.copy.toSeq == [1, 2]
- doAssert [1, 2, 3].toList.copy.toSeq == [1, 2, 3]
- type Foo = ref object
- x: int
- var f0 = Foo(x: 0)
- let f1 = Foo(x: 1)
- var a = [f0].toList
- var b = a.copy
- b.add f1
- doAssert a.toSeq == [f0]
- doAssert b.toSeq == [f0, f1]
- f0.x = 42
- doAssert a.head.value.x == 42
- doAssert b.head.value.x == 42
- block: # add, addMoved
- block:
- var
- l0 = initList[int]()
- l1 = [1].toList
- l2 = [2, 3].toList
- l3 = [4, 5, 6].toList
- l0.add l3
- l1.add l3
- l2.addMoved l3
- doAssert l0.toSeq == [4, 5, 6]
- doAssert l1.toSeq == [1, 4, 5, 6]
- doAssert l2.toSeq == [2, 3, 4, 5, 6]
- doAssert l3.toSeq == []
- l2.add l3 # re-adding l3 that was destroyed is now a no-op
- doAssert l2.toSeq == [2, 3, 4, 5, 6]
- doAssert l3.toSeq == []
- block:
- var
- l0 = initList[int]()
- l1 = [1].toList
- l2 = [2, 3].toList
- l3 = [4, 5, 6].toList
- l3.addMoved l0
- l2.addMoved l1
- doAssert l3.toSeq == [4, 5, 6]
- doAssert l2.toSeq == [2, 3, 1]
- l3.add l0
- doAssert l3.toSeq == [4, 5, 6]
- block:
- var c = [0, 1].toList
- c.addMoved c
- doAssert c.take(6) == [0, 1, 0, 1, 0, 1]
- block: # prepend, prependMoved
- block:
- var
- l0 = initList[int]()
- l1 = [1].toList
- l2 = [2, 3].toList
- l3 = [4, 5, 6].toList
- l0.prepend l3
- l1.prepend l3
- doAssert l3.toSeq == [4, 5, 6]
- l2.prependMoved l3
- doAssert l0.toSeq == [4, 5, 6]
- doAssert l1.toSeq == [4, 5, 6, 1]
- doAssert l2.toSeq == [4, 5, 6, 2, 3]
- doAssert l3.toSeq == []
- l2.prepend l3 # re-prepending l3 that was destroyed is now a no-op
- doAssert l2.toSeq == [4, 5, 6, 2, 3]
- doAssert l3.toSeq == []
- block:
- var
- l0 = initList[int]()
- l1 = [1].toList
- l2 = [2, 3].toList
- l3 = [4, 5, 6].toList
- l3.prependMoved l0
- l2.prependMoved l1
- doAssert l3.toSeq == [4, 5, 6]
- doAssert l2.toSeq == [1, 2, 3]
- l3.prepend l0
- doAssert l3.toSeq == [4, 5, 6]
- block:
- var c = [0, 1].toList
- c.prependMoved c
- doAssert c.take(6) == [0, 1, 0, 1, 0, 1]
- block remove:
- var l = [0, 1, 2, 3].toList
- let
- l0 = l.head
- l1 = l0.next
- l2 = l1.next
- l3 = l2.next
- l.remove l0
- doAssert l.toSeq == [1, 2, 3]
- l.remove l2
- doAssert l.toSeq == [1, 3]
- l.remove l2
- doAssert l.toSeq == [1, 3]
- l.remove l3
- doAssert l.toSeq == [1]
- l.remove l1
- doAssert l.toSeq == []
- # Cycle preservation
- var a = [10, 11, 12].toList
- a.addMoved a
- doAssert a.take(6) == @[10, 11, 12, 10, 11, 12]
- a.remove a.head.next
- doAssert a.take(6) == @[10, 12, 10, 12, 10, 12]
- a.remove a.head
- doAssert a.take(6) == @[12, 12, 12, 12, 12, 12]
- testCommon initSinglyLinkedList, toSinglyLinkedList
- testCommon initDoublyLinkedList, toDoublyLinkedList
- block remove: # return value check
- var l = [0, 1, 2, 3].toSinglyLinkedList
- let n = l.head.next.next
- doAssert l.remove(n) == true
- doAssert l.toSeq == [0, 1, 3]
- doAssert l.remove(n) == false
- doAssert l.toSeq == [0, 1, 3]
- doAssert l.remove(l.head) == true
- doAssert l.toSeq == [1, 3]
- doAssert l.remove(l.head.next) == true
- doAssert l.toSeq == [1]
- doAssert l.remove(l.head) == true
- doAssert l.toSeq == []
- static: main()
- main()
|