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