1#![deny(missing_docs)]
2
3extern crate uninitialized;
19
20use std::mem::replace;
21use uninitialized::UNINITIALIZED;
22use std::ptr::write_bytes;
23
24pub trait ResizeSlice {
26 fn resize(&mut self, start: usize, end: usize);
32
33 fn resize_from(&mut self, start: usize);
39
40 fn resize_to(&mut self, end: usize);
46}
47
48impl<'a, T> ResizeSlice for &'a mut [T] {
49 #[inline]
50 fn resize(&mut self, start: usize, end: usize) {
51 assert!(start <= end && end <= self.len());
52 let mut value = replace(self, &mut []);
53 value = &mut {value}[start..end];
54 replace(self, value);
55 }
56
57 #[inline]
58 fn resize_from(&mut self, start: usize) {
59 let len = self.len();
60 self.resize(start, len);
61 }
62
63 #[inline]
64 fn resize_to(&mut self, end: usize) {
65 self.resize(0, end)
66 }
67}
68
69impl<'a, T> ResizeSlice for &'a [T] {
70 #[inline]
71 fn resize(&mut self, start: usize, end: usize) {
72 *self = &self[start..end];
73 }
74
75 #[inline]
76 fn resize_from(&mut self, start: usize) {
77 *self = &self[start..];
78 }
79
80 #[inline]
81 fn resize_to(&mut self, end: usize) {
82 *self = &self[..end];
83 }
84}
85
86pub trait VecExt<T> {
88 unsafe fn uninitialized_resize(&mut self, new_len: usize);
90
91 unsafe fn zeroed_resize(&mut self, new_len: usize);
93}
94
95pub trait SliceExt<T> {
97 fn copy_from(&mut self, src: &[T]) -> usize where T: Copy;
100
101 fn copy_inner(&mut self, src: usize, dst: usize, len: usize) where T: Copy;
103}
104
105impl<T> SliceExt<T> for [T] {
106 #[inline]
107 fn copy_from(&mut self, src: &[T]) -> usize where T: Copy {
108 use std::ptr::copy_nonoverlapping;
109 use std::cmp::min;
110
111 let len = min(self.len(), src.len());
112 unsafe {
113 copy_nonoverlapping(src.as_ptr(), self.as_mut_ptr(), len);
114 }
115 len
116 }
117
118 #[inline]
119 fn copy_inner(&mut self, src: usize, dst: usize, len: usize) where T: Copy {
120 use std::ptr::copy;
121 assert!(self.len() - len >= src && self.len() - len >= dst);
122
123 unsafe {
124 copy(self.as_ptr().offset(src as isize), self.as_mut_ptr().offset(dst as isize), len);
125 }
126 }
127}
128
129impl<T> VecExt<T> for Vec<T> {
130 #[inline]
131 unsafe fn uninitialized_resize(&mut self, new_len: usize) {
132 let len = self.len();
133 if new_len > len {
134 self.reserve_exact(new_len - len);
135 }
136 self.set_len(new_len);
137 }
138
139 #[inline]
140 unsafe fn zeroed_resize(&mut self, new_len: usize) {
141 self.uninitialized_resize(new_len);
142 if !UNINITIALIZED {
143 write_bytes(self.as_mut_ptr(), 0, new_len);
144 }
145 }
146}
147
148#[cfg(feature = "smallvec")]
149mod smallvec_impl {
150 extern crate smallvec;
151 use self::smallvec::{SmallVec, Array};
152
153 use std::ptr::write_bytes;
154 use uninitialized::UNINITIALIZED;
155 use super::VecExt;
156
157 impl<T: Array> VecExt<T::Item> for SmallVec<T> {
158 #[inline]
159 unsafe fn uninitialized_resize(&mut self, new_len: usize) {
160 let len = self.len();
161 if new_len > len {
162 self.reserve_exact(new_len - len);
163 }
164 self.set_len(new_len);
165 }
166
167 #[inline]
168 unsafe fn zeroed_resize(&mut self, new_len: usize) {
169 self.uninitialized_resize(new_len);
170 if !UNINITIALIZED {
171 write_bytes(self.as_mut_ptr(), 0, new_len);
172 }
173 }
174 }
175}
176
177#[test]
178fn resize() {
179 let mut s: &mut [_] = &mut [1, 2, 3];
180 assert_eq!(s.len(), 3);
181
182 s.resize_from(1);
183 assert_eq!(s.len(), 2);
184
185 s.resize_to(1);
186 assert_eq!(s.len(), 1);
187 assert_eq!(s[0], 2);
188
189 s.resize(1, 1);
190 assert_eq!(s.len(), 0);
191}
192
193#[test]
194#[should_panic]
195fn resize_fail() {
196 let mut s: &mut [_] = &mut [1, 2, 3];
197 s.resize_to(4);
198}