@@ -77,8 +77,6 @@ use core::hash::{self, Hash};
77
77
use core:: intrinsics:: { arith_offset, assume} ;
78
78
use core:: iter:: { FromIterator , FusedIterator , TrustedLen } ;
79
79
use core:: mem;
80
- #[ cfg( not( test) ) ]
81
- use core:: num:: Float ;
82
80
use core:: ops:: { InPlace , Index , IndexMut , Place , Placer } ;
83
81
use core:: ops;
84
82
use core:: ptr;
@@ -1388,59 +1386,48 @@ impl<T: Clone> SpecFromElem for T {
1388
1386
}
1389
1387
}
1390
1388
1391
- impl SpecFromElem for u8 {
1392
- #[ inline]
1393
- fn from_elem ( elem : u8 , n : usize ) -> Vec < u8 > {
1394
- if elem == 0 {
1389
+ unsafe fn chunked_or < T , U : ops:: BitOr < Output = U > + Copy > ( x : T ) -> U {
1390
+ let p = & x as * const T as * const U ;
1391
+ let len = mem:: size_of :: < T > ( ) / mem:: size_of :: < U > ( ) ;
1392
+ slice:: from_raw_parts ( p, len) . iter ( ) . fold ( mem:: zeroed ( ) , |state, & x| state | x)
1393
+ }
1394
+
1395
+ fn is_zero < T : Copy > ( x : T ) -> bool {
1396
+ unsafe {
1397
+ match mem:: align_of :: < T > ( ) {
1398
+ n if n % 16 == 0 => 0u128 == chunked_or ( x) ,
1399
+ n if n % 8 == 0 => 0u64 == chunked_or ( x) ,
1400
+ n if n % 4 == 0 => 0u32 == chunked_or ( x) ,
1401
+ n if n % 2 == 0 => 0u16 == chunked_or ( x) ,
1402
+ _ => 0u8 == chunked_or ( x) ,
1403
+ }
1404
+ }
1405
+ }
1406
+
1407
+ impl < T : Copy > SpecFromElem for T {
1408
+ default fn from_elem ( elem : Self , n : usize ) -> Vec < Self > {
1409
+ if is_zero ( elem) {
1395
1410
return Vec {
1396
1411
buf : RawVec :: with_capacity_zeroed ( n) ,
1397
1412
len : n,
1398
1413
}
1399
1414
}
1400
- unsafe {
1401
- let mut v = Vec :: with_capacity ( n) ;
1402
- ptr:: write_bytes ( v. as_mut_ptr ( ) , elem, n) ;
1403
- v. set_len ( n) ;
1404
- v
1405
- }
1406
- }
1407
- }
1408
1415
1409
- macro_rules! impl_spec_from_elem {
1410
- ( $t: ty, $is_zero: expr) => {
1411
- impl SpecFromElem for $t {
1412
- #[ inline]
1413
- fn from_elem( elem: $t, n: usize ) -> Vec <$t> {
1414
- if $is_zero( elem) {
1415
- return Vec {
1416
- buf: RawVec :: with_capacity_zeroed( n) ,
1417
- len: n,
1418
- }
1419
- }
1420
- let mut v = Vec :: with_capacity( n) ;
1421
- v. extend_with_element( n, elem) ;
1422
- v
1416
+ let mut v = Vec :: with_capacity ( n) ;
1417
+ if mem:: size_of :: < T > ( ) == 1 {
1418
+ unsafe {
1419
+ // let elem: u8 = mem::transmute(elem);
1420
+ let elem: u8 = * ( & elem as * const T as * const u8 ) ;
1421
+ ptr:: write_bytes ( v. as_mut_ptr ( ) , elem, n) ;
1422
+ v. set_len ( n) ;
1423
1423
}
1424
+ } else {
1425
+ v. extend_with_element ( n, elem) ;
1424
1426
}
1425
- } ;
1427
+ v
1428
+ }
1426
1429
}
1427
1430
1428
- impl_spec_from_elem ! ( i8 , |x| x == 0 ) ;
1429
- impl_spec_from_elem ! ( i16 , |x| x == 0 ) ;
1430
- impl_spec_from_elem ! ( i32 , |x| x == 0 ) ;
1431
- impl_spec_from_elem ! ( i64 , |x| x == 0 ) ;
1432
- impl_spec_from_elem ! ( i128 , |x| x == 0 ) ;
1433
- impl_spec_from_elem ! ( isize , |x| x == 0 ) ;
1434
-
1435
- impl_spec_from_elem ! ( u16 , |x| x == 0 ) ;
1436
- impl_spec_from_elem ! ( u32 , |x| x == 0 ) ;
1437
- impl_spec_from_elem ! ( u64 , |x| x == 0 ) ;
1438
- impl_spec_from_elem ! ( u128 , |x| x == 0 ) ;
1439
- impl_spec_from_elem ! ( usize , |x| x == 0 ) ;
1440
-
1441
- impl_spec_from_elem ! ( f32 , |x: f32 | x == 0. && x. is_sign_positive( ) ) ;
1442
- impl_spec_from_elem ! ( f64 , |x: f64 | x == 0. && x. is_sign_positive( ) ) ;
1443
-
1444
1431
////////////////////////////////////////////////////////////////////////////////
1445
1432
// Common trait implementations for Vec
1446
1433
////////////////////////////////////////////////////////////////////////////////
0 commit comments