aboutsummaryrefslogtreecommitdiff
path: root/core/container/queue
diff options
context:
space:
mode:
authorFeoramund <161657516+Feoramund@users.noreply.github.com>2025-06-11 07:05:48 -0400
committerFeoramund <161657516+Feoramund@users.noreply.github.com>2025-06-11 11:54:47 -0400
commit27cd508571a8d7c9668147a602225231d5690e63 (patch)
treeafbfae2549ff084326b8388698afb970d5de263b /core/container/queue
parent5bf180d8f9ab3f673f74119c9dbbe239e94ced63 (diff)
container/queue: Fix and add more bounds checking
Diffstat (limited to 'core/container/queue')
-rw-r--r--core/container/queue/queue.odin42
1 files changed, 31 insertions, 11 deletions
diff --git a/core/container/queue/queue.odin b/core/container/queue/queue.odin
index d1040a7c9..43eb14410 100644
--- a/core/container/queue/queue.odin
+++ b/core/container/queue/queue.odin
@@ -80,36 +80,48 @@ reserve :: proc(q: ^$Q/Queue($T), capacity: int) -> runtime.Allocator_Error {
get :: proc(q: ^$Q/Queue($T), #any_int i: int, loc := #caller_location) -> T {
- runtime.bounds_check_error_loc(loc, i, builtin.len(q.data))
+ runtime.bounds_check_error_loc(loc, i, int(q.len))
idx := (uint(i)+q.offset)%builtin.len(q.data)
return q.data[idx]
}
-front :: proc(q: ^$Q/Queue($T)) -> T {
+front :: proc(q: ^$Q/Queue($T), loc := #caller_location) -> T {
+ when !ODIN_NO_BOUNDS_CHECK {
+ ensure(q.len > 0, "Queue is empty.", loc)
+ }
return q.data[q.offset]
}
-front_ptr :: proc(q: ^$Q/Queue($T)) -> ^T {
+front_ptr :: proc(q: ^$Q/Queue($T), loc := #caller_location) -> ^T {
+ when !ODIN_NO_BOUNDS_CHECK {
+ ensure(q.len > 0, "Queue is empty.", loc)
+ }
return &q.data[q.offset]
}
-back :: proc(q: ^$Q/Queue($T)) -> T {
+back :: proc(q: ^$Q/Queue($T), loc := #caller_location) -> T {
+ when !ODIN_NO_BOUNDS_CHECK {
+ ensure(q.len > 0, "Queue is empty.", loc)
+ }
idx := (q.offset+uint(q.len - 1))%builtin.len(q.data)
return q.data[idx]
}
-back_ptr :: proc(q: ^$Q/Queue($T)) -> ^T {
+back_ptr :: proc(q: ^$Q/Queue($T), loc := #caller_location) -> ^T {
+ when !ODIN_NO_BOUNDS_CHECK {
+ ensure(q.len > 0, "Queue is empty.", loc)
+ }
idx := (q.offset+uint(q.len - 1))%builtin.len(q.data)
return &q.data[idx]
}
set :: proc(q: ^$Q/Queue($T), #any_int i: int, val: T, loc := #caller_location) {
- runtime.bounds_check_error_loc(loc, i, builtin.len(q.data))
+ runtime.bounds_check_error_loc(loc, i, int(q.len))
idx := (uint(i)+q.offset)%builtin.len(q.data)
q.data[idx] = val
}
get_ptr :: proc(q: ^$Q/Queue($T), #any_int i: int, loc := #caller_location) -> ^T {
- runtime.bounds_check_error_loc(loc, i, builtin.len(q.data))
+ runtime.bounds_check_error_loc(loc, i, int(q.len))
idx := (uint(i)+q.offset)%builtin.len(q.data)
return &q.data[idx]
@@ -152,7 +164,9 @@ push_front :: proc(q: ^$Q/Queue($T), elem: T) -> (ok: bool, err: runtime.Allocat
// Pop an element from the back of the queue
pop_back :: proc(q: ^$Q/Queue($T), loc := #caller_location) -> (elem: T) {
- assert(condition=q.len > 0, loc=loc)
+ when !ODIN_NO_BOUNDS_CHECK {
+ ensure(q.len > 0, "Queue is empty.", loc)
+ }
q.len -= 1
idx := (q.offset+uint(q.len))%builtin.len(q.data)
elem = q.data[idx]
@@ -171,7 +185,9 @@ pop_back_safe :: proc(q: ^$Q/Queue($T)) -> (elem: T, ok: bool) {
// Pop an element from the front of the queue
pop_front :: proc(q: ^$Q/Queue($T), loc := #caller_location) -> (elem: T) {
- assert(condition=q.len > 0, loc=loc)
+ when !ODIN_NO_BOUNDS_CHECK {
+ ensure(q.len > 0, "Queue is empty.", loc)
+ }
elem = q.data[q.offset]
q.offset = (q.offset+1)%builtin.len(q.data)
q.len -= 1
@@ -209,7 +225,9 @@ push_back_elems :: proc(q: ^$Q/Queue($T), elems: ..T) -> (ok: bool, err: runtime
// Consume `n` elements from the front of the queue
consume_front :: proc(q: ^$Q/Queue($T), n: int, loc := #caller_location) {
- assert(condition=int(q.len) >= n, loc=loc)
+ when !ODIN_NO_BOUNDS_CHECK {
+ ensure(q.len >= uint(n), "Queue does not have enough elements to consume.", loc)
+ }
if n > 0 {
nu := uint(n)
q.offset = (q.offset + nu) % builtin.len(q.data)
@@ -219,7 +237,9 @@ consume_front :: proc(q: ^$Q/Queue($T), n: int, loc := #caller_location) {
// Consume `n` elements from the back of the queue
consume_back :: proc(q: ^$Q/Queue($T), n: int, loc := #caller_location) {
- assert(condition=int(q.len) >= n, loc=loc)
+ when !ODIN_NO_BOUNDS_CHECK {
+ ensure(q.len >= uint(n), "Queue does not have enough elements to consume.", loc)
+ }
if n > 0 {
q.len -= uint(n)
}