@@ -25,7 +25,7 @@ use core::{
25
25
} ;
26
26
27
27
mod errors;
28
- pub use self :: errors:: { PushError , RemoveError } ;
28
+ pub use self :: errors:: { InsertError , PushError , RemoveError } ;
29
29
30
30
/// Create a [`KVec`] containing the arguments.
31
31
///
@@ -361,6 +361,55 @@ where
361
361
unsafe { self . inc_len ( 1 ) } ;
362
362
}
363
363
364
+ /// Inserts an element at the given index in the [`Vec`] instance.
365
+ ///
366
+ /// Fails if the vector does not have capacity for the new element. Panics if the index is out
367
+ /// of bounds.
368
+ ///
369
+ /// # Examples
370
+ ///
371
+ /// ```
372
+ /// use kernel::alloc::kvec::InsertError;
373
+ ///
374
+ /// let mut v = KVec::with_capacity(5, GFP_KERNEL)?;
375
+ /// for i in 0..5 {
376
+ /// v.insert_within_capacity(0, i)?;
377
+ /// }
378
+ ///
379
+ /// assert!(matches!(v.insert_within_capacity(0, 5), Err(InsertError::OutOfCapacity(_))));
380
+ /// assert!(matches!(v.insert_within_capacity(1000, 5), Err(InsertError::IndexOutOfBounds(_))));
381
+ /// assert_eq!(v, [4, 3, 2, 1, 0]);
382
+ /// # Ok::<(), Error>(())
383
+ /// ```
384
+ pub fn insert_within_capacity (
385
+ & mut self ,
386
+ index : usize ,
387
+ element : T ,
388
+ ) -> Result < ( ) , InsertError < T > > {
389
+ let len = self . len ( ) ;
390
+ if index > len {
391
+ return Err ( InsertError :: IndexOutOfBounds ( element) ) ;
392
+ }
393
+
394
+ if len >= self . capacity ( ) {
395
+ return Err ( InsertError :: OutOfCapacity ( element) ) ;
396
+ }
397
+
398
+ // SAFETY: This is in bounds since `index <= len < capacity`.
399
+ let p = unsafe { self . as_mut_ptr ( ) . add ( index) } ;
400
+ // INVARIANT: This breaks the Vec invariants by making `index` contain an invalid element,
401
+ // but we restore the invariants below.
402
+ // SAFETY: Both the src and dst ranges end no later than one element after the length.
403
+ // Since the length is less than the capacity, both ranges are in bounds of the allocation.
404
+ unsafe { ptr:: copy ( p, p. add ( 1 ) , len - index) } ;
405
+ // INVARIANT: This restores the Vec invariants.
406
+ // SAFETY: The pointer is in-bounds of the allocation.
407
+ unsafe { ptr:: write ( p, element) } ;
408
+ // SAFETY: Index `len` contains a valid element due to the above copy and write.
409
+ unsafe { self . inc_len ( 1 ) } ;
410
+ Ok ( ( ) )
411
+ }
412
+
364
413
/// Removes the last element from a vector and returns it, or `None` if it is empty.
365
414
///
366
415
/// # Examples
0 commit comments