Coverage for src/fifo.mys : 100%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1from string import StringBuilder
3class FifoError(Error):
4 message: string
6@generic(T)
7class Fifo:
8 """A fixed size fifo.
10 """
12 _read_index: i64
13 _read_length: i64
14 _items: [T]
16 func __init__(self, capacity: i64):
17 self._read_index = 0
18 self._read_length = 0
19 self._items = []
21 for _ in range(capacity):
22 self._items.append(default(T))
24 func length(self) -> i64:
25 """Returns the number of items in the fifo.
27 """
29 return self._read_length
31 func is_full(self) -> bool:
32 """Returns True if the fifo is full, False otherwise.
34 """
36 return self._read_length == self._items.length()
38 func is_empty(self) -> bool:
39 """Returns True if the fifo is empty, False otherwise.
41 """
43 return self._read_length == 0
45 func push(self, item: T):
46 """Push an item on the fifo.
48 """
50 if self.is_full():
51 raise FifoError("cannot push to full fifo")
53 write_index = (self._read_index + self._read_length) % self._items.length()
54 self._items[write_index] = item
55 self._read_length += 1
57 func pop(self) -> T:
58 """Pop an item from the fifo.
60 """
62 if self.is_empty():
63 raise FifoError("cannot pop from empty fifo")
65 item = self._items[self._read_index]
66 self._read_index += 1
67 self._read_index %= self._items.length()
68 self._read_length -= 1
70 return item
72 func __str__(self) -> string:
73 builder = StringBuilder()
74 builder += "Fifo(items=["
76 for offset in range(i64(self._read_length)):
77 index = self._read_index + offset
78 index %= self._items.length()
80 if offset != 0:
81 builder += ", "
83 builder += str(self._items[index])
85 builder += "])"
87 return builder.to_string()
89test fifo():
90 fifo = Fifo[string](10)
91 assert fifo.length() == 0
92 assert fifo.is_empty()
93 assert not fifo.is_full()
95 try:
96 message = ""
97 fifo.pop()
98 except FifoError as error:
99 message = error.message
101 assert message == "cannot pop from empty fifo"
103 fifo.push("foo")
104 assert fifo.pop() == "foo"
106 try:
107 message = ""
108 fifo.pop()
109 except FifoError as error:
110 message = error.message
112 assert message == "cannot pop from empty fifo"
114 for i in range(10):
115 assert not fifo.is_full()
116 fifo.push(str(i))
117 assert fifo.length() == i + 1
118 assert not fifo.is_empty()
120 try:
121 message = ""
122 fifo.push("11")
123 except FifoError as error:
124 message = error.message
126 assert message == "cannot push to full fifo"
128 assert fifo.length() == 10
129 assert fifo.is_full()
130 assert not fifo.is_empty()
132 for i in range(10):
133 assert fifo.pop() == str(i)
134 assert fifo.length() == 9 - i
136test str():
137 fifo = Fifo[string](10)
138 assert str(fifo) == "Fifo(items=[])"
140 fifo.push("1")
141 # ToDo: Support optional.
142 # fifo.push(None)
143 fifo.push("2")
144 # assert str(fifo) == "Fifo(items=[\"1\", None, \"2\"])"
145 assert str(fifo) == "Fifo(items=[\"1\", \"2\"])"
147 # fifo.pop()
148 fifo.pop()
149 assert str(fifo) == "Fifo(items=[\"2\"])"
151test capacity_zero():
152 fifo = Fifo[bytes](0)
153 assert fifo.is_empty()
154 assert fifo.is_full()
156test i32():
157 fifo = Fifo[i32](1)
158 fifo.push(5)
159 assert fifo.pop() == 5