diff --git a/base/random/generation.jl b/base/random/generation.jl index 3b4aa83469b7f..bb3315332f607 100644 --- a/base/random/generation.jl +++ b/base/random/generation.jl @@ -137,6 +137,32 @@ end ## Generate random integer within a range +### Bool + +struct SamplerRangeBool <: Sampler + a::Bool + mask::Bool +end + +function SamplerRangeBool(r::AbstractUnitRange{Bool}) + s = last(r) - first(r) + s < 0 && throw(ArgumentError("range must be non-empty")) + SamplerRangeBool(first(r), s % Bool) +end + +rand(rng::AbstractRNG, sp::SamplerRangeBool) = + _rand(rng, sp, rng_gen_bool(rng)) + +rng_gen_bool(::AbstractRNG) = Val(:Default) + +_rand(rng::AbstractRNG, sp::SamplerRangeBool, ::Val{:FastBool}) = + sp.a ⊻ (rand(rng, Bool) & sp.mask) + +_rand(rng::AbstractRNG, sp::SamplerRangeBool, ::Val{:Default}) = + sp.mask ? rand(rng, UInt8) % Bool : # sp.a == false + sp.a + + ### BitInteger # there are two implemented samplers for unit ranges, which assume that Float64 (i.e.