generic_arraydeque/unstable/mod.rs
1use super::*;
2
3pub use extract_if::ExtractIf;
4
5mod extract_if;
6
7impl<T, N: ArrayLength> ArrayDeque<T, N> {
8 /// Removes and returns the first element from the deque if the predicate
9 /// returns `true`, or [`None`] if the predicate returns false or the deque
10 /// is empty (the predicate will not be called in that case).
11 ///
12 /// ## Examples
13 ///
14 /// ```
15 /// use generic_arraydeque::{ArrayDeque, typenum::U8};
16 ///
17 /// let mut deque = ArrayDeque::<i32, U8>::new();
18 /// for value in 0..5 {
19 /// assert!(deque.push_back(value).is_none());
20 /// }
21 /// let pred = |x: &mut i32| *x % 2 == 0;
22 ///
23 /// assert_eq!(deque.pop_front_if(pred), Some(0));
24 /// assert_eq!(deque.front(), Some(&1));
25 /// assert_eq!(deque.pop_front_if(pred), None);
26 /// ```
27 #[inline(always)]
28 pub fn pop_front_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option<T> {
29 let first = self.front_mut()?;
30 if predicate(first) {
31 self.pop_front()
32 } else {
33 None
34 }
35 }
36
37 /// Removes and returns the last element from the deque if the predicate
38 /// returns `true`, or [`None`] if the predicate returns false or the deque
39 /// is empty (the predicate will not be called in that case).
40 ///
41 /// ## Examples
42 ///
43 /// ```
44 /// use generic_arraydeque::{ArrayDeque, typenum::U8};
45 ///
46 /// let mut deque = ArrayDeque::<i32, U8>::new();
47 /// for value in 0..5 {
48 /// assert!(deque.push_back(value).is_none());
49 /// }
50 /// let pred = |x: &mut i32| *x % 2 == 0;
51 ///
52 /// assert_eq!(deque.pop_back_if(pred), Some(4));
53 /// assert_eq!(deque.back(), Some(&3));
54 /// assert_eq!(deque.pop_back_if(pred), None);
55 /// ```
56 #[inline(always)]
57 pub fn pop_back_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option<T> {
58 let first = self.back_mut()?;
59 if predicate(first) {
60 self.pop_back()
61 } else {
62 None
63 }
64 }
65
66 /// Appends an element to the back of the deque, returning a mutable reference to it if successful.
67 ///
68 /// If the deque is at full capacity, returns the element back without modifying the deque.
69 ///
70 /// ## Examples
71 ///
72 /// ```
73 /// use generic_arraydeque::{ArrayDeque, typenum::U2};
74 ///
75 /// let mut deque: ArrayDeque<u32, U2> = ArrayDeque::new();
76 /// let elem_ref = deque.push_back_mut(10).unwrap();
77 /// *elem_ref += 5;
78 /// assert_eq!(*deque.get(0).unwrap(), 15);
79 /// let _ = deque.push_back_mut(20).unwrap();
80 /// assert!(deque.push_back_mut(30).is_err());
81 /// ```
82 #[inline(always)]
83 pub const fn push_back_mut(&mut self, value: T) -> Result<&mut T, T> {
84 if self.is_full() {
85 Err(value)
86 } else {
87 Ok(unsafe { push_back_unchecked!(self(value)).assume_init_mut() })
88 }
89 }
90
91 /// Prepends an element to the front of the deque, returning a mutable reference to it if successful.
92 ///
93 /// If the deque is at full capacity, returns the element back without modifying the deque.
94 ///
95 /// ## Examples
96 ///
97 /// ```
98 /// use generic_arraydeque::{ArrayDeque, typenum::U2};
99 ///
100 /// let mut deque: ArrayDeque<u32, U2> = ArrayDeque::new();
101 /// let elem_ref = deque.push_front_mut(10).unwrap();
102 /// *elem_ref += 5;
103 /// assert_eq!(*deque.get(0).unwrap(), 15);
104 /// let _ = deque.push_front_mut(20).unwrap();
105 /// assert!(deque.push_front_mut(30).is_err());
106 /// ```
107 #[inline(always)]
108 pub const fn push_front_mut(&mut self, value: T) -> Result<&mut T, T> {
109 if self.is_full() {
110 Err(value)
111 } else {
112 Ok(unsafe { push_front_unchecked!(self(value)).assume_init_mut() })
113 }
114 }
115
116 /// Shortens the deque, keeping the last `len` elements and dropping
117 /// the rest.
118 ///
119 /// If `len` is greater or equal to the deque's current length, this has
120 /// no effect.
121 ///
122 /// ## Examples
123 ///
124 /// ```
125 /// use generic_arraydeque::{ArrayDeque, typenum::U4};
126 ///
127 /// let mut buf = ArrayDeque::<u32, U4>::new();
128 /// assert!(buf.push_front(5).is_none());
129 /// assert!(buf.push_front(10).is_none());
130 /// assert!(buf.push_front(15).is_none());
131 /// assert_eq!(buf.as_slices(), (&[15, 10, 5][..], &[][..]));
132 /// buf.truncate_front(1);
133 /// assert_eq!(buf.as_slices(), (&[5][..], &[][..]));
134 /// ```
135 pub fn truncate_front(&mut self, len: usize) {
136 /// Runs the destructor for all items in the slice when it gets dropped (normally or
137 /// during unwinding).
138 struct Dropper<'a, T>(&'a mut [T]);
139
140 impl<T> Drop for Dropper<'_, T> {
141 fn drop(&mut self) {
142 unsafe {
143 ptr::drop_in_place(self.0);
144 }
145 }
146 }
147
148 unsafe {
149 if len >= self.len {
150 // No action is taken
151 return;
152 }
153
154 let (front, back) = self.as_mut_slices();
155 if len > back.len() {
156 // The 'back' slice remains unchanged.
157 // front.len() + back.len() == self.len, so 'end' is non-negative
158 // and end < front.len()
159 let end = front.len() - (len - back.len());
160 let drop_front = front.get_unchecked_mut(..end) as *mut _;
161 self.head += end;
162 self.len = len;
163 ptr::drop_in_place(drop_front);
164 } else {
165 let drop_front = front as *mut _;
166 // 'end' is non-negative by the condition above
167 let end = back.len() - len;
168 let drop_back = back.get_unchecked_mut(..end) as *mut _;
169 self.head = self.to_physical_idx(self.len - len);
170 self.len = len;
171
172 // Make sure the second half is dropped even when a destructor
173 // in the first one panics.
174 let _back_dropper = Dropper(&mut *drop_back);
175 ptr::drop_in_place(drop_front);
176 }
177 }
178 }
179
180 /// Inserts an element at `index` within the deque, shifting all elements
181 /// with indices greater than or equal to `index` towards the back, and
182 /// returning a reference to it.
183 ///
184 /// Returns `Err(value)` if `index` is strictly greater than the deque's length or if
185 /// the deque is full.
186 ///
187 /// Element at index 0 is the front of the queue.
188 ///
189 /// ## Examples
190 ///
191 /// ```
192 /// use generic_arraydeque::{ArrayDeque, typenum::U8};
193 ///
194 /// let mut deque = ArrayDeque::<i32, U8>::try_from_iter([1, 2, 3]).unwrap();
195 /// let x = deque.insert_mut(1, 5).unwrap();
196 /// *x += 7;
197 /// assert_eq!(deque.into_iter().collect::<Vec<_>>(), vec![1, 12, 2, 3]);
198 /// ```
199 #[must_use = "if you don't need a reference to the value, use `ArrayDeque::insert` instead"]
200 pub const fn insert_mut(&mut self, index: usize, value: T) -> Result<&mut T, T> {
201 if index > self.len() || self.is_full() {
202 return Err(value);
203 }
204
205 Ok(insert!(self(index, value)))
206 }
207}
208
209impl<T: Clone, N: ArrayLength> ArrayDeque<T, N> {
210 /// Clones the elements at the range `src` and appends them to the end.
211 ///
212 /// # Panics
213 ///
214 /// Panics if the starting index is greater than the end index
215 /// or if either index is greater than the length of the vector.
216 ///
217 /// # Examples
218 ///
219 /// ```
220 /// use generic_arraydeque::{ArrayDeque, typenum::U20};
221 ///
222 /// let mut characters = ArrayDeque::<_, U20>::try_from_exact_iter(['a', 'b', 'c', 'd', 'e']).unwrap();
223 /// characters.extend_from_within(2..);
224 /// assert_eq!(characters, ['a', 'b', 'c', 'd', 'e', 'c', 'd', 'e']);
225 ///
226 /// let mut numbers = ArrayDeque::<_, U20>::try_from_exact_iter([0, 1, 2, 3, 4]).unwrap();
227 /// numbers.extend_from_within(..2);
228 /// assert_eq!(numbers, [0, 1, 2, 3, 4, 0, 1]);
229 ///
230 /// let mut strings = ArrayDeque::<_, U20>::try_from_exact_iter([String::from("hello"), String::from("world"), String::from("!")]).unwrap();
231 /// strings.extend_from_within(1..=2);
232 /// assert_eq!(strings, ["hello", "world", "!", "world", "!"]);
233 /// ```
234 pub fn extend_from_within<R>(&mut self, src: R) -> bool
235 where
236 R: RangeBounds<usize>,
237 {
238 let Some(range) = try_range(src, ..self.len()) else {
239 return false;
240 };
241 if range.len() > self.remaining_capacity() {
242 return false;
243 }
244
245 // SAFETY:
246 // - `slice::range` guarantees that the given range is valid for indexing self
247 // - at least `range.len()` additional space is available
248 unsafe {
249 self.spec_extend_from_within(range);
250 }
251 true
252 }
253
254 /// Clones the elements at the range `src` and prepends them to the front.
255 ///
256 /// # Panics
257 ///
258 /// Panics if the starting index is greater than the end index
259 /// or if either index is greater than the length of the vector.
260 ///
261 /// # Examples
262 ///
263 /// ```
264 /// # #[cfg(feature = "std")] {
265 /// use generic_arraydeque::{ArrayDeque, typenum::U20};
266 ///
267 /// let mut characters = ArrayDeque::<_, U20>::try_from_exact_iter(['a'.to_string(), 'b'.to_string(), 'c'.to_string(), 'd'.to_string(), 'e'.to_string()]).unwrap();
268 /// characters.prepend_from_within(2..);
269 /// assert_eq!(characters, ['c'.to_string(), 'd'.to_string(), 'e'.to_string(), 'a'.to_string(), 'b'.to_string(), 'c'.to_string(), 'd'.to_string(), 'e'.to_string()]);
270 ///
271 /// let mut numbers = ArrayDeque::<_, U20>::try_from_exact_iter(["0".to_string(), "1".to_string(), "2".to_string(), "3".to_string(), "4".to_string()]).unwrap();
272 /// numbers.prepend_from_within(..2);
273 /// assert_eq!(numbers, ["0".to_string(), "1".to_string(), "0".to_string(), "1".to_string(), "2".to_string(), "3".to_string(), "4".to_string()]);
274 ///
275 /// let mut strings = ArrayDeque::<_, U20>::try_from_exact_iter([String::from("hello"), String::from("world"), String::from("!")]).unwrap();
276 /// strings.prepend_from_within(1..=2);
277 /// assert_eq!(strings, ["world", "!", "hello", "world", "!"]);
278 /// # }
279 /// ```
280 pub fn prepend_from_within<R>(&mut self, src: R) -> bool
281 where
282 R: RangeBounds<usize>,
283 {
284 let Some(range) = try_range(src, ..self.len()) else {
285 return false;
286 };
287
288 if range.len() > self.remaining_capacity() {
289 return false;
290 }
291
292 // SAFETY:
293 // - `slice::range` guarantees that the given range is valid for indexing self
294 // - at least `range.len()` additional space is available
295 unsafe {
296 self.spec_prepend_from_within(range);
297 }
298 true
299 }
300
301 /// Get source, destination and count (like the arguments to [`ptr::copy_nonoverlapping`])
302 /// for copying `count` values from index `src` to index `dst`.
303 /// One of the ranges can wrap around the physical buffer, for this reason 2 triples are returned.
304 ///
305 /// Use of the word "ranges" specifically refers to `src..src + count` and `dst..dst + count`.
306 ///
307 /// # Safety
308 ///
309 /// - Ranges must not overlap: `src.abs_diff(dst) >= count`.
310 /// - Ranges must be in bounds of the logical buffer: `src + count <= self.capacity()` and `dst + count <= self.capacity()`.
311 /// - `head` must be in bounds: `head < self.capacity()`.
312 unsafe fn nonoverlapping_ranges(
313 &mut self,
314 src: usize,
315 dst: usize,
316 count: usize,
317 head: usize,
318 ) -> [(*const T, *mut T, usize); 2] {
319 // "`src` and `dst` must be at least as far apart as `count`"
320 debug_assert!(
321 src.abs_diff(dst) >= count,
322 "`src` and `dst` must not overlap. src={src} dst={dst} count={count}",
323 );
324 debug_assert!(
325 src.max(dst) + count <= self.capacity(),
326 "ranges must be in bounds. src={src} dst={dst} count={count} cap={}",
327 self.capacity(),
328 );
329
330 let wrapped_src = self.wrap_add(head, src);
331 let wrapped_dst = self.wrap_add(head, dst);
332
333 let room_after_src = self.capacity() - wrapped_src;
334 let room_after_dst = self.capacity() - wrapped_dst;
335
336 let src_wraps = room_after_src < count;
337 let dst_wraps = room_after_dst < count;
338
339 // Wrapping occurs if `capacity` is contained within `wrapped_src..wrapped_src + count` or `wrapped_dst..wrapped_dst + count`.
340 // Since these two ranges must not overlap as per the safety invariants of this function, only one range can wrap.
341 debug_assert!(
342 !(src_wraps && dst_wraps),
343 "BUG: at most one of src and dst can wrap. src={src} dst={dst} count={count} cap={}",
344 self.capacity(),
345 );
346
347 unsafe {
348 let ptr = self.ptr_mut() as *mut T;
349 let src_ptr = ptr.add(wrapped_src) as _;
350 let dst_ptr = ptr.add(wrapped_dst) as _;
351
352 if src_wraps {
353 [
354 (src_ptr, dst_ptr, room_after_src),
355 (ptr, dst_ptr.add(room_after_src), count - room_after_src),
356 ]
357 } else if dst_wraps {
358 [
359 (src_ptr, dst_ptr, room_after_dst),
360 (src_ptr.add(room_after_dst), ptr, count - room_after_dst),
361 ]
362 } else {
363 [
364 (src_ptr, dst_ptr, count),
365 // null pointers are fine as long as the count is 0
366 (ptr::null(), ptr::null_mut(), 0),
367 ]
368 }
369 }
370 }
371
372 unsafe fn spec_extend_from_within(&mut self, src: Range<usize>) {
373 let dst = self.len();
374 let count = src.end - src.start;
375 let src = src.start;
376
377 unsafe {
378 // SAFETY:
379 // - Ranges do not overlap: src entirely spans initialized values, dst entirely spans uninitialized values.
380 // - Ranges are in bounds: guaranteed by the caller.
381 let ranges = self.nonoverlapping_ranges(src, dst, count, self.head);
382
383 // `len` is updated after every clone to prevent leaking and
384 // leave the deque in the right state when a clone implementation panics
385
386 for (src, dst, count) in ranges {
387 for offset in 0..count {
388 dst.add(offset).write((*src.add(offset)).clone());
389 self.len += 1;
390 }
391 }
392 }
393 }
394
395 unsafe fn spec_prepend_from_within(&mut self, src: Range<usize>) {
396 let dst = 0;
397 let count = src.end - src.start;
398 let src = src.start + count;
399
400 let new_head = self.wrap_sub(self.head, count);
401 let cap = self.capacity();
402
403 unsafe {
404 // SAFETY:
405 // - Ranges do not overlap: src entirely spans initialized values, dst entirely spans uninitialized values.
406 // - Ranges are in bounds: guaranteed by the caller.
407 let ranges = self.nonoverlapping_ranges(src, dst, count, new_head);
408
409 // Cloning is done in reverse because we prepend to the front of the deque,
410 // we can't get holes in the *logical* buffer.
411 // `head` and `len` are updated after every clone to prevent leaking and
412 // leave the deque in the right state when a clone implementation panics
413
414 // Clone the first range
415 let (src, dst, count) = ranges[1];
416 for offset in (0..count).rev() {
417 dst.add(offset).write((*src.add(offset)).clone());
418 self.head -= 1;
419 self.len += 1;
420 }
421
422 // Clone the second range
423 let (src, dst, count) = ranges[0];
424 let mut iter = (0..count).rev();
425 if let Some(offset) = iter.next() {
426 dst.add(offset).write((*src.add(offset)).clone());
427 // After the first clone of the second range, wrap `head` around
428 if self.head == 0 {
429 self.head = cap;
430 }
431 self.head -= 1;
432 self.len += 1;
433
434 // Continue like normal
435 for offset in iter {
436 dst.add(offset).write((*src.add(offset)).clone());
437 self.head -= 1;
438 self.len += 1;
439 }
440 }
441 }
442 }
443}