@@ -451,6 +451,154 @@ impl AbiAndPrefAlign {
451451 }
452452}
453453
454+ /// An aligned size preference.
455+ /// Better name appreciated.
456+ #[ derive( Copy , Clone , PartialEq , Eq , Hash , Debug , RustcEncodable , RustcDecodable ) ]
457+ pub struct LayoutPositionPref {
458+ /// A size not rounded up to alignment
459+ pub size : Size ,
460+ /// the alignment of the start of the size
461+ pub align : AbiAndPrefAlign ,
462+ }
463+
464+ impl LayoutPositionPref {
465+ pub fn new_simple ( size : Size , align : Align ) -> LayoutPositionPref {
466+ LayoutPositionPref {
467+ size,
468+ align : AbiAndPrefAlign :: new ( align)
469+ }
470+ }
471+
472+ pub fn new ( size : Size , align : AbiAndPrefAlign ) -> LayoutPositionPref {
473+ LayoutPositionPref {
474+ size,
475+ align
476+ }
477+ }
478+
479+ #[ inline]
480+ pub fn from_bits ( bits : u64 ) -> LayoutPositionPref {
481+ // Avoid potential overflow from `bits + 7`.
482+ LayoutPositionPref :: from_bytes ( bits / 8 + ( ( bits % 8 ) + 7 ) / 8 )
483+ }
484+
485+ #[ inline]
486+ pub fn from_bytes ( bytes : u64 ) -> LayoutPositionPref {
487+ LayoutPositionPref :: new_simple ( Size :: from_bytes ( bytes) , Align :: from_bytes ( bytes) . unwrap ( ) )
488+ }
489+
490+ #[ inline]
491+ pub fn stride_to ( self , align : Align ) -> LayoutPositionPref {
492+ LayoutPositionPref :: new ( self . size . align_to ( align) , self . align )
493+ }
494+
495+ #[ inline]
496+ pub fn max ( self , other : LayoutPositionPref ) -> LayoutPositionPref {
497+ LayoutPositionPref :: new ( self . size . max ( other. size ) , self . align . max ( other. align ) )
498+ }
499+
500+ pub fn padding_needed_for ( self , align : Align ) -> Size {
501+ self . stride_to ( align) . size - self . size
502+ }
503+
504+ pub fn repeat ( self , count : u64 ) -> Self {
505+ return self * count
506+ }
507+
508+ pub fn extend ( self , other : LayoutPositionPref ) -> ( Self , Size ) {
509+ let p2 = self . stride_to ( other. align . abi ) . size ;
510+ ( LayoutPositionPref :: new ( p2 + other. size , self . align ) , p2)
511+ }
512+
513+ #[ inline]
514+ pub fn align_to ( self , align : AbiAndPrefAlign ) -> LayoutPositionPref {
515+ LayoutPositionPref :: new ( self . size , self . align . max ( align) )
516+ }
517+
518+ #[ inline]
519+ pub fn pack_to ( self , align : AbiAndPrefAlign ) -> LayoutPositionPref {
520+ LayoutPositionPref :: new ( self . size , self . align . min ( align) )
521+ }
522+
523+ #[ inline]
524+ pub fn align_and_stride_to ( self , align : AbiAndPrefAlign ) -> LayoutPositionPref {
525+ self . align_to ( align) . stride_to ( align. abi )
526+ }
527+
528+ pub fn strided ( self ) -> LayoutPositionPref {
529+ self . stride_to ( self . align . abi )
530+ }
531+
532+ pub fn strided_pref ( self ) -> LayoutPositionPref {
533+ self . stride_to ( self . align . pref )
534+ }
535+
536+ pub fn stride ( self ) -> Size {
537+ self . strided ( ) . size
538+ }
539+
540+ pub fn pref_stride ( self ) -> Size {
541+ self . strided_pref ( ) . size
542+ }
543+
544+ #[ inline]
545+ pub fn is_aligned ( self , align : Align ) -> bool {
546+ self . size . is_aligned ( align)
547+ }
548+
549+ #[ inline]
550+ pub fn checked_add < C : HasDataLayout > ( self , other : LayoutPositionPref , cx : & C )
551+ -> Option < LayoutPositionPref > {
552+ let size = self . stride_to ( other. align . abi ) . size . checked_add ( other. size , cx) ?;
553+ Some ( LayoutPositionPref :: new ( size, self . align ) )
554+ }
555+
556+ #[ inline]
557+ pub fn checked_mul < C : HasDataLayout > ( self , count : u64 , cx : & C ) -> Option < LayoutPositionPref > {
558+ Some ( if count == 0 {
559+ LayoutPositionPref :: new ( Size :: ZERO , self . align )
560+ } else {
561+ LayoutPositionPref :: new ( self . stride ( ) . checked_mul ( count - 1 , cx) ?, self . align ) + self
562+ } )
563+ }
564+
565+ }
566+
567+ impl Add for LayoutPositionPref {
568+ type Output = LayoutPositionPref ;
569+ #[ inline]
570+ fn add ( self , other : LayoutPositionPref ) -> LayoutPositionPref {
571+ self . extend ( other) . 0
572+ }
573+ }
574+
575+ impl Mul < LayoutPositionPref > for u64 {
576+ type Output = LayoutPositionPref ;
577+ #[ inline]
578+ fn mul ( self , size : LayoutPositionPref ) -> LayoutPositionPref {
579+ size * self
580+ }
581+ }
582+
583+ impl Mul < u64 > for LayoutPositionPref {
584+ type Output = LayoutPositionPref ;
585+ #[ inline]
586+ fn mul ( self , count : u64 ) -> LayoutPositionPref {
587+ if count == 0 {
588+ LayoutPositionPref :: new ( Size :: ZERO , self . align )
589+ } else {
590+ LayoutPositionPref :: new ( self . stride ( ) * ( count - 1 ) , self . align ) + self
591+ }
592+ }
593+ }
594+
595+ impl AddAssign for LayoutPositionPref {
596+ #[ inline]
597+ fn add_assign ( & mut self , other : LayoutPositionPref ) {
598+ * self = * self + other;
599+ }
600+ }
601+
454602/// Integers, also used for enum discriminants.
455603#[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Hash , Debug ) ]
456604pub enum Integer {
0 commit comments