@@ -77,8 +77,6 @@ use core::hash::{self, Hash};
7777use core:: intrinsics:: { arith_offset, assume} ;
7878use core:: iter:: { FromIterator , FusedIterator , TrustedLen } ;
7979use core:: mem;
80- #[ cfg( not( test) ) ]
81- use core:: num:: Float ;
8280use core:: ops:: { InPlace , Index , IndexMut , Place , Placer } ;
8381use core:: ops;
8482use core:: ptr;
@@ -1388,59 +1386,48 @@ impl<T: Clone> SpecFromElem for T {
13881386 }
13891387}
13901388
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) {
13951410 return Vec {
13961411 buf : RawVec :: with_capacity_zeroed ( n) ,
13971412 len : n,
13981413 }
13991414 }
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- }
14081415
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) ;
14231423 }
1424+ } else {
1425+ v. extend_with_element ( n, elem) ;
14241426 }
1425- } ;
1427+ v
1428+ }
14261429}
14271430
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-
14441431////////////////////////////////////////////////////////////////////////////////
14451432// Common trait implementations for Vec
14461433////////////////////////////////////////////////////////////////////////////////
0 commit comments