@@ -429,19 +429,37 @@ tuple_abomonate!(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z AA AB AC AD
429
429
tuple_abomonate ! ( A B C D E F G H I J K L M N O P Q R S T U V W X Y Z AA AB AC AD AE ) ;
430
430
tuple_abomonate ! ( A B C D E F G H I J K L M N O P Q R S T U V W X Y Z AA AB AC AD AE AF ) ;
431
431
432
+ unsafe impl < T : Abomonation > Abomonation for [ T ] {
433
+ unsafe fn entomb < W : Write > ( & self , write : & mut W ) -> IOResult < ( ) > {
434
+ for element in self { T :: entomb ( element, write) ?; }
435
+ Ok ( ( ) )
436
+ }
437
+
438
+ unsafe fn exhume < ' a > ( self_ : NonNull < Self > , bytes : & ' a mut [ u8 ] ) -> Option < & ' a mut [ u8 ] > {
439
+ // FIXME: This constructs an &[T] to invalid data, which is UB.
440
+ // I'm not sure if this can be fully resolved without relying on slice implementation details.
441
+ let self_len = self_. as_ref ( ) . len ( ) ;
442
+ exhume_slice ( self_. as_ptr ( ) as * mut T , self_len, bytes)
443
+ }
444
+
445
+ fn extent ( & self ) -> usize {
446
+ self . iter ( ) . map ( T :: extent) . sum ( )
447
+ }
448
+ }
449
+
432
450
macro_rules! array_abomonate {
433
451
( $size: expr) => (
434
452
unsafe impl <T : Abomonation > Abomonation for [ T ; $size] {
435
453
unsafe fn entomb<W : Write >( & self , write: & mut W ) -> IOResult <( ) > {
436
- entomb_slice ( & self [ ..] , write)
454
+ < [ T ] > :: entomb ( & self [ ..] , write)
437
455
}
438
456
439
457
unsafe fn exhume<' a>( self_: NonNull <Self >, bytes: & ' a mut [ u8 ] ) -> Option <& ' a mut [ u8 ] > {
440
458
exhume_slice( self_. as_ptr( ) as * mut T , $size, bytes)
441
459
}
442
460
443
461
fn extent( & self ) -> usize {
444
- slice_extent ( & self [ ..] )
462
+ < [ T ] > :: extent ( & self [ ..] )
445
463
}
446
464
}
447
465
)
@@ -541,30 +559,64 @@ unsafe impl Abomonation for String {
541
559
}
542
560
}
543
561
544
- unsafe impl < T : Abomonation > Abomonation for Vec < T > {
562
+ unsafe impl < T : Abomonation > Abomonation for & ' _ [ T ] {
545
563
unsafe fn entomb < W : Write > ( & self , write : & mut W ) -> IOResult < ( ) > {
546
564
write. write_all ( typed_to_bytes ( & self [ ..] ) ) ?;
547
- entomb_slice ( & self [ ..] , write)
565
+ <[ T ] >:: entomb ( & self [ ..] , write)
566
+ }
567
+
568
+ #[ inline]
569
+ unsafe fn exhume < ' a > ( self_ : NonNull < Self > , bytes : & ' a mut [ u8 ] ) -> Option < & ' a mut [ u8 ] > {
570
+ // FIXME: This (briefly) constructs an &[T] to invalid data, which is UB.
571
+ // I'm not sure if this can be fully resolved without relying on slice implementation details.
572
+ let self_len = self_. as_ref ( ) . len ( ) ;
573
+ let ( s, rest) = exhume_slice_ref ( self_len, bytes) ?;
574
+ self_. as_ptr ( ) . write ( s. as_ref ( ) ) ;
575
+ Some ( rest)
576
+ }
577
+
578
+ fn extent ( & self ) -> usize {
579
+ mem:: size_of :: < T > ( ) * self . len ( ) + <[ T ] >:: extent ( & self [ ..] )
580
+ }
581
+ }
582
+
583
+ unsafe impl < T : Abomonation > Abomonation for & ' _ mut [ T ] {
584
+ unsafe fn entomb < W : Write > ( & self , write : & mut W ) -> IOResult < ( ) > {
585
+ <& [ T ] >:: entomb ( & & self [ ..] , write)
586
+ }
587
+
588
+ #[ inline]
589
+ unsafe fn exhume < ' a > ( self_ : NonNull < Self > , bytes : & ' a mut [ u8 ] ) -> Option < & ' a mut [ u8 ] > {
590
+ // FIXME: This (briefly) constructs an &mut [T] to invalid data, which is UB.
591
+ // I'm not sure if this can be fully resolved without relying on slice implementation details.
592
+ let self_len = self_. as_ref ( ) . len ( ) ;
593
+ let ( mut s, rest) = exhume_slice_ref ( self_len, bytes) ?;
594
+ self_. as_ptr ( ) . write ( s. as_mut ( ) ) ;
595
+ Some ( rest)
596
+ }
597
+
598
+ fn extent ( & self ) -> usize {
599
+ <& [ T ] >:: extent ( & & self [ ..] )
600
+ }
601
+ }
602
+
603
+ unsafe impl < T : Abomonation > Abomonation for Vec < T > {
604
+ unsafe fn entomb < W : Write > ( & self , write : & mut W ) -> IOResult < ( ) > {
605
+ <& [ T ] >:: entomb ( & & self [ ..] , write)
548
606
}
549
607
550
608
#[ inline]
551
609
unsafe fn exhume < ' a > ( self_ : NonNull < Self > , bytes : & ' a mut [ u8 ] ) -> Option < & ' a mut [ u8 ] > {
552
610
// FIXME: This (briefly) constructs an &Vec<T> to invalid data, which is UB.
553
611
// I'm not sure if this can be fully resolved without relying on Vec implementation details.
554
612
let self_len = self_. as_ref ( ) . len ( ) ;
555
- let binary_len = self_len * mem:: size_of :: < T > ( ) ;
556
- if binary_len > bytes. len ( ) { None }
557
- else {
558
- let ( mine, mut rest) = bytes. split_at_mut ( binary_len) ;
559
- let first_ptr = mine. as_mut_ptr ( ) as * mut T ;
560
- rest = exhume_slice ( first_ptr, self_len, rest) ?;
561
- self_. as_ptr ( ) . write ( Vec :: from_raw_parts ( first_ptr, self_len, self_len) ) ;
562
- Some ( rest)
563
- }
613
+ let ( mut s, rest) = exhume_slice_ref ( self_len, bytes) ?;
614
+ self_. as_ptr ( ) . write ( Vec :: from_raw_parts ( s. as_mut ( ) . as_mut_ptr ( ) , self_len, self_len) ) ;
615
+ Some ( rest)
564
616
}
565
617
566
618
fn extent ( & self ) -> usize {
567
- mem :: size_of :: < T > ( ) * self . len ( ) + slice_extent ( & self [ ..] )
619
+ < & [ T ] > :: extent ( & & self [ ..] )
568
620
}
569
621
}
570
622
@@ -622,14 +674,8 @@ unsafe fn typed_to_bytes<T>(slice: &[T]) -> &[u8] {
622
674
std:: slice:: from_raw_parts ( slice. as_ptr ( ) as * const u8 , slice. len ( ) * mem:: size_of :: < T > ( ) )
623
675
}
624
676
625
- // Common subset of "entomb" for all [T]-like types
626
- unsafe fn entomb_slice < T : Abomonation , W : Write > ( slice : & [ T ] , write : & mut W ) -> IOResult < ( ) > {
627
- for element in slice { T :: entomb ( element, write) ?; }
628
- Ok ( ( ) )
629
- }
630
-
631
677
// Common subset of "exhume" for all [T]-like types
632
- // (I'd gladly take a NonNull< [T]> , but it is too difficult to build raw pointers to slices )
678
+ // (I'd gladly move this to [T]::extent , but building a NonNull<[T]> is currently too difficult )
633
679
#[ inline]
634
680
unsafe fn exhume_slice < ' a , T : Abomonation > ( first_ptr : * mut T , length : usize , mut bytes : & ' a mut [ u8 ] ) -> Option < & ' a mut [ u8 ] > {
635
681
for i in 0 ..length {
@@ -639,9 +685,17 @@ unsafe fn exhume_slice<'a, T: Abomonation>(first_ptr: *mut T, length: usize, mut
639
685
Some ( bytes)
640
686
}
641
687
642
- // Common subset of "extent" for all [T]-like types
643
- fn slice_extent < T : Abomonation > ( slice : & [ T ] ) -> usize {
644
- slice. iter ( ) . map ( T :: extent) . sum ( )
688
+ // Common subset of "exhume" for all &[T]-like types
689
+ #[ inline]
690
+ unsafe fn exhume_slice_ref < ' a , T : Abomonation > ( length : usize , bytes : & ' a mut [ u8 ] ) -> Option < ( NonNull < [ T ] > , & ' a mut [ u8 ] ) > {
691
+ let binary_len = length * mem:: size_of :: < T > ( ) ;
692
+ if binary_len > bytes. len ( ) { None }
693
+ else {
694
+ let ( mine, mut rest) = bytes. split_at_mut ( binary_len) ;
695
+ let first_ptr = mine. as_mut_ptr ( ) as * mut T ;
696
+ rest = exhume_slice ( first_ptr, length, rest) ?;
697
+ Some ( ( std:: slice:: from_raw_parts_mut ( first_ptr, length) . into ( ) , rest) )
698
+ }
645
699
}
646
700
647
701
// Common subset of "exhume" for all NonNull<T>-like types
0 commit comments