1515///|
1616fn [T ] set_null(buffer : UninitializedArray [T ], index : Int ) = " %fixedarray.set_null "
1717
18- ///|
19- /// The deque representation invariant guarantees these indices are in bounds.
20- /// Keep these private so callers cannot bypass bounds checks.
21- #inline
22- fn [T ] unsafe_buffer_get(buffer : UninitializedArray [T ], index : Int ) -> T = " %fixedarray.unsafe_get "
23-
24- ///|
25- #inline
26- fn [T ] unsafe_buffer_set(
27- buffer : UninitializedArray [T ],
28- index : Int ,
29- value : T ,
30- ) -> Unit = " %fixedarray.unsafe_set "
31-
3218///|
3319fn [A ] new_deque(capacity : Int ) -> Deque [A ] {
3420 { buf: UninitializedArray ::make(capacity), len: 0, head: 0 }
3521}
3622
37- ///|
38- /// Wraps an in-buffer offset without division. Comparing the offset with the
39- /// contiguous space first also avoids overflowing `head + offset`.
40- #inline
41- fn wrap_index(
42- head : Int ,
43- offset : Int ,
44- capacity : Int ,
45- ) -> Int where {
46- proof_require: wrap_index_pre(head, offset, capacity),
47- proof_ensure: result => wrap_index_post(head, offset, capacity, result),
48- proof_ensure: result => wrap_index_mod_equiv(head, offset, capacity, result),
49- } {
50- let contiguous = capacity - head
51- if offset < contiguous {
52- proof_assert (head + offset) % capacity == head + offset
53- head + offset
54- } else {
55- proof_assert (head + offset) % capacity == offset - contiguous
56- offset - contiguous
57- }
58- }
59-
60- ///|
61- /// Moves an in-buffer index back by one without division.
62- #inline
63- fn decrement_index(
64- index : Int ,
65- capacity : Int ,
66- ) -> Int where {
67- proof_require: decrement_index_pre(index, capacity),
68- proof_ensure: result => decrement_index_post(index, capacity, result),
69- proof_ensure: result => decrement_index_mod_equiv(index, capacity, result),
70- } {
71- if index == 0 {
72- proof_assert (index + capacity - 1) % capacity == capacity - 1
73- capacity - 1
74- } else {
75- proof_assert (index + capacity - 1) % capacity == index - 1
76- index - 1
77- }
78- }
79-
8023///|
8124/// Computes the tail index (index of last element) on demand.
8225/// Only valid when len > 0.
8326fn [A ] Deque ::tail_index(self : Deque [A ]) -> Int {
84- wrap_index (self.head, self.len - 1 , self.buf.length())
27+ deque_tail_index (self.head, self.len, self.buf.length())
8528}
8629
8730///|
@@ -343,15 +286,15 @@ pub fn[A] Deque::blit_to(
343286 }
344287 // Copy in reverse order
345288 for i in len>..0 {
346- let dst_idx = wrap_index (dst.head, dst_offset + i, dst.buf.length() )
347- let src_idx = wrap_index (self.head, src_offset + i, self.buf.length() )
348- unsafe_buffer_set( dst.buf, dst_idx, unsafe_buffer_get( self.buf, src_idx))
289+ let dst_idx = (dst.head + dst_offset + i) % dst.buf.length()
290+ let src_idx = (self.head + src_offset + i) % self.buf.length()
291+ dst.buf[ dst_idx] = self.buf[ src_idx]
349292 }
350293 } else {
351294 for i in 0..<len {
352- let dst_idx = wrap_index (dst.head, dst_offset + i, dst.buf.length() )
353- let src_idx = wrap_index (self.head, src_offset + i, self.buf.length() )
354- unsafe_buffer_set( dst.buf, dst_idx, unsafe_buffer_get( self.buf, src_idx))
295+ let dst_idx = (dst.head + dst_offset + i) % dst.buf.length()
296+ let src_idx = (self.head + src_offset + i) % self.buf.length()
297+ dst.buf[ dst_idx] = self.buf[ src_idx]
355298 if dst_offset + i >= dst_len {
356299 dst.len += 1
357300 }
@@ -416,13 +359,9 @@ pub fn[A] Deque::append(self : Deque[A], other : Deque[A]) -> Unit {
416359 let cap = self.buf.length()
417360 // Use captured state to read from other, avoiding aliasing issues
418361 for i in 0..<other_len {
419- let read_idx = wrap_index(other_head, i, other_buf_len)
420- let write_idx = wrap_index(self.head, self.len, cap)
421- unsafe_buffer_set(
422- self.buf,
423- write_idx,
424- unsafe_buffer_get(other_buf, read_idx),
425- )
362+ let read_idx = (other_head + i) % other_buf_len
363+ let write_idx = (self.head + self.len) % cap
364+ self.buf[write_idx] = other_buf[read_idx]
426365 self.len += 1
427366 }
428367}
@@ -483,22 +422,22 @@ pub fn[A] Deque::insert(self : Deque[A], index : Int, value : A) -> Unit {
483422 let cap = self.buf.length()
484423 if index < self.len / 2 {
485424 // Shift front elements left
486- let new_head = decrement_index (self.head, cap)
425+ let new_head = (self.head - 1 + cap) % cap
487426 for i in 0..<index {
488- let to = wrap_index (new_head, i, cap)
489- let from = wrap_index (self.head, i, cap)
490- unsafe_buffer_set( self.buf, to, unsafe_buffer_get( self.buf, from))
427+ let to = (new_head + i) % cap
428+ let from = (self.head + i) % cap
429+ self.buf[to] = self.buf[ from]
491430 }
492431 self.head = new_head
493432 } else {
494433 // Shift back elements right
495434 for i = self.len; i > index; i = i - 1 {
496- let from = wrap_index (self.head, i - 1, cap)
497- let to = wrap_index (self.head, i, cap)
498- unsafe_buffer_set( self.buf, to, unsafe_buffer_get( self.buf, from))
435+ let from = (self.head + i - 1) % cap
436+ let to = (self.head + i) % cap
437+ self.buf[to] = self.buf[ from]
499438 }
500439 }
501- unsafe_buffer_set( self.buf, wrap_index (self.head, index, cap), value)
440+ self.buf[ (self.head + index) % cap] = value
502441 self.len += 1
503442}
504443
@@ -559,21 +498,21 @@ pub fn[A] Deque::remove(self : Deque[A], index : Int) -> A {
559498 let cap = self.buf.length()
560499 if index < self.len / 2 {
561500 // Shift front elements right
562- let new_head = wrap_index (self.head, 1, cap)
501+ let new_head = (self.head + 1) % cap
563502 for i in index>..0 {
564- let to = wrap_index (self.head, i + 1, cap)
565- let from = wrap_index (self.head, i, cap)
566- unsafe_buffer_set( self.buf, to, unsafe_buffer_get( self.buf, from))
503+ let to = (self.head + i + 1) % cap
504+ let from = (self.head + i) % cap
505+ self.buf[to] = self.buf[ from]
567506 }
568507 set_null(self.buf, self.head)
569508 self.head = new_head
570509 } else {
571510 // Shift back elements left
572- let tail_idx = wrap_index (self.head, self.len - 1, cap)
511+ let tail_idx = (self.head + self.len - 1) % cap
573512 for i in (index + 1)..<self.len {
574- let to = wrap_index (self.head, i - 1, cap)
575- let from = wrap_index (self.head, i, cap)
576- unsafe_buffer_set( self.buf, to, unsafe_buffer_get( self.buf, from))
513+ let to = (self.head + i - 1) % cap
514+ let from = (self.head + i) % cap
515+ self.buf[to] = self.buf[ from]
577516 }
578517 set_null(self.buf, tail_idx)
579518 }
@@ -637,7 +576,9 @@ pub fn[A] Deque::capacity(self : Deque[A]) -> Int {
637576/// Reallocate the deque with a new capacity.
638577fn[A ] Deque ::realloc(self : Deque [A ]) -> Unit {
639578 let old_cap = self.buf.length()
640- let new_cap = if old_cap == 0 { 8 } else { old_cap * 2 }
579+ // Doubling a larger capacity would overflow `Int`.
580+ guard old_cap <= 0x3fff_ffff else { abort("Deque capacity overflow") }
581+ let new_cap = deque_realloc_capacity(old_cap, self.len)
641582 let new_buf = self.unsafe_make_and_blit_to(new_cap, 0)
642583 self.head = 0
643584 self.buf = new_buf
@@ -657,7 +598,8 @@ pub fn[A] Deque::front(self : Deque[A]) -> A? {
657598 if self.len == 0 {
658599 None
659600 } else {
660- Some (unsafe_buffer_get(self.buf, self.head))
601+ let index = deque_element_index(self.head, self.len, self.buf.length(), 0)
602+ Some (self.buf.unsafe_get(index))
661603 }
662604}
663605
@@ -675,7 +617,13 @@ pub fn[A] Deque::back(self : Deque[A]) -> A? {
675617 if self.len == 0 {
676618 None
677619 } else {
678- Some (unsafe_buffer_get(self.buf, self.tail_index()))
620+ let index = deque_element_index(
621+ self.head,
622+ self.len,
623+ self.buf.length(),
624+ self.len - 1,
625+ )
626+ Some (self.buf.unsafe_get(index))
679627 }
680628}
681629
@@ -696,9 +644,9 @@ pub fn[A] Deque::push_front(self : Deque[A], value : A) -> Unit {
696644 if self.len == self.buf.length() {
697645 self.realloc()
698646 }
699- let cap = self.buf.length()
700- self.head = decrement_index(self.head, cap )
701- unsafe_buffer_set( self.buf, self. head, value)
647+ let new_head = deque_push_front_core( self.head, self.len, self. buf.length() )
648+ self.buf.unsafe_set(new_head, value )
649+ self.head = new_head
702650 self.len += 1
703651}
704652
@@ -719,9 +667,8 @@ pub fn[A] Deque::push_back(self : Deque[A], value : A) -> Unit {
719667 if self.len == self.buf.length() {
720668 self.realloc()
721669 }
722- let cap = self.buf.length()
723- let write_idx = wrap_index(self.head, self.len, cap)
724- unsafe_buffer_set(self.buf, write_idx, value)
670+ let write_idx = deque_push_back_core(self.head, self.len, self.buf.length())
671+ self.buf.unsafe_set(write_idx, value)
725672 self.len += 1
726673}
727674
@@ -741,9 +688,9 @@ pub fn[A] Deque::push_back(self : Deque[A], value : A) -> Unit {
741688#alias(pop_front_exn, deprecated)
742689pub fn[A ] Deque ::unsafe_pop_front(self : Deque [A ]) -> Unit {
743690 guard self.len > 0 else { abort("The deque is empty!") }
691+ let new_head = deque_pop_front_core(self.head, self.len, self.buf.length())
744692 set_null(self.buf, self.head)
745- let cap = self.buf.length()
746- self.head = wrap_index(self.head, 1, cap)
693+ self.head = new_head
747694 self.len -= 1
748695}
749696
@@ -794,7 +741,7 @@ test "unsafe_pop_front after many push_front" {
794741#alias(pop_back_exn, deprecated)
795742pub fn[A ] Deque ::unsafe_pop_back(self : Deque [A ]) -> Unit {
796743 guard self.len > 0 else { abort("The deque is empty!") }
797- let tail_idx = self.tail_index( )
744+ let tail_idx = deque_pop_back_core( self.head, self.len, self.buf.length() )
798745 set_null(self.buf, tail_idx)
799746 self.len -= 1
800747}
@@ -832,10 +779,10 @@ pub fn[A] Deque::unsafe_pop_back(self : Deque[A]) -> Unit {
832779/// ```
833780pub fn[A ] Deque ::pop_front(self : Deque [A ]) -> A? {
834781 guard self.len > 0 else { return None }
835- let value = unsafe_buffer_get(self.buf, self.head)
782+ let new_head = deque_pop_front_core(self.head, self.len, self.buf.length())
783+ let value = self.buf.unsafe_get(self.head)
836784 set_null(self.buf, self.head)
837- let cap = self.buf.length()
838- self.head = wrap_index(self.head, 1, cap)
785+ self.head = new_head
839786 self.len -= 1
840787 Some (value)
841788}
@@ -852,8 +799,8 @@ pub fn[A] Deque::pop_front(self : Deque[A]) -> A? {
852799/// ```
853800pub fn[A ] Deque ::pop_back(self : Deque [A ]) -> A? {
854801 guard self.len > 0 else { return None }
855- let tail_idx = self.tail_index( )
856- let value = unsafe_buffer_get( self.buf, tail_idx)
802+ let tail_idx = deque_pop_back_core( self.head, self.len, self.buf.length() )
803+ let value = self.buf.unsafe_get( tail_idx)
857804 set_null(self.buf, tail_idx)
858805 self.len -= 1
859806 Some (value)
@@ -876,8 +823,13 @@ pub fn[A] Deque::at(self : Deque[A], index : Int) -> A {
876823 if index < 0 || index >= self.len {
877824 index_out_of_bounds(self.len, index)
878825 }
879- let physical_index = wrap_index(self.head, index, self.buf.length())
880- unsafe_buffer_get(self.buf, physical_index)
826+ let physical_index = deque_element_index(
827+ self.head,
828+ self.len,
829+ self.buf.length(),
830+ index,
831+ )
832+ self.buf.unsafe_get(physical_index)
881833}
882834
883835///|
@@ -898,8 +850,13 @@ pub fn[A] Deque::set(self : Deque[A], index : Int, value : A) -> Unit {
898850 if index < 0 || index >= self.len {
899851 index_out_of_bounds(self.len, index)
900852 }
901- let physical_index = wrap_index(self.head, index, self.buf.length())
902- unsafe_buffer_set(self.buf, physical_index, value)
853+ let physical_index = deque_element_index(
854+ self.head,
855+ self.len,
856+ self.buf.length(),
857+ index,
858+ )
859+ self.buf.unsafe_set(physical_index, value)
903860}
904861
905862///|
@@ -2367,8 +2324,13 @@ pub fn[A] Deque::binary_search_by(
23672324/// Safe element access with bounds checking
23682325pub fn[A ] Deque ::get(self : Deque [A ], index : Int ) -> A? {
23692326 if index >= 0 && index < self.len {
2370- let physical_index = wrap_index(self.head, index, self.buf.length())
2371- Some (unsafe_buffer_get(self.buf, physical_index))
2327+ let physical_index = deque_element_index(
2328+ self.head,
2329+ self.len,
2330+ self.buf.length(),
2331+ index,
2332+ )
2333+ Some (self.buf.unsafe_get(physical_index))
23722334 } else {
23732335 None
23742336 }
@@ -2490,12 +2452,10 @@ pub fn[A] Deque::rev_in_place(self : Deque[A]) -> Unit {
24902452 guard self.len > 0 else { return }
24912453 let cap = self.buf.length()
24922454 for _ in 0..<(self.len / 2); left = self.head, right = self.tail_index() {
2493- let temp = unsafe_buffer_get(self.buf, left)
2494- unsafe_buffer_set(self.buf, left, unsafe_buffer_get(self.buf, right))
2495- unsafe_buffer_set(self.buf, right, temp)
2496- let left = wrap_index(left, 1, cap)
2497- let right = decrement_index(right, cap)
2498- continue left, right
2455+ let temp = self.buf[left]
2456+ self.buf[left] = self.buf[right]
2457+ self.buf[right] = temp
2458+ continue (left + 1) % cap, (right - 1 + cap) % cap
24992459 }
25002460}
25012461
@@ -2533,8 +2493,8 @@ pub fn[A] Deque::rev(self : Deque[A]) -> Deque[A] {
25332493 let new_buf = UninitializedArray ::make(len)
25342494 // Copy elements in reverse order
25352495 for i in 0..<len {
2536- let src_idx = wrap_index (self.head, len - i - 1, self.buf.length() )
2537- unsafe_buffer_set( new_buf, i, unsafe_buffer_get( self.buf, src_idx))
2496+ let src_idx = (self.head + len - i - 1) % self.buf.length()
2497+ new_buf[i] = self.buf[ src_idx]
25382498 }
25392499 // Create new deque with reversed elements
25402500 { buf: new_buf, len, head: 0 }
0 commit comments