Merge pull request #1141 from dhardy/work
Add serde1 feature for rand_distr
This commit is contained in:
@@ -92,7 +92,7 @@ jobs:
|
||||
cargo test --target ${{ matrix.target }} --manifest-path rand_core/Cargo.toml --no-default-features --features=alloc,getrandom
|
||||
- name: Test rand_distr
|
||||
run: |
|
||||
cargo test --target ${{ matrix.target }} --manifest-path rand_distr/Cargo.toml
|
||||
cargo test --target ${{ matrix.target }} --manifest-path rand_distr/Cargo.toml --features=serde1
|
||||
cargo test --target ${{ matrix.target }} --manifest-path rand_distr/Cargo.toml --no-default-features
|
||||
cargo test --target ${{ matrix.target }} --manifest-path rand_distr/Cargo.toml --no-default-features --features=std,std_math
|
||||
- name: Test rand_pcg
|
||||
@@ -134,7 +134,7 @@ jobs:
|
||||
cross test --no-fail-fast --target ${{ matrix.target }} --features=serde1,log,small_rng
|
||||
cross test --no-fail-fast --target ${{ matrix.target }} --examples
|
||||
cross test --no-fail-fast --target ${{ matrix.target }} --manifest-path rand_core/Cargo.toml
|
||||
cross test --no-fail-fast --target ${{ matrix.target }} --manifest-path rand_distr/Cargo.toml
|
||||
cross test --no-fail-fast --target ${{ matrix.target }} --manifest-path rand_distr/Cargo.toml --features=serde1
|
||||
cross test --no-fail-fast --target ${{ matrix.target }} --manifest-path rand_pcg/Cargo.toml --features=serde1
|
||||
cross test --no-fail-fast --target ${{ matrix.target }} --manifest-path rand_chacha/Cargo.toml
|
||||
cross test --no-fail-fast --target ${{ matrix.target }} --manifest-path rand_hc/Cargo.toml
|
||||
|
||||
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Make sure all distributions and their error types implement `Error`, `Display`, `Clone`,
|
||||
`Copy`, `PartialEq` and `Eq` as appropriate (#1126)
|
||||
- Port benchmarks to use Criterion crate (#1116)
|
||||
- Support serde for distributions (#1141)
|
||||
|
||||
## [0.4.0] - 2020-12-18
|
||||
- Bump `rand` to v0.8.0
|
||||
|
||||
@@ -15,15 +15,17 @@ categories = ["algorithms", "no-std"]
|
||||
edition = "2018"
|
||||
include = ["src/", "LICENSE-*", "README.md", "CHANGELOG.md", "COPYRIGHT"]
|
||||
|
||||
[dependencies]
|
||||
rand = { path = "..", version = "0.8.0", default-features = false }
|
||||
num-traits = { version = "0.2", default-features = false, features = ["libm"] }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = ["alloc", "rand/std"]
|
||||
alloc = ["rand/alloc"]
|
||||
std_math = ["num-traits/std"]
|
||||
serde1 = ["serde", "rand/serde1"]
|
||||
|
||||
[dependencies]
|
||||
rand = { path = "..", version = "0.8.0", default-features = false }
|
||||
num-traits = { version = "0.2", default-features = false, features = ["libm"] }
|
||||
serde = { version = "1.0.103", features = ["derive"], optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
rand_pcg = { version = "0.3.0", path = "../rand_pcg" }
|
||||
|
||||
+11
-6
@@ -20,11 +20,7 @@ It is worth mentioning the [statrs] crate which provides similar functionality
|
||||
along with various support functions, including PDF and CDF computation. In
|
||||
contrast, this `rand_distr` crate focuses on sampling from distributions.
|
||||
|
||||
If the `std` default feature is enabled, `rand_distr` implements the `Error`
|
||||
trait for its error types.
|
||||
|
||||
The default `alloc` feature (which is implied by the `std` feature) is required
|
||||
for some distributions (in particular, `Dirichlet` and `WeightedAliasIndex`).
|
||||
## Portability and libm
|
||||
|
||||
The floating point functions from `num_traits` and `libm` are used to support
|
||||
`no_std` environments and ensure reproducibility. If the floating point
|
||||
@@ -32,7 +28,16 @@ functions from `std` are preferred, which may provide better accuracy and
|
||||
performance but may produce different random values, the `std_math` feature
|
||||
can be enabled.
|
||||
|
||||
Links:
|
||||
## Crate features
|
||||
|
||||
- `std` (enabled by default): `rand_distr` implements the `Error` trait for
|
||||
its error types. Implies `alloc` and `rand/std`.
|
||||
- `alloc` (enabled by default): required for some distributions when not using
|
||||
`std` (in particular, `Dirichlet` and `WeightedAliasIndex`).
|
||||
- `std_math`: see above on portability and libm
|
||||
- `serde1`: implement (de)seriaialization using `serde`
|
||||
|
||||
## Links
|
||||
|
||||
- [API documentation (master)](https://rust-random.github.io/rand/rand_distr)
|
||||
- [API documentation (docs.rs)](https://docs.rs/rand_distr)
|
||||
|
||||
@@ -29,6 +29,7 @@ use core::cmp::Ordering;
|
||||
/// println!("{} is from a binomial distribution", v);
|
||||
/// ```
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct Binomial {
|
||||
/// Number of trials.
|
||||
n: u64,
|
||||
|
||||
@@ -32,6 +32,7 @@ use core::fmt;
|
||||
/// println!("{} is from a Cauchy(2, 5) distribution", v);
|
||||
/// ```
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct Cauchy<F>
|
||||
where F: Float + FloatConst, Standard: Distribution<F>
|
||||
{
|
||||
|
||||
@@ -33,6 +33,7 @@ use alloc::{boxed::Box, vec, vec::Vec};
|
||||
/// ```
|
||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct Dirichlet<F>
|
||||
where
|
||||
F: Float,
|
||||
|
||||
@@ -39,6 +39,7 @@ use core::fmt;
|
||||
/// println!("{}", val);
|
||||
/// ```
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct Exp1;
|
||||
|
||||
impl Distribution<f32> for Exp1 {
|
||||
@@ -91,6 +92,7 @@ impl Distribution<f64> for Exp1 {
|
||||
/// println!("{} is from a Exp(2) distribution", v);
|
||||
/// ```
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct Exp<F>
|
||||
where F: Float, Exp1: Distribution<F>
|
||||
{
|
||||
|
||||
@@ -21,6 +21,8 @@ use num_traits::Float;
|
||||
use crate::{Distribution, Exp, Exp1, Open01};
|
||||
use rand::Rng;
|
||||
use core::fmt;
|
||||
#[cfg(feature = "serde1")]
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
/// The Gamma distribution `Gamma(shape, scale)` distribution.
|
||||
///
|
||||
@@ -53,6 +55,7 @@ use core::fmt;
|
||||
/// (September 2000), 363-372.
|
||||
/// DOI:[10.1145/358407.358414](https://doi.acm.org/10.1145/358407.358414)
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
|
||||
pub struct Gamma<F>
|
||||
where
|
||||
F: Float,
|
||||
@@ -89,6 +92,7 @@ impl fmt::Display for Error {
|
||||
impl std::error::Error for Error {}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
|
||||
enum GammaRepr<F>
|
||||
where
|
||||
F: Float,
|
||||
@@ -116,6 +120,7 @@ where
|
||||
/// See `Gamma` for sampling from a Gamma distribution with general
|
||||
/// shape parameters.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
|
||||
struct GammaSmallShape<F>
|
||||
where
|
||||
F: Float,
|
||||
@@ -131,6 +136,7 @@ where
|
||||
/// See `Gamma` for sampling from a Gamma distribution with general
|
||||
/// shape parameters.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
|
||||
struct GammaLargeShape<F>
|
||||
where
|
||||
F: Float,
|
||||
@@ -275,6 +281,7 @@ where
|
||||
/// println!("{} is from a χ²(11) distribution", v)
|
||||
/// ```
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
|
||||
pub struct ChiSquared<F>
|
||||
where
|
||||
F: Float,
|
||||
@@ -287,6 +294,7 @@ where
|
||||
|
||||
/// Error type returned from `ChiSquared::new` and `StudentT::new`.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
|
||||
pub enum ChiSquaredError {
|
||||
/// `0.5 * k <= 0` or `nan`.
|
||||
DoFTooSmall,
|
||||
@@ -307,6 +315,7 @@ impl fmt::Display for ChiSquaredError {
|
||||
impl std::error::Error for ChiSquaredError {}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
|
||||
enum ChiSquaredRepr<F>
|
||||
where
|
||||
F: Float,
|
||||
@@ -377,6 +386,7 @@ where
|
||||
/// println!("{} is from an F(2, 32) distribution", v)
|
||||
/// ```
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
|
||||
pub struct FisherF<F>
|
||||
where
|
||||
F: Float,
|
||||
@@ -393,6 +403,7 @@ where
|
||||
|
||||
/// Error type returned from `FisherF::new`.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
|
||||
pub enum FisherFError {
|
||||
/// `m <= 0` or `nan`.
|
||||
MTooSmall,
|
||||
@@ -462,6 +473,7 @@ where
|
||||
/// println!("{} is from a t(11) distribution", v)
|
||||
/// ```
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
|
||||
pub struct StudentT<F>
|
||||
where
|
||||
F: Float,
|
||||
@@ -511,6 +523,7 @@ where
|
||||
/// Communications of the ACM 21, 317-322.
|
||||
/// https://doi.org/10.1145/359460.359482
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
|
||||
enum BetaAlgorithm<N> {
|
||||
BB(BB<N>),
|
||||
BC(BC<N>),
|
||||
@@ -518,6 +531,7 @@ enum BetaAlgorithm<N> {
|
||||
|
||||
/// Algorithm BB for `min(alpha, beta) > 1`.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
|
||||
struct BB<N> {
|
||||
alpha: N,
|
||||
beta: N,
|
||||
@@ -526,6 +540,7 @@ struct BB<N> {
|
||||
|
||||
/// Algorithm BC for `min(alpha, beta) <= 1`.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
|
||||
struct BC<N> {
|
||||
alpha: N,
|
||||
beta: N,
|
||||
@@ -546,6 +561,7 @@ struct BC<N> {
|
||||
/// println!("{} is from a Beta(2, 5) distribution", v);
|
||||
/// ```
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
|
||||
pub struct Beta<F>
|
||||
where
|
||||
F: Float,
|
||||
@@ -557,6 +573,7 @@ where
|
||||
|
||||
/// Error type returned from `Beta::new`.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
|
||||
pub enum BetaError {
|
||||
/// `alpha <= 0` or `nan`.
|
||||
AlphaTooSmall,
|
||||
|
||||
@@ -26,6 +26,7 @@ use core::fmt;
|
||||
/// println!("{} is from a Geometric(0.25) distribution", v);
|
||||
/// ```
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct Geometric
|
||||
{
|
||||
p: f64,
|
||||
@@ -151,6 +152,7 @@ impl Distribution<u64> for Geometric
|
||||
/// println!("{} is from a Geometric(0.5) distribution", v);
|
||||
/// ```
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct StandardGeometric;
|
||||
|
||||
impl Distribution<u64> for StandardGeometric {
|
||||
@@ -231,4 +233,4 @@ mod test {
|
||||
results.iter().map(|x| (x - mean) * (x - mean)).sum::<f64>() / results.len() as f64;
|
||||
assert!((variance - expected_variance).abs() < expected_variance / 10.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ use rand::distributions::uniform::Uniform;
|
||||
use core::fmt;
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
|
||||
enum SamplingMethod {
|
||||
InverseTransform{ initial_p: f64, initial_x: i64 },
|
||||
RejectionAcceptance{
|
||||
@@ -43,6 +44,7 @@ enum SamplingMethod {
|
||||
/// println!("{} is from a hypergeometric distribution", v);
|
||||
/// ```
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct Hypergeometric {
|
||||
n1: u64,
|
||||
n2: u64,
|
||||
|
||||
@@ -27,6 +27,7 @@ impl std::error::Error for Error {}
|
||||
|
||||
/// The [inverse Gaussian distribution](https://en.wikipedia.org/wiki/Inverse_Gaussian_distribution)
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct InverseGaussian<F>
|
||||
where
|
||||
F: Float,
|
||||
|
||||
@@ -37,6 +37,7 @@ use core::fmt;
|
||||
/// println!("{}", val);
|
||||
/// ```
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct StandardNormal;
|
||||
|
||||
impl Distribution<f32> for StandardNormal {
|
||||
@@ -112,6 +113,7 @@ impl Distribution<f64> for StandardNormal {
|
||||
///
|
||||
/// [`StandardNormal`]: crate::StandardNormal
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct Normal<F>
|
||||
where F: Float, StandardNormal: Distribution<F>
|
||||
{
|
||||
@@ -226,6 +228,7 @@ where F: Float, StandardNormal: Distribution<F>
|
||||
/// println!("{} is from an ln N(2, 9) distribution", v)
|
||||
/// ```
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct LogNormal<F>
|
||||
where F: Float, StandardNormal: Distribution<F>
|
||||
{
|
||||
|
||||
@@ -27,6 +27,7 @@ impl std::error::Error for Error {}
|
||||
|
||||
/// The [normal-inverse Gaussian distribution](https://en.wikipedia.org/wiki/Normal-inverse_Gaussian_distribution)
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct NormalInverseGaussian<F>
|
||||
where
|
||||
F: Float,
|
||||
|
||||
@@ -24,6 +24,7 @@ use core::fmt;
|
||||
/// println!("{}", val);
|
||||
/// ```
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct Pareto<F>
|
||||
where F: Float, OpenClosed01: Distribution<F>
|
||||
{
|
||||
|
||||
@@ -31,6 +31,7 @@ use core::fmt;
|
||||
///
|
||||
/// [`Triangular`]: crate::Triangular
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct Pert<F>
|
||||
where
|
||||
F: Float,
|
||||
|
||||
@@ -29,6 +29,7 @@ use core::fmt;
|
||||
/// println!("{} is from a Poisson(2) distribution", v);
|
||||
/// ```
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct Poisson<F>
|
||||
where F: Float + FloatConst, Standard: Distribution<F>
|
||||
{
|
||||
|
||||
@@ -32,6 +32,7 @@ use core::fmt;
|
||||
///
|
||||
/// [`Pert`]: crate::Pert
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct Triangular<F>
|
||||
where F: Float, Standard: Distribution<F>
|
||||
{
|
||||
|
||||
@@ -25,6 +25,7 @@ use rand::Rng;
|
||||
/// println!("{:?} is from the unit ball.", v)
|
||||
/// ```
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct UnitBall;
|
||||
|
||||
impl<F: Float + SampleUniform> Distribution<[F; 3]> for UnitBall {
|
||||
|
||||
@@ -29,6 +29,7 @@ use rand::Rng;
|
||||
/// NBS Appl. Math. Ser., No. 12. Washington, DC: U.S. Government Printing
|
||||
/// Office, pp. 36-38.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct UnitCircle;
|
||||
|
||||
impl<F: Float + SampleUniform> Distribution<[F; 2]> for UnitCircle {
|
||||
|
||||
@@ -24,6 +24,7 @@ use rand::Rng;
|
||||
/// println!("{:?} is from the unit Disc.", v)
|
||||
/// ```
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct UnitDisc;
|
||||
|
||||
impl<F: Float + SampleUniform> Distribution<[F; 2]> for UnitDisc {
|
||||
|
||||
@@ -28,6 +28,7 @@ use rand::Rng;
|
||||
/// Sphere.*](https://doi.org/10.1214/aoms/1177692644)
|
||||
/// Ann. Math. Statist. 43, no. 2, 645--646.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct UnitSphere;
|
||||
|
||||
impl<F: Float + SampleUniform> Distribution<[F; 3]> for UnitSphere {
|
||||
|
||||
@@ -24,6 +24,7 @@ use core::fmt;
|
||||
/// println!("{}", val);
|
||||
/// ```
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct Weibull<F>
|
||||
where F: Float, OpenClosed01: Distribution<F>
|
||||
{
|
||||
|
||||
@@ -16,6 +16,8 @@ use core::iter::Sum;
|
||||
use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
|
||||
use rand::Rng;
|
||||
use alloc::{boxed::Box, vec, vec::Vec};
|
||||
#[cfg(feature = "serde1")]
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
/// A distribution using weighted sampling to pick a discretely selected item.
|
||||
///
|
||||
@@ -64,6 +66,9 @@ use alloc::{boxed::Box, vec, vec::Vec};
|
||||
/// [`Uniform<u32>::sample`]: Distribution::sample
|
||||
/// [`Uniform<W>::sample`]: Distribution::sample
|
||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
|
||||
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "serde1", serde(bound(serialize = "W: Serialize, W::Sampler: Serialize")))]
|
||||
#[cfg_attr(feature = "serde1", serde(bound(deserialize = "W: Deserialize<'de>, W::Sampler: Deserialize<'de>")))]
|
||||
pub struct WeightedAliasIndex<W: AliasableWeight> {
|
||||
aliases: Box<[u32]>,
|
||||
no_alias_odds: Box<[W]>,
|
||||
|
||||
@@ -172,6 +172,8 @@ use serde::{Serialize, Deserialize};
|
||||
/// [`Rng::gen_range`]: Rng::gen_range
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "serde1", serde(bound(serialize = "X::Sampler: Serialize")))]
|
||||
#[cfg_attr(feature = "serde1", serde(bound(deserialize = "X::Sampler: Deserialize<'de>")))]
|
||||
pub struct Uniform<X: SampleUniform>(X::Sampler);
|
||||
|
||||
impl<X: SampleUniform> Uniform<X> {
|
||||
|
||||
Reference in New Issue
Block a user