Skip to main content

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}