generic_arraydeque/
unstable.rs

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