42 lines
1.0 KiB
Plaintext
42 lines
1.0 KiB
Plaintext
local record Ringbuffer<T>
|
|
{T}
|
|
push: function(self: Ringbuffer<T>, el: T): boolean
|
|
pop: function(self: Ringbuffer<T>): T | nil
|
|
is_empty: function(self: Ringbuffer<T>): boolean
|
|
|
|
head: integer
|
|
n: integer
|
|
size: integer
|
|
end
|
|
|
|
local impl: table = {}
|
|
|
|
impl.push = function<T>(self: Ringbuffer<T>, el: T): boolean
|
|
if self.n == self.size then return false end
|
|
-- items are at head + 0, head + 1, ..., head + (n-1)
|
|
local tail = (self.head + self.n) % self.size
|
|
self[1 + tail] = el
|
|
self.n = self.n + 1
|
|
return true
|
|
end
|
|
|
|
impl.pop = function<T>(self: Ringbuffer<T>): T | nil
|
|
if self.n == 0 then return nil end
|
|
local res = self[1 + self.head]
|
|
self.head = (self.head + 1) % self.size
|
|
self.n = self.n - 1
|
|
return res
|
|
end
|
|
|
|
impl.is_empty = function<T>(self: Ringbuffer<T>): boolean
|
|
return self.n == 0
|
|
end
|
|
|
|
local function new<T>(size: integer): Ringbuffer<T>
|
|
return setmetatable({ head = 0, n = 0, size = size }, { __index = impl })
|
|
end
|
|
|
|
return {
|
|
new = new,
|
|
Ringbuffer = Ringbuffer
|
|
} |