@@ -90,7 +90,7 @@ pub struct SmallVec<A: Array> {
9090}
9191
9292impl < A : Array > SmallVec < A > {
93- unsafe fn set_len ( & mut self , new_len : usize ) {
93+ pub unsafe fn set_len ( & mut self , new_len : usize ) {
9494 self . len = new_len
9595 }
9696
@@ -190,6 +190,82 @@ impl<A: Array> SmallVec<A> {
190190 } ) ;
191191 }
192192 }
193+
194+ pub fn reserve ( & mut self , additional : usize ) {
195+ let len = self . len ( ) ;
196+ if self . capacity ( ) - len < additional {
197+ match len. checked_add ( additional) . and_then ( usize:: checked_next_power_of_two) {
198+ Some ( cap) => self . grow ( cap) ,
199+ None => self . grow ( usize:: max_value ( ) ) ,
200+ }
201+ }
202+ }
203+
204+ pub fn reserve_exact ( & mut self , additional : usize ) {
205+ let len = self . len ( ) ;
206+ if self . capacity ( ) - len < additional {
207+ match len. checked_add ( additional) {
208+ Some ( cap) => self . grow ( cap) ,
209+ None => panic ! ( "reserve_exact overflow" ) ,
210+ }
211+ }
212+ }
213+
214+ pub fn shrink_to_fit ( & mut self ) {
215+ let len = self . len ;
216+ if self . spilled ( ) && self . capacity ( ) > len {
217+ self . grow ( len) ;
218+ }
219+ }
220+
221+ pub fn truncate ( & mut self , len : usize ) {
222+ let end_ptr = self . as_ptr ( ) ;
223+ while len < self . len {
224+ unsafe {
225+ let last_index = self . len - 1 ;
226+ self . set_len ( last_index) ;
227+ ptr:: read ( end_ptr. offset ( last_index as isize ) ) ;
228+ }
229+ }
230+ }
231+
232+ pub fn swap_remove ( & mut self , index : usize ) -> A :: Item {
233+ let len = self . len ;
234+ self . swap ( len - 1 , index) ;
235+ self . pop ( ) . unwrap ( )
236+ }
237+
238+ pub fn clear ( & mut self ) {
239+ self . truncate ( 0 ) ;
240+ }
241+
242+ pub fn remove ( & mut self , index : usize ) -> A :: Item {
243+ let len = self . len ( ) ;
244+
245+ assert ! ( index < len) ;
246+
247+ unsafe {
248+ let ptr = self . as_mut_ptr ( ) . offset ( index as isize ) ;
249+ let item = ptr:: read ( ptr) ;
250+ ptr:: copy ( ptr. offset ( 1 ) , ptr, len - index - 1 ) ;
251+ self . set_len ( len - 1 ) ;
252+ item
253+ }
254+ }
255+
256+ pub fn insert ( & mut self , index : usize , element : A :: Item ) {
257+ self . reserve ( 1 ) ;
258+
259+ let len = self . len ;
260+ assert ! ( index <= len) ;
261+
262+ unsafe {
263+ let ptr = self . as_mut_ptr ( ) . offset ( index as isize ) ;
264+ ptr:: copy ( ptr, ptr. offset ( 1 ) , len - index) ;
265+ ptr:: write ( ptr, element) ;
266+ self . set_len ( len + 1 ) ;
267+ }
268+ }
193269}
194270
195271impl < A : Array > ops:: Deref for SmallVec < A > {
@@ -378,20 +454,20 @@ macro_rules! impl_array(
378454 }
379455) ;
380456
381- impl_array ! ( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 20 , 24 , 32 ) ;
457+ impl_array ! ( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 20 , 24 , 32 ,
458+ 0x40 , 0x80 , 0x100 , 0x200 , 0x400 , 0x800 , 0x1000 , 0x2000 , 0x4000 , 0x8000 ,
459+ 0x10000 , 0x20000 , 0x40000 , 0x80000 , 0x100000 ) ;
382460
383461#[ cfg( test) ]
384462pub mod tests {
385463 use SmallVec ;
386- use SmallVec2 ;
387- use SmallVec16 ;
388464 use std:: borrow:: ToOwned ;
389465
390466 // We heap allocate all these strings so that double frees will show up under valgrind.
391467
392468 #[ test]
393469 pub fn test_inline ( ) {
394- let mut v = SmallVec16 :: new ( ) ;
470+ let mut v = SmallVec :: < [ _ ; 16 ] > :: new ( ) ;
395471 v. push ( "hello" . to_owned ( ) ) ;
396472 v. push ( "there" . to_owned ( ) ) ;
397473 assert_eq ! ( & * v, & [
@@ -402,7 +478,7 @@ pub mod tests {
402478
403479 #[ test]
404480 pub fn test_spill ( ) {
405- let mut v = SmallVec2 :: new ( ) ;
481+ let mut v = SmallVec :: < [ _ ; 2 ] > :: new ( ) ;
406482 v. push ( "hello" . to_owned ( ) ) ;
407483 assert_eq ! ( v[ 0 ] , "hello" ) ;
408484 v. push ( "there" . to_owned ( ) ) ;
@@ -419,7 +495,7 @@ pub mod tests {
419495
420496 #[ test]
421497 pub fn test_double_spill ( ) {
422- let mut v = SmallVec2 :: new ( ) ;
498+ let mut v = SmallVec :: < [ _ ; 2 ] > :: new ( ) ;
423499 v. push ( "hello" . to_owned ( ) ) ;
424500 v. push ( "there" . to_owned ( ) ) ;
425501 v. push ( "burma" . to_owned ( ) ) ;
@@ -443,13 +519,13 @@ pub mod tests {
443519 /// https://github.com/servo/rust-smallvec/issues/4
444520 #[ test]
445521 fn issue_4 ( ) {
446- SmallVec2 :: < Box < u32 > > :: new ( ) ;
522+ SmallVec :: < [ Box < u32 > ; 2 ] > :: new ( ) ;
447523 }
448524
449525 /// https://github.com/servo/rust-smallvec/issues/5
450526 #[ test]
451527 fn issue_5 ( ) {
452- assert ! ( Some ( SmallVec2 :: <& u32 >:: new( ) ) . is_some( ) ) ;
528+ assert ! ( Some ( SmallVec :: <[ & u32 ; 2 ] >:: new( ) ) . is_some( ) ) ;
453529 }
454530
455531 #[ test]
@@ -464,4 +540,42 @@ pub mod tests {
464540 v. push ( 5 ) ;
465541 assert_eq ! ( v. into_iter( ) . collect:: <Vec <_>>( ) , & [ 3 , 4 , 5 ] ) ;
466542 }
543+
544+ #[ test]
545+ fn test_capacity ( ) {
546+ let mut v: SmallVec < [ u8 ; 2 ] > = SmallVec :: new ( ) ;
547+ v. reserve ( 1 ) ;
548+ assert_eq ! ( v. capacity( ) , 2 ) ;
549+ assert ! ( !v. spilled( ) ) ;
550+
551+ v. reserve_exact ( 0x100 ) ;
552+ assert ! ( v. capacity( ) >= 0x100 ) ;
553+
554+ v. push ( 0 ) ;
555+ v. push ( 1 ) ;
556+ v. push ( 2 ) ;
557+ v. push ( 3 ) ;
558+
559+ v. shrink_to_fit ( ) ;
560+ assert ! ( v. capacity( ) < 0x100 ) ;
561+ }
562+
563+ #[ test]
564+ fn test_truncate ( ) {
565+ let mut v: SmallVec < [ Box < u8 > ; 8 ] > = SmallVec :: new ( ) ;
566+
567+ for x in 0 ..8 {
568+ v. push ( Box :: new ( x) ) ;
569+ }
570+ v. truncate ( 4 ) ;
571+
572+ assert_eq ! ( v. len( ) , 4 ) ;
573+ assert ! ( !v. spilled( ) ) ;
574+
575+ assert_eq ! ( * v. swap_remove( 1 ) , 1 ) ;
576+ assert_eq ! ( * v. remove( 1 ) , 3 ) ;
577+ v. insert ( 1 , Box :: new ( 3 ) ) ;
578+
579+ assert_eq ! ( & v. iter( ) . map( |v| * * v) . collect:: <Vec <_>>( ) , & [ 0 , 3 , 2 ] ) ;
580+ }
467581}
0 commit comments