@@ -598,6 +598,148 @@ impl AddAssign for LayoutPositionPref {
598
598
}
599
599
}
600
600
601
+ /// An aligned size.
602
+ /// Better name appreciated.
603
+ #[ derive( Copy , Clone , PartialEq , Eq , Hash , Debug , RustcEncodable , RustcDecodable ) ]
604
+ pub struct MemoryPosition {
605
+ /// A size not rounded up to alignment
606
+ pub size : Size ,
607
+ /// the alignment of the start of the size
608
+ pub align : Align ,
609
+ }
610
+
611
+ impl LayoutPositionPref {
612
+ pub fn mem_pos ( self ) -> MemoryPosition {
613
+ MemoryPosition :: new ( self . size , self . align . abi )
614
+ }
615
+ }
616
+
617
+ impl MemoryPosition {
618
+ pub fn new ( size : Size , align : Align ) -> MemoryPosition {
619
+ MemoryPosition {
620
+ size,
621
+ align
622
+ }
623
+ }
624
+
625
+ pub fn pref_pos ( self ) -> LayoutPositionPref {
626
+ LayoutPositionPref :: new_simple ( self . size , self . align )
627
+ }
628
+
629
+ #[ inline]
630
+ pub fn from_bits ( bits : u64 ) -> MemoryPosition {
631
+ // Avoid potential overflow from `bits + 7`.
632
+ MemoryPosition :: from_bytes ( bits / 8 + ( ( bits % 8 ) + 7 ) / 8 )
633
+ }
634
+
635
+ #[ inline]
636
+ pub fn from_bytes ( bytes : u64 ) -> MemoryPosition {
637
+ MemoryPosition :: new ( Size :: from_bytes ( bytes) , Align :: from_bytes ( bytes) . unwrap ( ) )
638
+ }
639
+
640
+ #[ inline]
641
+ pub fn stride_to ( self , align : Align ) -> MemoryPosition {
642
+ MemoryPosition :: new ( self . size . align_to ( align) , self . align )
643
+ }
644
+
645
+ #[ inline]
646
+ pub fn pack_to ( self , align : Align ) -> MemoryPosition {
647
+ MemoryPosition :: new ( self . size , self . align . min ( align) )
648
+ }
649
+
650
+ #[ inline]
651
+ pub fn max ( self , other : MemoryPosition ) -> MemoryPosition {
652
+ MemoryPosition :: new ( self . size . max ( other. size ) , self . align . max ( other. align ) )
653
+ }
654
+
655
+ pub fn padding_needed_for ( self , align : Align ) -> Size {
656
+ self . stride_to ( align) . size - self . size
657
+ }
658
+
659
+ pub fn repeat ( self , count : u64 ) -> Self {
660
+ return self * count
661
+ }
662
+
663
+ pub fn extend ( self , other : MemoryPosition ) -> ( Self , Size ) {
664
+ let p2 = self . stride_to ( other. align ) . size ;
665
+ ( MemoryPosition :: new ( p2 + other. size , self . align ) , p2)
666
+ }
667
+
668
+ #[ inline]
669
+ pub fn align_to ( self , align : Align ) -> MemoryPosition {
670
+ MemoryPosition :: new ( self . size , self . align . max ( align) )
671
+ }
672
+
673
+ #[ inline]
674
+ pub fn align_and_stride_to ( self , align : Align ) -> MemoryPosition {
675
+ self . align_to ( align) . stride_to ( align)
676
+ }
677
+
678
+ pub fn strided ( self ) -> MemoryPosition {
679
+ self . stride_to ( self . align )
680
+ }
681
+
682
+ pub fn stride ( self ) -> Size {
683
+ self . strided ( ) . size
684
+ }
685
+
686
+ #[ inline]
687
+ pub fn is_aligned ( self , align : Align ) -> bool {
688
+ self . size . is_aligned ( align)
689
+ }
690
+
691
+ #[ inline]
692
+ pub fn checked_add < C : HasDataLayout > ( self , other : Self , cx : & C ) -> Option < Self > {
693
+ let size = self . stride_to ( other. align ) . size . checked_add ( other. size , cx) ?;
694
+ Some ( MemoryPosition :: new ( size, self . align ) )
695
+ }
696
+
697
+ #[ inline]
698
+ pub fn checked_mul < C : HasDataLayout > ( self , count : u64 , cx : & C ) -> Option < MemoryPosition > {
699
+ if count == 0 {
700
+ Some ( MemoryPosition :: new ( Size :: ZERO , self . align ) )
701
+ } else {
702
+ Some ( MemoryPosition :: new ( self . stride ( ) . checked_mul ( count - 1 , cx) ?, self . align ) + self )
703
+ }
704
+ }
705
+
706
+ }
707
+
708
+ impl Add for MemoryPosition {
709
+ type Output = MemoryPosition ;
710
+ #[ inline]
711
+ fn add ( self , other : MemoryPosition ) -> MemoryPosition {
712
+ self . extend ( other) . 0
713
+ }
714
+ }
715
+
716
+ impl Mul < MemoryPosition > for u64 {
717
+ type Output = MemoryPosition ;
718
+ #[ inline]
719
+ fn mul ( self , size : MemoryPosition ) -> MemoryPosition {
720
+ size * self
721
+ }
722
+ }
723
+
724
+ impl Mul < u64 > for MemoryPosition {
725
+ type Output = MemoryPosition ;
726
+ #[ inline]
727
+ fn mul ( self , count : u64 ) -> MemoryPosition {
728
+ if count == 0 {
729
+ MemoryPosition :: new ( Size :: ZERO , self . align )
730
+ } else {
731
+ MemoryPosition :: new ( self . stride ( ) * ( count - 1 ) , self . align ) + self
732
+ }
733
+ }
734
+ }
735
+
736
+ impl AddAssign for MemoryPosition {
737
+ #[ inline]
738
+ fn add_assign ( & mut self , other : MemoryPosition ) {
739
+ * self = * self + other;
740
+ }
741
+ }
742
+
601
743
/// Integers, also used for enum discriminants.
602
744
#[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Hash , Debug ) ]
603
745
pub enum Integer {
0 commit comments