47
47
//! Tracking issue: [rust-lang/rust#34761](https://github.com/rust-lang/rust/issues/34761)
48
48
49
49
#![ no_std]
50
+ #![ cfg_attr( docsrs, feature( doc_cfg) ) ]
51
+ #![ cfg_attr( feature = "specialization" , allow( incomplete_features) ) ]
52
+ #![ cfg_attr( feature = "specialization" , feature( specialization) ) ]
53
+ #![ cfg_attr( feature = "may_dangle" , feature( dropck_eyepatch) ) ]
50
54
51
55
#[ doc( hidden) ]
52
56
pub extern crate alloc;
@@ -73,8 +77,8 @@ use core::ptr::addr_of;
73
77
use core:: ptr:: addr_of_mut;
74
78
use core:: ptr:: copy_nonoverlapping;
75
79
76
- #[ cfg( feature = "serde" ) ]
77
80
use core:: marker:: PhantomData ;
81
+
78
82
#[ cfg( feature = "serde" ) ]
79
83
use serde:: {
80
84
de:: { Deserialize , Deserializer , SeqAccess , Visitor } ,
@@ -279,6 +283,7 @@ impl TaggedLen {
279
283
pub struct SmallVec < T , const N : usize > {
280
284
len : TaggedLen ,
281
285
raw : RawSmallVec < T , N > ,
286
+ _marker : PhantomData < T > ,
282
287
}
283
288
284
289
/// An iterator that removes the items from a `SmallVec` and yields them by value.
@@ -361,6 +366,7 @@ pub struct IntoIter<T, const N: usize> {
361
366
raw : RawSmallVec < T , N > ,
362
367
begin : usize ,
363
368
end : TaggedLen ,
369
+ _marker : PhantomData < T > ,
364
370
}
365
371
366
372
impl < T , const N : usize > IntoIter < T , N > {
@@ -468,13 +474,16 @@ impl<T, const N: usize> SmallVec<T, N> {
468
474
Self {
469
475
len : TaggedLen :: new ( 0 , false , Self :: is_zst ( ) ) ,
470
476
raw : RawSmallVec :: new ( ) ,
477
+ _marker : PhantomData ,
471
478
}
472
479
}
473
480
474
481
#[ inline]
475
482
pub fn with_capacity ( capacity : usize ) -> Self {
476
483
let mut this = Self :: new ( ) ;
477
- this. reserve_exact ( capacity) ;
484
+ if capacity > Self :: inline_size ( ) {
485
+ this. grow ( capacity) ;
486
+ }
478
487
this
479
488
}
480
489
@@ -494,6 +503,7 @@ impl<T, const N: usize> SmallVec<T, N> {
494
503
Self {
495
504
len : TaggedLen :: new ( len, false , Self :: is_zst ( ) ) ,
496
505
raw : RawSmallVec :: new ( ) ,
506
+ _marker : PhantomData ,
497
507
}
498
508
} else {
499
509
let mut vec = ManuallyDrop :: new ( vec) ;
@@ -504,6 +514,7 @@ impl<T, const N: usize> SmallVec<T, N> {
504
514
Self {
505
515
len : TaggedLen :: new ( len, true , Self :: is_zst ( ) ) ,
506
516
raw : RawSmallVec :: new_heap ( ptr, cap) ,
517
+ _marker : PhantomData ,
507
518
}
508
519
}
509
520
}
@@ -513,6 +524,7 @@ impl<T, const N: usize> SmallVec<T, N> {
513
524
Self {
514
525
len : TaggedLen :: new ( N , false , Self :: is_zst ( ) ) ,
515
526
raw : RawSmallVec :: new_inline ( MaybeUninit :: new ( buf) ) ,
527
+ _marker : PhantomData ,
516
528
}
517
529
}
518
530
@@ -522,6 +534,7 @@ impl<T, const N: usize> SmallVec<T, N> {
522
534
let mut vec = Self {
523
535
len : TaggedLen :: new ( len, false , Self :: is_zst ( ) ) ,
524
536
raw : RawSmallVec :: new_inline ( MaybeUninit :: new ( buf) ) ,
537
+ _marker : PhantomData ,
525
538
} ;
526
539
// Deallocate the remaining elements so no memory is leaked.
527
540
unsafe {
@@ -545,6 +558,7 @@ impl<T, const N: usize> SmallVec<T, N> {
545
558
Self {
546
559
len : TaggedLen :: new ( len, false , Self :: is_zst ( ) ) ,
547
560
raw : RawSmallVec :: new_inline ( buf) ,
561
+ _marker : PhantomData ,
548
562
}
549
563
}
550
564
@@ -684,7 +698,7 @@ impl<T, const N: usize> SmallVec<T, N> {
684
698
infallible ( self . try_grow ( new_capacity) ) ;
685
699
}
686
700
687
- #[ inline ]
701
+ #[ cold ]
688
702
pub fn try_grow ( & mut self , new_capacity : usize ) -> Result < ( ) , CollectionAllocErr > {
689
703
let len = self . len ( ) ;
690
704
assert ! ( new_capacity >= len) ;
@@ -1043,6 +1057,7 @@ impl<T, const N: usize> SmallVec<T, N> {
1043
1057
SmallVec {
1044
1058
len : TaggedLen :: new ( length, true , Self :: is_zst ( ) ) ,
1045
1059
raw : RawSmallVec :: new_heap ( ptr, capacity) ,
1060
+ _marker : PhantomData ,
1046
1061
}
1047
1062
}
1048
1063
@@ -1070,14 +1085,23 @@ impl<T: Copy, const N: usize> SmallVec<T, N> {
1070
1085
#[ inline]
1071
1086
pub fn from_slice ( slice : & [ T ] ) -> Self {
1072
1087
let len = slice. len ( ) ;
1073
-
1074
- let mut this = Self :: with_capacity ( len) ;
1075
- let ptr = this. as_mut_ptr ( ) ;
1076
- unsafe {
1077
- copy_nonoverlapping ( slice. as_ptr ( ) , ptr, len) ;
1078
- this. set_len ( len) ;
1088
+ if len <= Self :: inline_size ( ) {
1089
+ let mut this = Self :: new ( ) ;
1090
+ unsafe {
1091
+ let ptr = this. raw . as_mut_ptr_inline ( ) ;
1092
+ copy_nonoverlapping ( slice. as_ptr ( ) , ptr, len) ;
1093
+ this. set_len ( len) ;
1094
+ }
1095
+ this
1096
+ } else {
1097
+ let mut this = Vec :: with_capacity ( len) ;
1098
+ unsafe {
1099
+ let ptr = this. as_mut_ptr ( ) ;
1100
+ copy_nonoverlapping ( slice. as_ptr ( ) , ptr, len) ;
1101
+ this. set_len ( len) ;
1102
+ }
1103
+ Self :: from_vec ( this)
1079
1104
}
1080
- this
1081
1105
}
1082
1106
1083
1107
#[ inline]
@@ -1250,6 +1274,29 @@ impl Drop for DropDealloc {
1250
1274
}
1251
1275
}
1252
1276
1277
+ #[ cfg( feature = "may_dangle" ) ]
1278
+ unsafe impl < #[ may_dangle] T , const N : usize > Drop for SmallVec < T , N > {
1279
+ fn drop ( & mut self ) {
1280
+ let on_heap = self . spilled ( ) ;
1281
+ let len = self . len ( ) ;
1282
+ let ptr = self . as_mut_ptr ( ) ;
1283
+ unsafe {
1284
+ let _drop_dealloc = if on_heap {
1285
+ let capacity = self . capacity ( ) ;
1286
+ Some ( DropDealloc {
1287
+ ptr : ptr as * mut u8 ,
1288
+ size_bytes : capacity * size_of :: < T > ( ) ,
1289
+ align : align_of :: < T > ( ) ,
1290
+ } )
1291
+ } else {
1292
+ None
1293
+ } ;
1294
+ core:: ptr:: slice_from_raw_parts_mut ( ptr, len) . drop_in_place ( ) ;
1295
+ }
1296
+ }
1297
+ }
1298
+
1299
+ #[ cfg( not( feature = "may_dangle" ) ) ]
1253
1300
impl < T , const N : usize > Drop for SmallVec < T , N > {
1254
1301
fn drop ( & mut self ) {
1255
1302
let on_heap = self . spilled ( ) ;
@@ -1318,6 +1365,36 @@ impl<T, const N: usize> core::iter::FromIterator<T> for SmallVec<T, N> {
1318
1365
}
1319
1366
}
1320
1367
1368
+ #[ cfg( feature = "specialization" ) ]
1369
+ trait SpecFrom {
1370
+ type Element ;
1371
+ fn spec_from ( slice : & [ Self :: Element ] ) -> Self ;
1372
+ }
1373
+
1374
+ #[ cfg( feature = "specialization" ) ]
1375
+ impl < T : Clone , const N : usize > SpecFrom for SmallVec < T , N > {
1376
+ type Element = T ;
1377
+
1378
+ default fn spec_from ( slice : & [ Self :: Element ] ) -> Self {
1379
+ slice. iter ( ) . cloned ( ) . collect ( )
1380
+ }
1381
+ }
1382
+
1383
+ #[ cfg( feature = "specialization" ) ]
1384
+ impl < T : Copy , const N : usize > SpecFrom for SmallVec < T , N > {
1385
+ fn spec_from ( slice : & [ Self :: Element ] ) -> Self {
1386
+ Self :: from_slice ( slice)
1387
+ }
1388
+ }
1389
+
1390
+ #[ cfg( feature = "specialization" ) ]
1391
+ impl < ' a , T : Clone , const N : usize > From < & ' a [ T ] > for SmallVec < T , N > {
1392
+ fn from ( slice : & ' a [ T ] ) -> Self {
1393
+ <Self as SpecFrom >:: spec_from ( slice)
1394
+ }
1395
+ }
1396
+
1397
+ #[ cfg( not( feature = "specialization" ) ) ]
1321
1398
impl < ' a , T : Clone , const N : usize > From < & ' a [ T ] > for SmallVec < T , N > {
1322
1399
fn from ( slice : & ' a [ T ] ) -> Self {
1323
1400
slice. iter ( ) . cloned ( ) . collect ( )
@@ -1408,6 +1485,7 @@ impl<T, const N: usize> IntoIterator for SmallVec<T, N> {
1408
1485
raw : ( & this. raw as * const RawSmallVec < T , N > ) . read ( ) ,
1409
1486
begin : 0 ,
1410
1487
end : this. len ,
1488
+ _marker : PhantomData ,
1411
1489
}
1412
1490
}
1413
1491
}
0 commit comments