@@ -571,61 +571,85 @@ macro_rules! arbitrary_tuple {
571
571
}
572
572
arbitrary_tuple ! ( 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 ) ;
573
573
574
- macro_rules! arbitrary_array {
575
- { $n: expr, ( $t: ident, $a: ident) $( ( $ts: ident, $as: ident) ) * } => {
576
- arbitrary_array!{ ( $n - 1 ) , $( ( $ts, $as) ) * }
577
-
578
- impl <' a, T : Arbitrary <' a>> Arbitrary <' a> for [ T ; $n] {
579
- fn arbitrary( u: & mut Unstructured <' a>) -> Result <[ T ; $n] > {
580
- Ok ( [
581
- Arbitrary :: arbitrary( u) ?,
582
- $( <$ts as Arbitrary >:: arbitrary( u) ?) ,*
583
- ] )
584
- }
585
-
586
- #[ allow( unused_mut) ]
587
- fn arbitrary_take_rest( mut u: Unstructured <' a>) -> Result <[ T ; $n] > {
588
- $( let $as = $ts:: arbitrary( & mut u) ?; ) *
589
- let last = Arbitrary :: arbitrary_take_rest( u) ?;
574
+ struct ArrayGuard < T , const N : usize > {
575
+ dst : * mut T ,
576
+ initialized : usize ,
577
+ }
590
578
591
- Ok ( [
592
- $( $as, ) * last
593
- ] )
594
- }
579
+ impl < T , const N : usize > Drop for ArrayGuard < T , N > {
580
+ fn drop ( & mut self ) {
581
+ debug_assert ! ( self . initialized <= N ) ;
582
+ let initialized_part = core:: ptr:: slice_from_raw_parts_mut ( self . dst , self . initialized ) ;
583
+ unsafe {
584
+ core:: ptr:: drop_in_place ( initialized_part) ;
585
+ }
586
+ }
587
+ }
595
588
596
- #[ inline]
597
- fn size_hint( depth: usize ) -> ( usize , Option <usize >) {
598
- crate :: size_hint:: and_all( & [
599
- <$t as Arbitrary >:: size_hint( depth) ,
600
- $( <$ts as Arbitrary >:: size_hint( depth) ) ,*
601
- ] )
602
- }
589
+ fn create_array < F , T , const N : usize > ( mut cb : F ) -> [ T ; N ]
590
+ where
591
+ F : FnMut ( usize ) -> T ,
592
+ {
593
+ let mut array: mem:: MaybeUninit < [ T ; N ] > = mem:: MaybeUninit :: uninit ( ) ;
594
+ let mut guard: ArrayGuard < T , N > = ArrayGuard {
595
+ dst : array. as_mut_ptr ( ) as _ ,
596
+ initialized : 0 ,
597
+ } ;
598
+ unsafe {
599
+ for ( idx, value_ptr) in ( & mut * array. as_mut_ptr ( ) ) . iter_mut ( ) . enumerate ( ) {
600
+ core:: ptr:: write ( value_ptr, cb ( idx) ) ;
601
+ guard. initialized += 1 ;
603
602
}
603
+ mem:: forget ( guard) ;
604
+ array. assume_init ( )
605
+ }
606
+ }
607
+
608
+ fn try_create_array < F , T , const N : usize > ( mut cb : F ) -> Result < [ T ; N ] >
609
+ where
610
+ F : FnMut ( usize ) -> Result < T > ,
611
+ {
612
+ let mut array: mem:: MaybeUninit < [ T ; N ] > = mem:: MaybeUninit :: uninit ( ) ;
613
+ let mut guard: ArrayGuard < T , N > = ArrayGuard {
614
+ dst : array. as_mut_ptr ( ) as _ ,
615
+ initialized : 0 ,
604
616
} ;
605
- ( $n: expr, ) => { } ;
617
+ unsafe {
618
+ for ( idx, value_ptr) in ( & mut * array. as_mut_ptr ( ) ) . iter_mut ( ) . enumerate ( ) {
619
+ core:: ptr:: write ( value_ptr, cb ( idx) ?) ;
620
+ guard. initialized += 1 ;
621
+ }
622
+ mem:: forget ( guard) ;
623
+ Ok ( array. assume_init ( ) )
624
+ }
606
625
}
607
626
608
- impl < ' a , T : Arbitrary < ' a > > Arbitrary < ' a > for [ T ; 0 ] {
609
- fn arbitrary ( _: & mut Unstructured < ' a > ) -> Result < [ T ; 0 ] > {
610
- Ok ( [ ] )
627
+ impl < ' a , T , const N : usize > Arbitrary < ' a > for [ T ; N ]
628
+ where
629
+ T : Arbitrary < ' a > ,
630
+ {
631
+ #[ inline]
632
+ fn arbitrary ( u : & mut Unstructured < ' a > ) -> Result < Self > {
633
+ try_create_array ( |_| <T as Arbitrary < ' a > >:: arbitrary ( u) )
611
634
}
612
635
613
- fn arbitrary_take_rest ( _: Unstructured < ' a > ) -> Result < [ T ; 0 ] > {
614
- Ok ( [ ] )
636
+ #[ inline]
637
+ fn arbitrary_take_rest ( mut u : Unstructured < ' a > ) -> Result < Self > {
638
+ let mut array = Self :: arbitrary ( & mut u) ?;
639
+ if let Some ( last) = array. last_mut ( ) {
640
+ * last = Arbitrary :: arbitrary_take_rest ( u) ?;
641
+ }
642
+ Ok ( array)
615
643
}
616
644
617
645
#[ inline]
618
- fn size_hint ( _: usize ) -> ( usize , Option < usize > ) {
619
- crate :: size_hint:: and_all ( & [ ] )
646
+ fn size_hint ( d : usize ) -> ( usize , Option < usize > ) {
647
+ crate :: size_hint:: and_all ( & create_array :: < _ , ( usize , Option < usize > ) , N > ( |_| {
648
+ <T as Arbitrary >:: size_hint ( d)
649
+ } ) )
620
650
}
621
651
}
622
652
623
- arbitrary_array ! { 32 , ( T , a) ( T , b) ( T , c) ( T , d) ( T , e) ( T , f) ( T , g) ( T , h)
624
- ( T , i) ( T , j) ( T , k) ( T , l) ( T , m) ( T , n) ( T , o) ( T , p)
625
- ( T , q) ( T , r) ( T , s) ( T , u) ( T , v) ( T , w) ( T , x) ( T , y)
626
- ( T , z) ( T , aa) ( T , ab) ( T , ac) ( T , ad) ( T , ae) ( T , af)
627
- ( T , ag) }
628
-
629
653
impl < ' a > Arbitrary < ' a > for & ' a [ u8 ] {
630
654
fn arbitrary ( u : & mut Unstructured < ' a > ) -> Result < Self > {
631
655
let len = u. arbitrary_len :: < u8 > ( ) ?;
0 commit comments