@@ -486,9 +486,31 @@ impl DroplessArena {
486
486
}
487
487
}
488
488
489
+ #[ inline]
490
+ unsafe fn write_from_iter < T , I : Iterator < Item = T > > (
491
+ & self ,
492
+ mut iter : I ,
493
+ len : usize ,
494
+ mem : * mut T ,
495
+ ) -> & mut [ T ] {
496
+ let mut i = 0 ;
497
+ // Use a manual loop since LLVM manages to optimize it better for
498
+ // slice iterators
499
+ loop {
500
+ let value = iter. next ( ) ;
501
+ if i >= len || value. is_none ( ) {
502
+ // We only return as many items as the iterator gave us, even
503
+ // though it was supposed to give us `len`
504
+ return slice:: from_raw_parts_mut ( mem, i) ;
505
+ }
506
+ ptr:: write ( mem. offset ( i as isize ) , value. unwrap ( ) ) ;
507
+ i += 1 ;
508
+ }
509
+ }
510
+
489
511
#[ inline]
490
512
pub fn alloc_from_iter < T , I : IntoIterator < Item = T > > ( & self , iter : I ) -> & mut [ T ] {
491
- let mut iter = iter. into_iter ( ) ;
513
+ let iter = iter. into_iter ( ) ;
492
514
assert ! ( mem:: size_of:: <T >( ) != 0 ) ;
493
515
assert ! ( !mem:: needs_drop:: <T >( ) ) ;
494
516
@@ -505,10 +527,7 @@ impl DroplessArena {
505
527
let size = len. checked_mul ( mem:: size_of :: < T > ( ) ) . unwrap ( ) ;
506
528
let mem = self . alloc_raw ( size, mem:: align_of :: < T > ( ) ) as * mut _ as * mut T ;
507
529
unsafe {
508
- for i in 0 ..len {
509
- ptr:: write ( mem. offset ( i as isize ) , iter. next ( ) . unwrap ( ) )
510
- }
511
- slice:: from_raw_parts_mut ( mem, len)
530
+ self . write_from_iter ( iter, len, mem)
512
531
}
513
532
}
514
533
( _, _) => {
0 commit comments