@@ -436,57 +436,135 @@ pub trait Bitwise: Bounded
436
436
/// assert_eq!(n.trailing_zeros(), 3);
437
437
/// ```
438
438
fn trailing_zeros ( & self ) -> Self ;
439
+
440
+ /// Reverses the byte order of a binary number.
441
+ ///
442
+ /// # Example
443
+ ///
444
+ /// ```rust
445
+ /// use std::num::Bitwise;
446
+ ///
447
+ /// let n = 0x0123456789ABCDEFu64;
448
+ /// let m = 0xEFCDAB8967452301u64;
449
+ /// assert_eq!(n.swap_bytes(), m);
450
+ /// ```
451
+ fn swap_bytes ( & self ) -> Self ;
452
+
453
+ /// Shifts the bits to the left by a specified amount amount, `r`, wrapping
454
+ /// the truncated bits to the end of the resulting value.
455
+ ///
456
+ /// # Example
457
+ ///
458
+ /// ```rust
459
+ /// use std::num::Bitwise;
460
+ ///
461
+ /// let n = 0x0123456789ABCDEFu64;
462
+ /// let m = 0x3456789ABCDEF012u64;
463
+ /// assert_eq!(n.rotate_left(12), m);
464
+ /// ```
465
+ fn rotate_left ( & self , r : uint ) -> Self ;
466
+
467
+ /// Shifts the bits to the right by a specified amount amount, `r`, wrapping
468
+ /// the truncated bits to the beginning of the resulting value.
469
+ ///
470
+ /// # Example
471
+ ///
472
+ /// ```rust
473
+ /// use std::num::Bitwise;
474
+ ///
475
+ /// let n = 0x0123456789ABCDEFu64;
476
+ /// let m = 0xDEF0123456789ABCu64;
477
+ /// assert_eq!(n.rotate_right(12), m);
478
+ /// ```
479
+ fn rotate_right ( & self , r : uint ) -> Self ;
439
480
}
440
481
482
+ /// Swapping a single byte does nothing. This is unsafe to be consistent with
483
+ /// the other `bswap` intrinsics.
484
+ #[ inline]
485
+ unsafe fn bswap8 ( x : u8 ) -> u8 { x }
486
+
441
487
macro_rules! bitwise_impl(
442
- ( $t: ty, $co: path , $lz: path , $tz: path) => {
488
+ ( $t: ty, $bits : expr , $ co: ident , $lz: ident , $tz: ident , $bs : path) => {
443
489
impl Bitwise for $t {
444
490
#[ inline]
445
- fn count_ones( & self ) -> $t { unsafe { $co( * self ) } }
491
+ fn count_ones( & self ) -> $t { unsafe { intrinsics :: $co( * self ) } }
446
492
447
493
#[ inline]
448
- fn leading_zeros( & self ) -> $t { unsafe { $lz( * self ) } }
494
+ fn leading_zeros( & self ) -> $t { unsafe { intrinsics :: $lz( * self ) } }
449
495
450
496
#[ inline]
451
- fn trailing_zeros( & self ) -> $t { unsafe { $tz( * self ) } }
497
+ fn trailing_zeros( & self ) -> $t { unsafe { intrinsics:: $tz( * self ) } }
498
+
499
+ #[ inline]
500
+ fn swap_bytes( & self ) -> $t { unsafe { $bs( * self ) } }
501
+
502
+ #[ inline]
503
+ fn rotate_left( & self , r: uint) -> $t {
504
+ // Protect against undefined behaviour for overlong bit shifts
505
+ let r = r % $bits;
506
+ ( * self << r) | ( * self >> ( $bits - r) )
507
+ }
508
+
509
+ #[ inline]
510
+ fn rotate_right( & self , r: uint) -> $t {
511
+ // Protect against undefined behaviour for overlong bit shifts
512
+ let r = r % $bits;
513
+ ( * self >> r) | ( * self << ( $bits - r) )
514
+ }
452
515
}
453
516
}
454
517
)
455
518
456
519
macro_rules! bitwise_cast_impl(
457
- ( $t: ty, $t_cast: ty, $co: path , $lz: path , $tz: path) => {
520
+ ( $t: ty, $t_cast: ty, $bits : expr , $co: ident , $lz: ident , $tz: ident , $bs : path) => {
458
521
impl Bitwise for $t {
459
522
#[ inline]
460
- fn count_ones( & self ) -> $t { unsafe { $co( * self as $t_cast) as $t } }
523
+ fn count_ones( & self ) -> $t { unsafe { intrinsics:: $co( * self as $t_cast) as $t } }
524
+
525
+ #[ inline]
526
+ fn leading_zeros( & self ) -> $t { unsafe { intrinsics:: $lz( * self as $t_cast) as $t } }
527
+
528
+ #[ inline]
529
+ fn trailing_zeros( & self ) -> $t { unsafe { intrinsics:: $tz( * self as $t_cast) as $t } }
461
530
462
531
#[ inline]
463
- fn leading_zeros ( & self ) -> $t { unsafe { $lz ( * self as $t_cast) as $t } }
532
+ fn swap_bytes ( & self ) -> $t { unsafe { $bs ( * self as $t_cast) as $t } }
464
533
465
534
#[ inline]
466
- fn trailing_zeros( & self ) -> $t { unsafe { $tz( * self as $t_cast) as $t } }
535
+ fn rotate_left( & self , r: uint) -> $t {
536
+ // cast to prevent the sign bit from being corrupted
537
+ ( * self as $t_cast) . rotate_left( r) as $t
538
+ }
539
+
540
+ #[ inline]
541
+ fn rotate_right( & self , r: uint) -> $t {
542
+ // cast to prevent the sign bit from being corrupted
543
+ ( * self as $t_cast) . rotate_right( r) as $t
544
+ }
467
545
}
468
546
}
469
547
)
470
548
471
549
#[ cfg( target_word_size = "32" ) ]
472
- bitwise_cast_impl ! ( uint, u32 , intrinsics :: ctpop32, intrinsics :: ctlz32, intrinsics:: cttz32 )
550
+ bitwise_cast_impl ! ( uint, u32 , 32 , ctpop32, ctlz32, cttz32 , intrinsics:: bswap32 )
473
551
#[ cfg( target_word_size = "64" ) ]
474
- bitwise_cast_impl ! ( uint, u64 , intrinsics :: ctpop64, intrinsics :: ctlz64, intrinsics:: cttz64 )
552
+ bitwise_cast_impl ! ( uint, u64 , 64 , ctpop64, ctlz64, cttz64 , intrinsics:: bswap64 )
475
553
476
- bitwise_impl ! ( u8 , intrinsics :: ctpop8, intrinsics :: ctlz8, intrinsics :: cttz8)
477
- bitwise_impl ! ( u16 , intrinsics :: ctpop16, intrinsics :: ctlz16, intrinsics:: cttz16 )
478
- bitwise_impl ! ( u32 , intrinsics :: ctpop32, intrinsics :: ctlz32, intrinsics:: cttz32 )
479
- bitwise_impl ! ( u64 , intrinsics :: ctpop64, intrinsics :: ctlz64, intrinsics:: cttz64 )
554
+ bitwise_impl ! ( u8 , 8 , ctpop8, ctlz8, cttz8, bswap8 )
555
+ bitwise_impl ! ( u16 , 16 , ctpop16, ctlz16, cttz16 , intrinsics:: bswap16 )
556
+ bitwise_impl ! ( u32 , 32 , ctpop32, ctlz32, cttz32 , intrinsics:: bswap32 )
557
+ bitwise_impl ! ( u64 , 64 , ctpop64, ctlz64, cttz64 , intrinsics:: bswap64 )
480
558
481
559
#[ cfg( target_word_size = "32" ) ]
482
- bitwise_cast_impl ! ( int, u32 , intrinsics :: ctpop32, intrinsics :: ctlz32, intrinsics:: cttz32 )
560
+ bitwise_cast_impl ! ( int, u32 , 32 , ctpop32, ctlz32, cttz32 , intrinsics:: bswap32 )
483
561
#[ cfg( target_word_size = "64" ) ]
484
- bitwise_cast_impl ! ( int, u64 , intrinsics :: ctpop64, intrinsics :: ctlz64, intrinsics:: cttz64 )
562
+ bitwise_cast_impl ! ( int, u64 , 64 , ctpop64, ctlz64, cttz64 , intrinsics:: bswap64 )
485
563
486
- bitwise_cast_impl ! ( i8 , u8 , intrinsics :: ctpop8, intrinsics :: ctlz8, intrinsics :: cttz8)
487
- bitwise_cast_impl ! ( i16 , u16 , intrinsics :: ctpop16, intrinsics :: ctlz16, intrinsics:: cttz16 )
488
- bitwise_cast_impl ! ( i32 , u32 , intrinsics :: ctpop32, intrinsics :: ctlz32, intrinsics:: cttz32 )
489
- bitwise_cast_impl ! ( i64 , u64 , intrinsics :: ctpop64, intrinsics :: ctlz64, intrinsics:: cttz64 )
564
+ bitwise_cast_impl ! ( i8 , u8 , 8 , ctpop8, ctlz8, cttz8, bswap8 )
565
+ bitwise_cast_impl ! ( i16 , u16 , 16 , ctpop16, ctlz16, cttz16 , intrinsics:: bswap16 )
566
+ bitwise_cast_impl ! ( i32 , u32 , 32 , ctpop32, ctlz32, cttz32 , intrinsics:: bswap32 )
567
+ bitwise_cast_impl ! ( i64 , u64 , 64 , ctpop64, ctlz64, cttz64 , intrinsics:: bswap64 )
490
568
491
569
/// Specifies the available operations common to all of Rust's core numeric primitives.
492
570
/// These may not always make sense from a purely mathematical point of view, but
0 commit comments