@@ -598,6 +598,148 @@ impl AddAssign for LayoutPositionPref {
598598 }
599599}
600600
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+
601743/// Integers, also used for enum discriminants.
602744#[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Hash , Debug ) ]
603745pub enum Integer {
0 commit comments