mirror of
https://github.com/odin-lang/Odin.git
synced 2025-12-29 09:24:33 +00:00
75 lines
1.0 KiB
Odin
75 lines
1.0 KiB
Odin
package container
|
|
|
|
|
|
Ring :: struct($T: typeid) {
|
|
next, prev: ^Ring(T),
|
|
value: T,
|
|
}
|
|
|
|
ring_init :: proc(r: ^$R/Ring) -> ^R {
|
|
r.prev, r.next = r, r;
|
|
return r;
|
|
}
|
|
|
|
ring_next :: proc(r: ^$R/Ring) -> ^R {
|
|
if r.next == nil {
|
|
return ring_init(r);
|
|
}
|
|
return r.next;
|
|
}
|
|
ring_prev :: proc(r: ^$R/Ring) -> ^R {
|
|
if r.prev == nil {
|
|
return ring_init(r);
|
|
}
|
|
return r.prev;
|
|
}
|
|
|
|
|
|
ring_move :: proc(r: ^$R/Ring, n: int) -> ^R {
|
|
r := r;
|
|
if r.next == nil {
|
|
return ring_init(r);
|
|
}
|
|
|
|
switch {
|
|
case n < 0:
|
|
for _ in n..<0 {
|
|
r = r.prev;
|
|
}
|
|
case n > 0:
|
|
for _ in 0..<n {
|
|
r = r.next;
|
|
}
|
|
}
|
|
return r;
|
|
}
|
|
|
|
ring_link :: proc(r, s: ^$R/Ring) -> ^R {
|
|
n := ring_next(r);
|
|
if s != nil {
|
|
p := ring_prev(s);
|
|
r.next = s;
|
|
s.prev = r;
|
|
n.prev = p;
|
|
p.next = n;
|
|
}
|
|
return n;
|
|
}
|
|
ring_unlink :: proc(r: ^$R/Ring, n: int) -> ^R {
|
|
if n <= 0 {
|
|
return nil;
|
|
}
|
|
return ring_link(r, ring_move(r, n+1));
|
|
}
|
|
ring_len :: proc(r: ^$R/Ring) -> int {
|
|
n := 0;
|
|
if r != nil {
|
|
n = 1;
|
|
for p := ring_next(r); p != r; p = p.next {
|
|
n += 1;
|
|
}
|
|
}
|
|
return n;
|
|
}
|
|
|