Skip to main content

alloc_checked/
vec_deque.rs

1use crate::claim::Claim;
2use crate::try_clone::TryClone;
3use alloc::collections::vec_deque::{Drain, VecDeque as InnerVecDeque};
4use alloc::collections::vec_deque::{Iter, IterMut};
5use alloc::collections::TryReserveError;
6use core::alloc::Allocator;
7use core::ops::RangeBounds;
8
9pub struct VecDeque<T, A: Allocator> {
10    inner: InnerVecDeque<T, A>,
11}
12
13impl<T, A: Allocator> VecDeque<T, A> {
14    #[inline]
15    pub fn new_in(alloc: A) -> Self {
16        Self {
17            inner: InnerVecDeque::new_in(alloc),
18        }
19    }
20
21    #[inline]
22    pub fn with_capacity_in(capacity: usize, alloc: A) -> Result<Self, TryReserveError> {
23        Ok(crate::vec::Vec::with_capacity_in(capacity, alloc)?.into())
24    }
25
26    #[inline]
27    pub fn get(&self, index: usize) -> Option<&T> {
28        self.inner.get(index)
29    }
30
31    #[inline]
32    pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
33        self.inner.get_mut(index)
34    }
35
36    #[inline]
37    pub fn capacity(&self) -> usize {
38        self.inner.capacity()
39    }
40
41    #[inline]
42    pub fn allocator(&self) -> &A {
43        self.inner.allocator()
44    }
45
46    #[inline]
47    pub fn iter(&self) -> Iter<'_, T> {
48        self.inner.iter()
49    }
50
51    #[inline]
52    pub fn iter_mut(&mut self) -> IterMut<'_, T> {
53        self.inner.iter_mut()
54    }
55
56    #[inline]
57    pub fn len(&self) -> usize {
58        self.inner.len()
59    }
60
61    #[inline]
62    pub fn is_empty(&self) -> bool {
63        self.inner.is_empty()
64    }
65
66    #[inline]
67    pub fn range<R>(&self, range: R) -> Iter<'_, T>
68    where
69        R: RangeBounds<usize>,
70    {
71        self.inner.range(range)
72    }
73
74    #[inline]
75    pub fn range_mut<R>(&mut self, range: R) -> IterMut<'_, T>
76    where
77        R: RangeBounds<usize>,
78    {
79        self.inner.range_mut(range)
80    }
81
82    #[inline]
83    pub fn reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
84        self.inner.try_reserve(additional)
85    }
86
87    #[inline]
88    pub fn drain<R>(&mut self, range: R) -> Drain<'_, T, A>
89    where
90        R: RangeBounds<usize>,
91    {
92        self.inner.drain(range)
93    }
94
95    #[inline]
96    pub fn clear(&mut self) {
97        self.inner.clear()
98    }
99
100    #[inline]
101    pub fn contains(&self, x: &T) -> bool
102    where
103        T: PartialEq,
104    {
105        self.inner.contains(x)
106    }
107
108    #[inline]
109    pub fn front(&self) -> Option<&T> {
110        self.inner.front()
111    }
112
113    #[inline]
114    pub fn front_mut(&mut self) -> Option<&mut T> {
115        self.inner.front_mut()
116    }
117
118    #[inline]
119    pub fn back(&self) -> Option<&T> {
120        self.inner.back()
121    }
122
123    #[inline]
124    pub fn back_mut(&mut self) -> Option<&mut T> {
125        self.inner.back_mut()
126    }
127
128    #[inline]
129    pub fn pop_front(&mut self) -> Option<T> {
130        self.inner.pop_front()
131    }
132
133    #[inline]
134    pub fn pop_back(&mut self) -> Option<T> {
135        self.inner.pop_back()
136    }
137
138    #[inline]
139    pub fn push_front(&mut self, item: T) -> Result<(), TryReserveError> {
140        self.reserve(1)?;
141        self.inner.push_front(item);
142        Ok(())
143    }
144
145    #[inline]
146    pub fn push_back(&mut self, item: T) -> Result<(), TryReserveError> {
147        self.reserve(1)?;
148        self.inner.push_back(item);
149        Ok(())
150    }
151
152    #[inline]
153    pub fn insert(&mut self, index: usize, item: T) -> Result<(), TryReserveError> {
154        self.reserve(1)?;
155        self.inner.insert(index, item);
156        Ok(())
157    }
158
159    #[inline]
160    pub fn remove(&mut self, index: usize) -> Option<T> {
161        self.inner.remove(index)
162    }
163
164    #[inline]
165    pub fn append(&mut self, other: &mut Self) -> Result<(), TryReserveError> {
166        self.reserve(other.len())?;
167        self.inner.append(&mut other.inner);
168        Ok(())
169    }
170
171    #[inline]
172    pub fn make_contiguous(&mut self) -> &mut [T] {
173        self.inner.make_contiguous()
174    }
175}
176
177impl<T: Claim, A: Allocator + Claim> TryClone for VecDeque<T, A> {
178    type Error = TryReserveError;
179
180    fn try_clone(&self) -> Result<Self, Self::Error> {
181        let mut cloned = Self::with_capacity_in(self.len(), self.allocator().clone())?;
182        cloned.inner.extend(self.iter().cloned());
183        Ok(cloned)
184    }
185}
186
187impl<T, A: Allocator> From<crate::vec::Vec<T, A>> for VecDeque<T, A> {
188    fn from(vec: crate::vec::Vec<T, A>) -> Self {
189        let vec_inner = vec.into_inner();
190        let inner = vec_inner.into();
191        Self { inner }
192    }
193}
194
195#[cfg(test)]
196mod tests {
197    use super::*;
198    use crate::testing::{AllowGlobalAllocGuard, NoGlobalAllocGuard, WatermarkAllocator};
199    use alloc::vec::Vec as InnerVec;
200
201    #[test]
202    fn test_new_in() {
203        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
204        let wma = WatermarkAllocator::new(1024);
205        let deque: VecDeque<i32, _> = VecDeque::new_in(wma.clone());
206        assert!(deque.is_empty());
207        assert_eq!(deque.len(), 0);
208        assert_eq!(wma.in_use(), 0);
209    }
210
211    #[test]
212    fn test_with_capacity_in_success() {
213        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
214        let wma = WatermarkAllocator::new(128);
215        let deque: Result<VecDeque<i32, _>, _> = VecDeque::with_capacity_in(10, wma.clone());
216        assert!(deque.is_ok());
217        assert_eq!(wma.in_use(), deque.unwrap().capacity() * size_of::<i32>());
218    }
219
220    #[test]
221    fn test_with_capacity_in_failure() {
222        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
223        let wma = WatermarkAllocator::new(4); // Set a low watermark to trigger failure
224        let deque = VecDeque::<i32, _>::with_capacity_in(10, wma.clone());
225        assert!(deque.is_err());
226        assert_eq!(wma.in_use(), 0);
227    }
228
229    #[test]
230    fn test_push_front_back() {
231        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
232        let wma = WatermarkAllocator::new(128);
233        let mut deque = VecDeque::new_in(wma.clone());
234
235        // Push elements to the front and back
236        assert!(deque.push_back(1).is_ok());
237        assert!(deque.push_front(2).is_ok());
238        assert_eq!(deque.len(), 2);
239        assert_eq!(deque.front(), Some(&2));
240        assert_eq!(deque.back(), Some(&1));
241    }
242
243    #[test]
244    fn test_push_front_back_allocation_failure() {
245        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
246        let wma = WatermarkAllocator::new(16); // Small watermark to limit allocations
247        let mut deque = VecDeque::with_capacity_in(1, wma.clone()).expect("should allocate");
248        assert_eq!(deque.capacity(), 1); // overallocated by default.
249
250        // Push first element should work
251        assert!(deque.push_back(1).is_ok());
252        // Second push should fail due to allocation error
253        assert!(deque.push_back(2).is_err());
254    }
255
256    #[test]
257    fn test_insert_remove() {
258        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
259        let wma = WatermarkAllocator::new(128);
260        let mut deque = VecDeque::new_in(wma.clone());
261
262        // Insert elements
263        assert!(deque.push_back(1).is_ok());
264        assert!(deque.push_back(3).is_ok());
265        assert!(deque.insert(1, 2).is_ok());
266        assert_eq!(deque.len(), 3);
267
268        // Check order after insertion
269        assert_eq!(deque.get(0), Some(&1));
270        assert_eq!(deque.get(1), Some(&2));
271        assert_eq!(deque.get(2), Some(&3));
272
273        // Remove an element and check results
274        assert_eq!(deque.remove(1), Some(2));
275        assert_eq!(deque.len(), 2);
276        assert_eq!(deque.get(1), Some(&3));
277    }
278
279    #[test]
280    fn test_insert_allocation_failure() {
281        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
282        let wma = WatermarkAllocator::new(16); // Limited allocation capacity
283        let mut deque = VecDeque::with_capacity_in(1, wma.clone()).expect("should allocate");
284
285        // First insert should succeed
286        assert!(deque.push_back(1).is_ok());
287        // Second insert, due to allocation, should fail
288        assert!(deque.insert(1, 2).is_err());
289    }
290
291    #[test]
292    fn test_append() {
293        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
294        let wma = WatermarkAllocator::new(128);
295        let mut deque1 = VecDeque::new_in(wma.clone());
296        let mut deque2 = VecDeque::new_in(wma.clone());
297
298        // Fill both deques
299        assert!(deque1.push_back(1).is_ok());
300        assert!(deque1.push_back(2).is_ok());
301        assert!(deque2.push_back(3).is_ok());
302
303        // Append deque2 into deque1
304        assert!(deque1.append(&mut deque2).is_ok());
305        assert_eq!(deque1.len(), 3);
306        assert!(deque2.is_empty());
307        assert_eq!(deque1.get(2), Some(&3));
308    }
309
310    #[test]
311    fn test_append_allocation_failure() {
312        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
313        let wma = WatermarkAllocator::new(16);
314        let mut deque1 = VecDeque::with_capacity_in(1, wma.clone()).expect("should allocate");
315        assert_eq!(deque1.capacity(), 1);
316        assert_eq!(wma.in_use(), deque1.capacity() * size_of::<i32>());
317        assert_eq!(wma.in_use(), 4);
318        let mut deque2 = VecDeque::with_capacity_in(2, wma.clone()).expect("should allocate");
319        assert_eq!(deque2.capacity(), 2);
320        assert_eq!(
321            wma.in_use(),
322            deque1.capacity() * size_of::<i32>() + deque2.capacity() * size_of::<i32>()
323        );
324        assert_eq!(wma.in_use(), 12);
325
326        // Push items into deque2
327        assert!(deque2.push_back(1).is_ok());
328        assert!(deque2.push_back(2).is_ok());
329
330        // Append should fail due to insufficient allocation capacity in deque1
331        assert!(deque1.append(&mut deque2).is_err());
332        assert!(!deque2.is_empty()); // deque2 should remain intact
333    }
334
335    #[test]
336    fn test_try_clone() {
337        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
338        let wma = WatermarkAllocator::new(128);
339        let mut deque = VecDeque::new_in(wma.clone());
340        deque.push_back(1).unwrap();
341        deque.push_back(2).unwrap();
342
343        let cloned = deque.try_clone();
344        assert!(cloned.is_ok());
345        let cloned = cloned.unwrap();
346        assert_eq!(cloned.len(), deque.len());
347        assert_eq!(cloned.get(0), Some(&1));
348        assert_eq!(cloned.get(1), Some(&2));
349    }
350
351    #[test]
352    fn test_try_clone_allocation_failure() {
353        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
354        let wma = WatermarkAllocator::new(16); // Low watermark for testing allocation failure
355        let mut deque = VecDeque::new_in(wma.clone());
356        deque.push_back(1).unwrap();
357
358        // Cloning should fail due to allocation constraints
359        let cloned = deque.try_clone();
360        assert!(cloned.is_err());
361    }
362
363    #[test]
364    fn test_get_mut() {
365        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
366        let wma = WatermarkAllocator::new(128);
367        let mut deque = VecDeque::new_in(wma.clone());
368        deque.push_back(1).unwrap();
369        deque.push_back(2).unwrap();
370
371        if let Some(value) = deque.get_mut(1) {
372            *value = 3;
373        }
374        assert_eq!(deque.get(1), Some(&3));
375    }
376
377    #[test]
378    fn test_iter() {
379        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
380        let wma = WatermarkAllocator::new(128);
381        let mut deque = VecDeque::new_in(wma.clone());
382        deque.push_back(1).unwrap();
383        deque.push_back(2).unwrap();
384        deque.push_back(3).unwrap();
385
386        let mut values = {
387            let _allow_global_alloc_guard = AllowGlobalAllocGuard::new();
388            InnerVec::with_capacity(deque.len())
389        };
390        values.extend(deque.iter().cloned());
391        assert_eq!(values, [1, 2, 3]);
392
393        {
394            let _allow_global_alloc_guard = AllowGlobalAllocGuard::new();
395            drop(values);
396        }
397    }
398
399    #[test]
400    fn test_iter_mut() {
401        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
402        let wma = WatermarkAllocator::new(128);
403        let mut deque = VecDeque::new_in(wma.clone());
404        deque.push_back(1).unwrap();
405        deque.push_back(2).unwrap();
406        deque.push_back(3).unwrap();
407
408        for value in deque.iter_mut() {
409            *value *= 2;
410        }
411
412        let mut values = {
413            let _allow_global_alloc_guard = AllowGlobalAllocGuard::new();
414            InnerVec::with_capacity(deque.len())
415        };
416        values.extend(deque.iter().cloned());
417        assert_eq!(values, [2, 4, 6]);
418        {
419            let _allow_global_alloc_guard = AllowGlobalAllocGuard::new();
420            drop(values);
421        }
422    }
423
424    #[test]
425    fn test_range() {
426        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
427        let wma = WatermarkAllocator::new(128);
428        let mut deque = VecDeque::new_in(wma.clone());
429        deque.push_back(10).unwrap();
430        deque.push_back(20).unwrap();
431        deque.push_back(30).unwrap();
432        deque.push_back(40).unwrap();
433
434        let mut values = {
435            let _allow_global_alloc_guard = AllowGlobalAllocGuard::new();
436            InnerVec::with_capacity(deque.len())
437        };
438        values.extend(deque.range(1..3).cloned());
439        assert_eq!(values, [20, 30]);
440        {
441            let _allow_global_alloc_guard = AllowGlobalAllocGuard::new();
442            drop(values);
443        }
444    }
445
446    #[test]
447    fn test_range_mut() {
448        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
449        let wma = WatermarkAllocator::new(128);
450        let mut deque = VecDeque::new_in(wma.clone());
451        deque.push_back(5).unwrap();
452        deque.push_back(10).unwrap();
453        deque.push_back(15).unwrap();
454
455        for value in deque.range_mut(1..3) {
456            *value += 10;
457        }
458
459        let mut values = {
460            let _allow_global_alloc_guard = AllowGlobalAllocGuard::new();
461            InnerVec::with_capacity(deque.len())
462        };
463        values.extend(deque.iter().cloned());
464        assert_eq!(values, [5, 20, 25]);
465        {
466            let _allow_global_alloc_guard = AllowGlobalAllocGuard::new();
467            drop(values);
468        }
469    }
470
471    #[test]
472    fn test_drain() {
473        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
474        let wma = WatermarkAllocator::new(128);
475        let mut deque = VecDeque::new_in(wma.clone());
476        deque.push_back(1).unwrap();
477        deque.push_back(2).unwrap();
478        deque.push_back(3).unwrap();
479        deque.push_back(4).unwrap();
480
481        let mut drained = {
482            let _allow_alloc_guard = AllowGlobalAllocGuard::new();
483            InnerVec::with_capacity(deque.len())
484        };
485
486        drained.extend(deque.drain(1..3));
487        assert_eq!(drained, [2, 3]);
488        assert_eq!(deque.len(), 2);
489        assert_eq!(deque.get(1), Some(&4));
490
491        {
492            let _allow_alloc_guard = AllowGlobalAllocGuard::new();
493            drop(drained);
494        }
495    }
496
497    #[test]
498    fn test_clear() {
499        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
500        let wma = WatermarkAllocator::new(128);
501        let mut deque = VecDeque::new_in(wma.clone());
502        deque.push_back(1).unwrap();
503        deque.push_back(2).unwrap();
504
505        deque.clear();
506        assert!(deque.is_empty());
507        assert_eq!(deque.len(), 0);
508    }
509
510    #[test]
511    fn test_contains() {
512        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
513        let wma = WatermarkAllocator::new(128);
514        let mut deque = VecDeque::new_in(wma.clone());
515        deque.push_back(42).unwrap();
516        deque.push_back(99).unwrap();
517
518        assert!(deque.contains(&42));
519        assert!(!deque.contains(&1));
520    }
521
522    #[test]
523    fn test_front_mut() {
524        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
525        let wma = WatermarkAllocator::new(128);
526        let mut deque = VecDeque::new_in(wma.clone());
527        deque.push_back(5).unwrap();
528        deque.push_back(10).unwrap();
529
530        if let Some(value) = deque.front_mut() {
531            *value = 7;
532        }
533        assert_eq!(deque.front(), Some(&7));
534    }
535
536    #[test]
537    fn test_back_mut() {
538        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
539        let wma = WatermarkAllocator::new(128);
540        let mut deque = VecDeque::new_in(wma.clone());
541        deque.push_back(5).unwrap();
542        deque.push_back(10).unwrap();
543
544        if let Some(value) = deque.back_mut() {
545            *value = 15;
546        }
547        assert_eq!(deque.back(), Some(&15));
548    }
549
550    #[test]
551    fn test_pop_front() {
552        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
553        let wma = WatermarkAllocator::new(128);
554        let mut deque = VecDeque::new_in(wma.clone());
555        deque.push_back(1).unwrap();
556        deque.push_back(2).unwrap();
557
558        assert_eq!(deque.pop_front(), Some(1));
559        assert_eq!(deque.pop_front(), Some(2));
560        assert!(deque.is_empty());
561    }
562
563    #[test]
564    fn test_pop_back() {
565        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
566        let wma = WatermarkAllocator::new(128);
567        let mut deque = VecDeque::new_in(wma.clone());
568        deque.push_back(3).unwrap();
569        deque.push_back(4).unwrap();
570
571        assert_eq!(deque.pop_back(), Some(4));
572        assert_eq!(deque.pop_back(), Some(3));
573        assert!(deque.is_empty());
574    }
575
576    #[test]
577    fn test_make_contiguous() {
578        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
579        let wma = WatermarkAllocator::new(128);
580        let mut deque = VecDeque::new_in(wma.clone());
581
582        // Alternate between front and back pushes to create a discontinuous buffer.
583        deque.push_back(1).unwrap();
584        deque.push_front(2).unwrap();
585        deque.push_back(3).unwrap();
586        deque.push_front(4).unwrap();
587        deque.push_back(5).unwrap();
588
589        // Calling make_contiguous should arrange elements in a contiguous slice.
590        let slice = deque.make_contiguous();
591
592        // Verify the order matches the intended sequence as if the buffer were continuous.
593        assert_eq!(slice, &[4, 2, 1, 3, 5]);
594    }
595
596    #[test]
597    fn test_try_clone_success() {
598        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
599        let wma = WatermarkAllocator::new(128);
600        let mut deque = VecDeque::new_in(wma.clone());
601
602        // Populate the deque with some elements.
603        deque.push_back(1).unwrap();
604        deque.push_back(2).unwrap();
605        deque.push_back(3).unwrap();
606
607        // Attempt to clone the deque.
608        let cloned = deque.try_clone();
609
610        // Verify the clone was successful and matches the original.
611        assert!(cloned.is_ok());
612        let cloned = cloned.unwrap();
613        assert_eq!(cloned.len(), deque.len());
614        {
615            let _allow_alloc_guard = AllowGlobalAllocGuard::new();
616            assert_eq!(
617                cloned.iter().collect::<InnerVec<_>>(),
618                deque.iter().collect::<InnerVec<_>>()
619            );
620        }
621    }
622
623    #[test]
624    fn test_try_clone_failure() {
625        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
626        // Set a low watermark to trigger allocation failure during cloning.
627        let wma = WatermarkAllocator::new(16); // Low watermark for small allocations.
628        let mut deque = VecDeque::new_in(wma.clone());
629
630        // Fill deque so it requires more allocation on cloning.
631        deque.push_back(1).unwrap();
632        deque.push_back(2).unwrap();
633        deque.push_back(3).unwrap();
634        deque.push_back(4).unwrap();
635
636        // Attempt to clone the deque. Expect an error due to allocation limit.
637        let cloned = deque.try_clone();
638        assert!(cloned.is_err());
639    }
640
641    #[test]
642    fn test_try_clone_from_success() {
643        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
644        let wma = WatermarkAllocator::new(128);
645        let mut original = VecDeque::new_in(wma.clone());
646
647        // Populate the original deque with some elements.
648        original.push_back(1).unwrap();
649        original.push_back(2).unwrap();
650        original.push_back(3).unwrap();
651
652        // Create a target deque with different contents to clone into.
653        let mut target = VecDeque::new_in(wma.clone());
654        target.push_back(10).unwrap();
655        target.push_back(20).unwrap();
656
657        // Use try_clone_from to clone from the original deque into the target.
658        let result = target.try_clone_from(&original);
659
660        // Verify that the clone was successful.
661        assert!(result.is_ok());
662
663        // Check that the target now matches the original.
664        assert_eq!(target.len(), original.len());
665        {
666            let _allow_global_alloc_guard = AllowGlobalAllocGuard::new();
667            assert_eq!(
668                target.iter().collect::<InnerVec<_>>(),
669                original.iter().collect::<InnerVec<_>>()
670            );
671        }
672    }
673}