@@ -451,6 +451,154 @@ impl AbiAndPrefAlign {
451
451
}
452
452
}
453
453
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
+
454
602
/// Integers, also used for enum discriminants.
455
603
#[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Hash , Debug ) ]
456
604
pub enum Integer {
0 commit comments