@@ -2504,76 +2504,209 @@ impl fmt::Display for TryFromIntError {
2504
2504
}
2505
2505
}
2506
2506
2507
- macro_rules! same_sign_try_from_int_impl {
2508
- ( $storage: ty, $target: ty, $( $source: ty) ,* ) => { $(
2507
+ // no possible bounds violation
2508
+ macro_rules! try_from_unbounded {
2509
+ ( $source: ty, $( $target: ty) ,* ) => { $(
2509
2510
#[ unstable( feature = "try_from" , issue = "33417" ) ]
2510
2511
impl TryFrom <$source> for $target {
2511
2512
type Error = TryFromIntError ;
2512
2513
2514
+ #[ inline]
2513
2515
fn try_from( u: $source) -> Result <$target, TryFromIntError > {
2514
- let min = <$target as FromStrRadixHelper >:: min_value( ) as $storage;
2515
- let max = <$target as FromStrRadixHelper >:: max_value( ) as $storage;
2516
- if u as $storage < min || u as $storage > max {
2517
- Err ( TryFromIntError ( ( ) ) )
2518
- } else {
2516
+ Ok ( u as $target)
2517
+ }
2518
+ }
2519
+ ) * }
2520
+ }
2521
+
2522
+ // only negative bounds
2523
+ macro_rules! try_from_lower_bounded {
2524
+ ( $source: ty, $( $target: ty) ,* ) => { $(
2525
+ #[ unstable( feature = "try_from" , issue = "33417" ) ]
2526
+ impl TryFrom <$source> for $target {
2527
+ type Error = TryFromIntError ;
2528
+
2529
+ #[ inline]
2530
+ fn try_from( u: $source) -> Result <$target, TryFromIntError > {
2531
+ if u >= 0 {
2519
2532
Ok ( u as $target)
2533
+ } else {
2534
+ Err ( TryFromIntError ( ( ) ) )
2520
2535
}
2521
2536
}
2522
2537
}
2523
2538
) * }
2524
2539
}
2525
2540
2526
- same_sign_try_from_int_impl ! ( u128 , u8 , u8 , u16 , u32 , u64 , u128 , usize ) ;
2527
- same_sign_try_from_int_impl ! ( i128 , i8 , i8 , i16 , i32 , i64 , i128 , isize ) ;
2528
- same_sign_try_from_int_impl ! ( u128 , u16 , u8 , u16 , u32 , u64 , u128 , usize ) ;
2529
- same_sign_try_from_int_impl ! ( i128 , i16 , i8 , i16 , i32 , i64 , i128 , isize ) ;
2530
- same_sign_try_from_int_impl ! ( u128 , u32 , u8 , u16 , u32 , u64 , u128 , usize ) ;
2531
- same_sign_try_from_int_impl ! ( i128 , i32 , i8 , i16 , i32 , i64 , i128 , isize ) ;
2532
- same_sign_try_from_int_impl ! ( u128 , u64 , u8 , u16 , u32 , u64 , u128 , usize ) ;
2533
- same_sign_try_from_int_impl ! ( i128 , i64 , i8 , i16 , i32 , i64 , i128 , isize ) ;
2534
- same_sign_try_from_int_impl ! ( u128 , u128 , u8 , u16 , u32 , u64 , u128 , usize ) ;
2535
- same_sign_try_from_int_impl ! ( i128 , i128 , i8 , i16 , i32 , i64 , i128 , isize ) ;
2536
- same_sign_try_from_int_impl ! ( u128 , usize , u8 , u16 , u32 , u64 , u128 , usize ) ;
2537
- same_sign_try_from_int_impl ! ( i128 , isize , i8 , i16 , i32 , i64 , i128 , isize ) ;
2538
-
2539
- macro_rules! cross_sign_from_int_impl {
2540
- ( $unsigned: ty, $( $signed: ty) ,* ) => { $(
2541
+ // unsigned to signed (only positive bound)
2542
+ macro_rules! try_from_upper_bounded {
2543
+ ( $source: ty, $( $target: ty) ,* ) => { $(
2541
2544
#[ unstable( feature = "try_from" , issue = "33417" ) ]
2542
- impl TryFrom <$unsigned > for $signed {
2545
+ impl TryFrom <$source > for $target {
2543
2546
type Error = TryFromIntError ;
2544
2547
2545
- fn try_from ( u : $unsigned ) -> Result <$signed , TryFromIntError > {
2546
- let max = <$signed as FromStrRadixHelper > :: max_value ( ) as u128 ;
2547
- if u as u128 > max {
2548
+ # [ inline ]
2549
+ fn try_from ( u : $source ) -> Result <$target , TryFromIntError > {
2550
+ if u > ( <$target> :: max_value ( ) as $source ) {
2548
2551
Err ( TryFromIntError ( ( ) ) )
2549
2552
} else {
2550
- Ok ( u as $signed )
2553
+ Ok ( u as $target )
2551
2554
}
2552
2555
}
2553
2556
}
2557
+ ) * }
2558
+ }
2554
2559
2560
+ // all other cases
2561
+ macro_rules! try_from_both_bounded {
2562
+ ( $source: ty, $( $target: ty) ,* ) => { $(
2555
2563
#[ unstable( feature = "try_from" , issue = "33417" ) ]
2556
- impl TryFrom <$signed > for $unsigned {
2564
+ impl TryFrom <$source > for $target {
2557
2565
type Error = TryFromIntError ;
2558
2566
2559
- fn try_from( u: $signed) -> Result <$unsigned, TryFromIntError > {
2560
- let max = <$unsigned as FromStrRadixHelper >:: max_value( ) as u128 ;
2561
- if u < 0 || u as u128 > max {
2567
+ #[ inline]
2568
+ fn try_from( u: $source) -> Result <$target, TryFromIntError > {
2569
+ let min = <$target>:: min_value( ) as $source;
2570
+ let max = <$target>:: max_value( ) as $source;
2571
+ if u < min || u > max {
2562
2572
Err ( TryFromIntError ( ( ) ) )
2563
2573
} else {
2564
- Ok ( u as $unsigned )
2574
+ Ok ( u as $target )
2565
2575
}
2566
2576
}
2567
2577
}
2568
2578
) * }
2569
2579
}
2570
2580
2571
- cross_sign_from_int_impl ! ( u8 , i8 , i16 , i32 , i64 , i128 , isize ) ;
2572
- cross_sign_from_int_impl ! ( u16 , i8 , i16 , i32 , i64 , i128 , isize ) ;
2573
- cross_sign_from_int_impl ! ( u32 , i8 , i16 , i32 , i64 , i128 , isize ) ;
2574
- cross_sign_from_int_impl ! ( u64 , i8 , i16 , i32 , i64 , i128 , isize ) ;
2575
- cross_sign_from_int_impl ! ( u128 , i8 , i16 , i32 , i64 , i128 , isize ) ;
2576
- cross_sign_from_int_impl ! ( usize , i8 , i16 , i32 , i64 , i128 , isize ) ;
2581
+ macro_rules! rev {
2582
+ ( $mac: ident, $source: ty, $( $target: ty) ,* ) => { $(
2583
+ $mac!( $target, $source) ;
2584
+ ) * }
2585
+ }
2586
+
2587
+ /// intra-sign conversions
2588
+ try_from_unbounded ! ( u8 , u8 , u16 , u32 , u64 , u128 ) ;
2589
+ try_from_unbounded ! ( u16 , u16 , u32 , u64 , u128 ) ;
2590
+ try_from_unbounded ! ( u32 , u32 , u64 , u128 ) ;
2591
+ try_from_unbounded ! ( u64 , u64 , u128 ) ;
2592
+ try_from_unbounded ! ( u128 , u128 ) ;
2593
+ try_from_upper_bounded ! ( u16 , u8 ) ;
2594
+ try_from_upper_bounded ! ( u32 , u16 , u8 ) ;
2595
+ try_from_upper_bounded ! ( u64 , u32 , u16 , u8 ) ;
2596
+ try_from_upper_bounded ! ( u128 , u64 , u32 , u16 , u8 ) ;
2597
+
2598
+ try_from_unbounded ! ( i8 , i8 , i16 , i32 , i64 , i128 ) ;
2599
+ try_from_unbounded ! ( i16 , i16 , i32 , i64 , i128 ) ;
2600
+ try_from_unbounded ! ( i32 , i32 , i64 , i128 ) ;
2601
+ try_from_unbounded ! ( i64 , i64 , i128 ) ;
2602
+ try_from_unbounded ! ( i128 , i128 ) ;
2603
+ try_from_both_bounded ! ( i16 , i8 ) ;
2604
+ try_from_both_bounded ! ( i32 , i16 , i8 ) ;
2605
+ try_from_both_bounded ! ( i64 , i32 , i16 , i8 ) ;
2606
+ try_from_both_bounded ! ( i128 , i64 , i32 , i16 , i8 ) ;
2607
+
2608
+ // unsigned-to-signed
2609
+ try_from_unbounded ! ( u8 , i16 , i32 , i64 , i128 ) ;
2610
+ try_from_unbounded ! ( u16 , i32 , i64 , i128 ) ;
2611
+ try_from_unbounded ! ( u32 , i64 , i128 ) ;
2612
+ try_from_unbounded ! ( u64 , i128 ) ;
2613
+ try_from_upper_bounded ! ( u8 , i8 ) ;
2614
+ try_from_upper_bounded ! ( u16 , i8 , i16 ) ;
2615
+ try_from_upper_bounded ! ( u32 , i8 , i16 , i32 ) ;
2616
+ try_from_upper_bounded ! ( u64 , i8 , i16 , i32 , i64 ) ;
2617
+ try_from_upper_bounded ! ( u128 , i8 , i16 , i32 , i64 , i128 ) ;
2618
+
2619
+ // signed-to-unsigned
2620
+ try_from_lower_bounded ! ( i8 , u8 , u16 , u32 , u64 , u128 ) ;
2621
+ try_from_lower_bounded ! ( i16 , u16 , u32 , u64 , u128 ) ;
2622
+ try_from_lower_bounded ! ( i32 , u32 , u64 , u128 ) ;
2623
+ try_from_lower_bounded ! ( i64 , u64 , u128 ) ;
2624
+ try_from_lower_bounded ! ( i128 , u128 ) ;
2625
+ try_from_both_bounded ! ( i16 , u8 ) ;
2626
+ try_from_both_bounded ! ( i32 , u16 , u8 ) ;
2627
+ try_from_both_bounded ! ( i64 , u32 , u16 , u8 ) ;
2628
+ try_from_both_bounded ! ( i128 , u64 , u32 , u16 , u8 ) ;
2629
+
2630
+ #[ unstable( feature = "try_from" , issue = "33417" ) ]
2631
+ pub use self :: ptr_try_from_impls:: * ;
2632
+
2633
+ #[ cfg( target_pointer_width = "16" ) ]
2634
+ mod ptr_try_from_impls {
2635
+ use super :: TryFromIntError ;
2636
+ use convert:: TryFrom ;
2637
+
2638
+ try_from_upper_bounded ! ( usize , u8 ) ;
2639
+ try_from_unbounded ! ( usize , usize , u16 , u32 , u64 , u128 ) ;
2640
+ try_from_upper_bounded ! ( usize , i8 , i16 , isize ) ;
2641
+ try_from_unbounded ! ( usize , i32 , i64 , i128 ) ;
2642
+
2643
+ try_from_both_bounded ! ( isize , u8 ) ;
2644
+ try_from_lower_bounded ! ( isize , usize , u16 , u32 , u64 , u128 ) ;
2645
+ try_from_both_bounded ! ( isize , i8 ) ;
2646
+ try_from_unbounded ! ( isize , i16 , i32 , i64 , i128 ) ;
2647
+
2648
+ rev ! ( try_from_unbounded, usize , u8 , u16 ) ;
2649
+ rev ! ( try_from_upper_bounded, usize , u32 , u64 , u128 ) ;
2650
+ rev ! ( try_from_lower_bounded, usize , i8 , i16 ) ;
2651
+ rev ! ( try_from_both_bounded, usize , i32 , i64 , i128 ) ;
2652
+
2653
+ rev ! ( try_from_unbounded, isize , u8 ) ;
2654
+ rev ! ( try_from_upper_bounded, isize , u16 , u32 , u64 , u128 ) ;
2655
+ rev ! ( try_from_unbounded, isize , i8 , i16 ) ;
2656
+ rev ! ( try_from_both_bounded, isize , i32 , i64 , i128 ) ;
2657
+ }
2658
+
2659
+ #[ cfg( target_pointer_width = "32" ) ]
2660
+ mod ptr_try_from_impls {
2661
+ use super :: TryFromIntError ;
2662
+ use convert:: TryFrom ;
2663
+
2664
+ try_from_upper_bounded ! ( usize , u8 , u16 ) ;
2665
+ try_from_unbounded ! ( usize , usize , u32 , u64 , u128 ) ;
2666
+ try_from_upper_bounded ! ( usize , i8 , i16 , i32 , isize ) ;
2667
+ try_from_unbounded ! ( usize , i64 , i128 ) ;
2668
+
2669
+ try_from_both_bounded ! ( isize , u8 , u16 ) ;
2670
+ try_from_lower_bounded ! ( isize , usize , u32 , u64 , u128 ) ;
2671
+ try_from_both_bounded ! ( isize , i8 , i16 ) ;
2672
+ try_from_unbounded ! ( isize , i32 , i64 , i128 ) ;
2673
+
2674
+ rev ! ( try_from_unbounded, usize , u8 , u16 , u32 ) ;
2675
+ rev ! ( try_from_upper_bounded, usize , u64 , u128 ) ;
2676
+ rev ! ( try_from_lower_bounded, usize , i8 , i16 , i32 ) ;
2677
+ rev ! ( try_from_both_bounded, usize , i64 , i128 ) ;
2678
+
2679
+ rev ! ( try_from_unbounded, isize , u8 , u16 ) ;
2680
+ rev ! ( try_from_upper_bounded, isize , u32 , u64 , u128 ) ;
2681
+ rev ! ( try_from_unbounded, isize , i8 , i16 , i32 ) ;
2682
+ rev ! ( try_from_both_bounded, isize , i64 , i128 ) ;
2683
+ }
2684
+
2685
+ #[ cfg( target_pointer_width = "64" ) ]
2686
+ mod ptr_try_from_impls {
2687
+ use super :: TryFromIntError ;
2688
+ use convert:: TryFrom ;
2689
+
2690
+ try_from_upper_bounded ! ( usize , u8 , u16 , u32 ) ;
2691
+ try_from_unbounded ! ( usize , usize , u64 , u128 ) ;
2692
+ try_from_upper_bounded ! ( usize , i8 , i16 , i32 , i64 , isize ) ;
2693
+ try_from_unbounded ! ( usize , i128 ) ;
2694
+
2695
+ try_from_both_bounded ! ( isize , u8 , u16 , u32 ) ;
2696
+ try_from_lower_bounded ! ( isize , usize , u64 , u128 ) ;
2697
+ try_from_both_bounded ! ( isize , i8 , i16 , i32 ) ;
2698
+ try_from_unbounded ! ( isize , i64 , i128 ) ;
2699
+
2700
+ rev ! ( try_from_unbounded, usize , u8 , u16 , u32 , u64 ) ;
2701
+ rev ! ( try_from_upper_bounded, usize , u128 ) ;
2702
+ rev ! ( try_from_lower_bounded, usize , i8 , i16 , i32 , i64 ) ;
2703
+ rev ! ( try_from_both_bounded, usize , i128 ) ;
2704
+
2705
+ rev ! ( try_from_unbounded, isize , u8 , u16 , u32 ) ;
2706
+ rev ! ( try_from_upper_bounded, isize , u64 , u128 ) ;
2707
+ rev ! ( try_from_unbounded, isize , i8 , i16 , i32 , i64 ) ;
2708
+ rev ! ( try_from_both_bounded, isize , i128 ) ;
2709
+ }
2577
2710
2578
2711
#[ doc( hidden) ]
2579
2712
trait FromStrRadixHelper : PartialOrd + Copy {
@@ -2587,15 +2720,21 @@ trait FromStrRadixHelper: PartialOrd + Copy {
2587
2720
2588
2721
macro_rules! doit {
2589
2722
( $( $t: ty) * ) => ( $( impl FromStrRadixHelper for $t {
2723
+ #[ inline]
2590
2724
fn min_value( ) -> Self { Self :: min_value( ) }
2725
+ #[ inline]
2591
2726
fn max_value( ) -> Self { Self :: max_value( ) }
2727
+ #[ inline]
2592
2728
fn from_u32( u: u32 ) -> Self { u as Self }
2729
+ #[ inline]
2593
2730
fn checked_mul( & self , other: u32 ) -> Option <Self > {
2594
2731
Self :: checked_mul( * self , other as Self )
2595
2732
}
2733
+ #[ inline]
2596
2734
fn checked_sub( & self , other: u32 ) -> Option <Self > {
2597
2735
Self :: checked_sub( * self , other as Self )
2598
2736
}
2737
+ #[ inline]
2599
2738
fn checked_add( & self , other: u32 ) -> Option <Self > {
2600
2739
Self :: checked_add( * self , other as Self )
2601
2740
}
0 commit comments