@@ -1232,3 +1232,154 @@ mod impl_schemars {
12321232 }
12331233 }
12341234}
1235+
1236+ #[ cfg( all( feature = "std" , feature = "rand" ) ) ]
1237+ mod impl_rand {
1238+ use super :: { NotNan , OrderedFloat } ;
1239+ use rand:: distributions:: { Distribution , Open01 , OpenClosed01 , Standard } ;
1240+ use rand:: distributions:: uniform:: * ;
1241+ use rand:: Rng ;
1242+
1243+ macro_rules! impl_distribution {
1244+ ( $dist: ident, $( $f: ty) ,+) => {
1245+ $(
1246+ impl Distribution <NotNan <$f>> for $dist {
1247+ fn sample<R : Rng + ?Sized >( & self , rng: & mut R ) -> NotNan <$f> {
1248+ // 'rand' never generates NaN values in the Standard, Open01, or
1249+ // OpenClosed01 distributions. Using 'unchecked_new' is therefore
1250+ // safe.
1251+ unsafe { NotNan :: unchecked_new( self . sample( rng) ) }
1252+ }
1253+ }
1254+
1255+ impl Distribution <OrderedFloat <$f>> for $dist {
1256+ fn sample<R : Rng + ?Sized >( & self , rng: & mut R ) -> OrderedFloat <$f> {
1257+ OrderedFloat ( self . sample( rng) )
1258+ }
1259+ }
1260+ ) *
1261+ }
1262+ }
1263+
1264+ impl_distribution ! { Standard , f32 , f64 }
1265+ impl_distribution ! { Open01 , f32 , f64 }
1266+ impl_distribution ! { OpenClosed01 , f32 , f64 }
1267+
1268+ pub struct UniformNotNan < T > ( UniformFloat < T > ) ;
1269+ impl SampleUniform for NotNan < f32 > {
1270+ type Sampler = UniformNotNan < f32 > ;
1271+ }
1272+ impl SampleUniform for NotNan < f64 > {
1273+ type Sampler = UniformNotNan < f64 > ;
1274+ }
1275+
1276+ pub struct UniformOrdered < T > ( UniformFloat < T > ) ;
1277+ impl SampleUniform for OrderedFloat < f32 > {
1278+ type Sampler = UniformOrdered < f32 > ;
1279+ }
1280+ impl SampleUniform for OrderedFloat < f64 > {
1281+ type Sampler = UniformOrdered < f64 > ;
1282+ }
1283+
1284+ macro_rules! impl_uniform_sampler {
1285+ ( $f: ty) => {
1286+ impl UniformSampler for UniformNotNan <$f> {
1287+ type X = NotNan <$f>;
1288+ fn new<B1 , B2 >( low: B1 , high: B2 ) -> Self
1289+ where B1 : SampleBorrow <Self :: X > + Sized ,
1290+ B2 : SampleBorrow <Self :: X > + Sized
1291+ {
1292+ UniformNotNan ( UniformFloat :: <$f>:: new( low. borrow( ) . 0 , high. borrow( ) . 0 ) )
1293+ }
1294+ fn new_inclusive<B1 , B2 >( low: B1 , high: B2 ) -> Self
1295+ where B1 : SampleBorrow <Self :: X > + Sized ,
1296+ B2 : SampleBorrow <Self :: X > + Sized
1297+ {
1298+ UniformSampler :: new( low, high)
1299+ }
1300+ fn sample<R : Rng + ?Sized >( & self , rng: & mut R ) -> Self :: X {
1301+ unsafe { NotNan :: unchecked_new( self . 0 . sample( rng) ) }
1302+ }
1303+ }
1304+
1305+ impl UniformSampler for UniformOrdered <$f> {
1306+ type X = OrderedFloat <$f>;
1307+ fn new<B1 , B2 >( low: B1 , high: B2 ) -> Self
1308+ where B1 : SampleBorrow <Self :: X > + Sized ,
1309+ B2 : SampleBorrow <Self :: X > + Sized
1310+ {
1311+ UniformOrdered ( UniformFloat :: <$f>:: new( low. borrow( ) . 0 , high. borrow( ) . 0 ) )
1312+ }
1313+ fn new_inclusive<B1 , B2 >( low: B1 , high: B2 ) -> Self
1314+ where B1 : SampleBorrow <Self :: X > + Sized ,
1315+ B2 : SampleBorrow <Self :: X > + Sized
1316+ {
1317+ UniformSampler :: new( low, high)
1318+ }
1319+ fn sample<R : Rng + ?Sized >( & self , rng: & mut R ) -> Self :: X {
1320+ OrderedFloat ( self . 0 . sample( rng) )
1321+ }
1322+ }
1323+ }
1324+ }
1325+
1326+ impl_uniform_sampler ! { f32 }
1327+ impl_uniform_sampler ! { f64 }
1328+
1329+ #[ cfg( test) ]
1330+ fn sample_fuzz < T > ( )
1331+ where
1332+ Standard : Distribution < NotNan < T > > ,
1333+ Open01 : Distribution < NotNan < T > > ,
1334+ OpenClosed01 : Distribution < NotNan < T > > ,
1335+ Standard : Distribution < OrderedFloat < T > > ,
1336+ Open01 : Distribution < OrderedFloat < T > > ,
1337+ OpenClosed01 : Distribution < OrderedFloat < T > > ,
1338+ T : super :: Float ,
1339+ {
1340+ let mut rng = rand:: thread_rng ( ) ;
1341+ let f1: NotNan < T > = rng. sample ( Standard ) ;
1342+ let f2: NotNan < T > = rng. sample ( Open01 ) ;
1343+ let f3: NotNan < T > = rng. sample ( OpenClosed01 ) ;
1344+ let _: OrderedFloat < T > = rng. sample ( Standard ) ;
1345+ let _: OrderedFloat < T > = rng. sample ( Open01 ) ;
1346+ let _: OrderedFloat < T > = rng. sample ( OpenClosed01 ) ;
1347+ assert ! ( !f1. into_inner( ) . is_nan( ) ) ;
1348+ assert ! ( !f2. into_inner( ) . is_nan( ) ) ;
1349+ assert ! ( !f3. into_inner( ) . is_nan( ) ) ;
1350+ }
1351+
1352+ #[ test]
1353+ fn sampling_f32_does_not_panic ( ) {
1354+ sample_fuzz :: < f32 > ( ) ;
1355+ }
1356+
1357+ #[ test]
1358+ fn sampling_f64_does_not_panic ( ) {
1359+ sample_fuzz :: < f64 > ( ) ;
1360+ }
1361+
1362+ #[ test]
1363+ #[ should_panic]
1364+ fn uniform_sampling_panic_on_infinity_notnan ( ) {
1365+ let ( low, high) = ( NotNan :: new ( 0f64 ) . unwrap ( ) , NotNan :: new ( f64:: INFINITY ) . unwrap ( ) ) ;
1366+ let uniform = Uniform :: new ( low, high) ;
1367+ let _ = uniform. sample ( & mut rand:: thread_rng ( ) ) ;
1368+ }
1369+
1370+ #[ test]
1371+ #[ should_panic]
1372+ fn uniform_sampling_panic_on_infinity_ordered ( ) {
1373+ let ( low, high) = ( OrderedFloat ( 0f64 ) , OrderedFloat ( f64:: INFINITY ) ) ;
1374+ let uniform = Uniform :: new ( low, high) ;
1375+ let _ = uniform. sample ( & mut rand:: thread_rng ( ) ) ;
1376+ }
1377+
1378+ #[ test]
1379+ #[ should_panic]
1380+ fn uniform_sampling_panic_on_nan_ordered ( ) {
1381+ let ( low, high) = ( OrderedFloat ( 0f64 ) , OrderedFloat ( f64:: NAN ) ) ;
1382+ let uniform = Uniform :: new ( low, high) ;
1383+ let _ = uniform. sample ( & mut rand:: thread_rng ( ) ) ;
1384+ }
1385+ }
0 commit comments