mutslices/lib.rs
1#![warn(
2 missing_docs,
3 missing_debug_implementations,
4 missing_copy_implementations,
5 rustdoc::broken_intra_doc_links
6)]
7//! This crate provides the ability to create many mutable slices of a vector.
8//! Slicers are created from an array of ranges.
9//!
10//! # Examples
11//!
12//! ```
13//! use mutslices::MutSlice;
14//!
15//! let vec = Vec::from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
16//! let mut mut_slice = MutSlice::vec_into(vec);
17//! let ranges = [(0, 5), (5, 10), (10, 15)];
18//! let [one, two, three] = &mut*mut_slice.slices_mut(&ranges) else { panic!(); };
19//!
20//! two.swap(2, 3);
21//! one.iter_mut().for_each(|elem| *elem = *elem * 3);
22//! one[0] = 77;
23//! two[1] = 78;
24//! one.swap_with_slice(two);
25//! two.swap_with_slice(three);
26//! three.swap_with_slice(one);
27//! let vec_from_slice = mut_slice.into_vec();
28//! assert_eq!(vec_from_slice, vec![77, 6, 9, 12, 15, 11, 12, 13, 14, 15, 6, 78, 9, 8, 10]);
29//! ```
30use std::mem::forget;
31use std::slice::from_raw_parts_mut;
32
33/// Structure to store the moved vector.
34#[derive(Debug, Clone, PartialEq, Eq)]
35pub struct MutSlice<T> {
36 vec: Vec<T>,
37}
38
39impl<T> MutSlice<T> {
40 /// Moves the vector into the structure.
41 ///
42 /// # Examples
43 ///
44 /// ```
45 /// use mutslices::MutSlice;
46 ///
47 /// let vec = vec![10, 20, 30, 40, 50];
48 /// let mut mut_slice = MutSlice::vec_into(vec);
49 /// ```
50 #[inline]
51 pub fn vec_into(mut vec: Vec<T>) -> Self {
52 let (ptr, length, capacity) = (vec.as_mut_ptr(), vec.len(), vec.capacity());
53 forget(vec);
54 Self {
55 vec: unsafe { Vec::from_raw_parts(ptr, length, capacity) },
56 }
57 }
58
59 /// Creates mutable slices.
60 ///
61 /// # Panics
62 ///
63 /// Panic if range out of the vector bounds or
64 /// ranges overlap or
65 /// the end of the range is smaller than the beginning.
66 ///
67 /// # Examples
68 ///
69 /// ```
70 /// use mutslices::MutSlice;
71 ///
72 /// let vec = Vec::from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
73 /// let mut mut_slice = MutSlice::vec_into(vec);
74 /// let ranges = [(0, 3), (3, 5), (5, 10)];
75 /// let [ref mut one, ref mut two, ref mut three] = mut_slice.slices_mut(&ranges)[..] else { panic!(); };
76 /// one[0] = 11;
77 /// two[1] = 55;
78 /// three[2] = 88;
79 /// assert_eq!(*one, &vec![11, 2, 3]);
80 /// assert_eq!(*two, &vec![4, 55]);
81 /// assert_eq!(*three, &vec![6, 7, 88, 9, 10]);
82 /// ```
83 #[inline]
84 pub fn slices_mut(&mut self, ranges: &[(usize, usize)]) -> Vec<&mut [T]> {
85 let mut vec = Vec::new();
86 let mut range_end = 0;
87 for range in ranges.iter() {
88 let (start, end) = *range;
89
90 if self.vec.len() < end {
91 panic!("Index out of range!");
92 } else if start < range_end {
93 panic!("Ranges should not overlap.");
94 } else if start >= end {
95 panic!("Range end must be larger ot equal");
96 }
97
98 unsafe {
99 vec.push(from_raw_parts_mut(
100 self.vec.as_mut_ptr().add(start),
101 end - start,
102 ))
103 };
104 range_end = end;
105 }
106 vec
107 }
108
109 /// Reconstructs a vector from a structure.
110 ///
111 /// # Examples
112 ///
113 /// ```
114 /// use mutslices::MutSlice;
115 ///
116 /// let vec = Vec::from([0, 8, 0, 9, 2, 0, 2, 3]);
117 /// let mut mut_slice = MutSlice::vec_into(vec);
118 /// let ranges = [(0, 2), (2, 4), (4, 8)];
119 /// let [day, month, year] = &mut mut_slice.slices_mut(&ranges)[..] else { panic!(); };
120 /// day[1] = 1;
121 /// month[1] = 1;
122 /// year[3] = 4;
123 ///
124 /// let rvec = mut_slice.into_vec();
125 /// assert_eq!(rvec, vec![0, 1, 0, 1, 2, 0, 2, 4]);
126 /// ```
127 #[inline]
128 pub fn into_vec(mut self) -> Vec<T> {
129 unsafe {
130 let (ptr, length, capacity) =
131 (self.vec.as_mut_ptr(), self.vec.len(), self.vec.capacity());
132 forget(self.vec);
133 Vec::from_raw_parts(ptr, length, capacity)
134 }
135 }
136}