1 // Written in the D programming language.
2 
3 /**
4 Facilities for random number generation.
5 
6 $(SCRIPT inhibitQuickIndex = 1;)
7 $(DIVC quickindex,
8 $(BOOKTABLE,
9 $(TR $(TH Category) $(TH Functions))
10 $(TR $(TD Uniform sampling) $(TD
11     $(LREF uniform)
12     $(LREF uniform01)
13     $(LREF uniformDistribution)
14 ))
15 $(TR $(TD Element sampling) $(TD
16     $(LREF choice)
17     $(LREF dice)
18 ))
19 $(TR $(TD Range sampling) $(TD
20     $(LREF randomCover)
21     $(LREF randomSample)
22 ))
23 $(TR $(TD Default Random Engines) $(TD
24     $(LREF rndGen)
25     $(LREF Random)
26     $(LREF unpredictableSeed)
27 ))
28 $(TR $(TD Linear Congruential Engines) $(TD
29     $(LREF MinstdRand)
30     $(LREF MinstdRand0)
31     $(LREF LinearCongruentialEngine)
32 ))
33 $(TR $(TD Mersenne Twister Engines) $(TD
34     $(LREF Mt19937)
35     $(LREF Mt19937_64)
36     $(LREF MersenneTwisterEngine)
37 ))
38 $(TR $(TD Xorshift Engines) $(TD
39     $(LREF Xorshift)
40     $(LREF XorshiftEngine)
41     $(LREF Xorshift32)
42     $(LREF Xorshift64)
43     $(LREF Xorshift96)
44     $(LREF Xorshift128)
45     $(LREF Xorshift160)
46     $(LREF Xorshift192)
47 ))
48 $(TR $(TD Shuffle) $(TD
49     $(LREF partialShuffle)
50     $(LREF randomShuffle)
51 ))
52 $(TR $(TD Traits) $(TD
53     $(LREF isSeedable)
54     $(LREF isUniformRNG)
55 ))
56 ))
57 
58 $(RED Disclaimer:) The random number generators and API provided in this
59 module are not designed to be cryptographically secure, and are therefore
60 unsuitable for cryptographic or security-related purposes such as generating
61 authentication tokens or network sequence numbers. For such needs, please use a
62 reputable cryptographic library instead.
63 
64 The new-style generator objects hold their own state so they are
65 immune of threading issues. The generators feature a number of
66 well-known and well-documented methods of generating random
67 numbers. An overall fast and reliable means to generate random numbers
68 is the $(D_PARAM Mt19937) generator, which derives its name from
69 "$(LINK2 https://en.wikipedia.org/wiki/Mersenne_Twister, Mersenne Twister)
70 with a period of 2 to the power of
71 19937". In memory-constrained situations,
72 $(LINK2 https://en.wikipedia.org/wiki/Linear_congruential_generator,
73 linear congruential generators) such as `MinstdRand0` and `MinstdRand` might be
74 useful. The standard library provides an alias $(D_PARAM Random) for
75 whichever generator it considers the most fit for the target
76 environment.
77 
78 In addition to random number generators, this module features
79 distributions, which skew a generator's output statistical
80 distribution in various ways. So far the uniform distribution for
81 integers and real numbers have been implemented.
82 
83 Source:    $(PHOBOSSRC std/random.d)
84 
85 Macros:
86 
87 Copyright: Copyright Andrei Alexandrescu 2008 - 2009, Joseph Rushton Wakeling 2012.
88 License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
89 Authors:   $(HTTP erdani.org, Andrei Alexandrescu)
90            Masahiro Nakagawa (Xorshift random generator)
91            $(HTTP braingam.es, Joseph Rushton Wakeling) (Algorithm D for random sampling)
92            Ilya Yaroshenko (Mersenne Twister implementation, adapted from $(HTTPS github.com/libmir/mir-random, mir-random))
93 Credits:   The entire random number library architecture is derived from the
94            excellent $(HTTP open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2461.pdf, C++0X)
95            random number facility proposed by Jens Maurer and contributed to by
96            researchers at the Fermi laboratory (excluding Xorshift).
97 */
98 /*
99          Copyright Andrei Alexandrescu 2008 - 2009.
100 Distributed under the Boost Software License, Version 1.0.
101    (See accompanying file LICENSE_1_0.txt or copy at
102          http://www.boost.org/LICENSE_1_0.txt)
103 */
104 module std.random;
105 
106 
107 import std.range.primitives;
108 import std.traits;
109 
110 ///
111 @safe unittest
112 {
113     import std.algorithm.comparison : among, equal;
114     import std.range : iota;
115 
116     // seed a random generator with a constant
117     auto rnd = Random(42);
118 
119     // Generate a uniformly-distributed integer in the range [0, 14]
120     // If no random generator is passed, the global `rndGen` would be used
121     auto i = uniform(0, 15, rnd);
122     assert(i >= 0 && i < 15);
123 
124     // Generate a uniformly-distributed real in the range [0, 100)
125     auto r = uniform(0.0L, 100.0L, rnd);
126     assert(r >= 0 && r < 100);
127 
128     // Sample from a custom type
129     enum Fruit { apple, mango, pear }
130     auto f = rnd.uniform!Fruit;
131     with(Fruit)
132     assert(f.among(apple, mango, pear));
133 
134     // Generate a 32-bit random number
135     auto u = uniform!uint(rnd);
136     static assert(is(typeof(u) == uint));
137 
138     // Generate a random number in the range in the range [0, 1)
139     auto u2 = uniform01(rnd);
140     assert(u2 >= 0 && u2 < 1);
141 
142     // Select an element randomly
143     auto el = 10.iota.choice(rnd);
144     assert(0 <= el && el < 10);
145 
146     // Throw a dice with custom proportions
147     // 0: 20%, 1: 10%, 2: 60%
148     auto val = rnd.dice(0.2, 0.1, 0.6);
149     assert(0 <= val && val <= 2);
150 
151     auto rnd2 = MinstdRand0(42);
152 
153     // Select a random subsample from a range
154     assert(10.iota.randomSample(3, rnd2).equal([7, 8, 9]));
155 
156     // Cover all elements in an array in random order
157     version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
158         assert(10.iota.randomCover(rnd2).equal([7, 4, 2, 0, 1, 6, 8, 3, 9, 5]));
159     else
160         assert(10.iota.randomCover(rnd2).equal([4, 8, 7, 3, 5, 9, 2, 6, 0, 1]));
161 
162     // Shuffle an array
163     version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
164         assert([0, 1, 2, 4, 5].randomShuffle(rnd2).equal([2, 0, 4, 5, 1]));
165     else
166         assert([0, 1, 2, 4, 5].randomShuffle(rnd2).equal([4, 2, 5, 0, 1]));
167 }
168 
169 version (OSX)
170     version = Darwin;
171 else version (iOS)
172     version = Darwin;
173 else version (TVOS)
174     version = Darwin;
175 else version (WatchOS)
176     version = Darwin;
177 
178 version (D_InlineAsm_X86) version = InlineAsm_X86_Any;
179 version (D_InlineAsm_X86_64) version = InlineAsm_X86_Any;
180 
181 version (StdUnittest)
182 {
183     static import std.meta;
184     package alias Xorshift64_64 = XorshiftEngine!(ulong, 64, -12, 25, -27);
185     package alias Xorshift128_64 = XorshiftEngine!(ulong, 128, 23, -18, -5);
186     package alias PseudoRngTypes = std.meta.AliasSeq!(MinstdRand0, MinstdRand, Mt19937, Xorshift32, Xorshift64,
187                                                       Xorshift96, Xorshift128, Xorshift160, Xorshift192,
188                                                       Xorshift64_64, Xorshift128_64);
189 }
190 
191 // Segments of the code in this file Copyright (c) 1997 by Rick Booth
192 // From "Inner Loops" by Rick Booth, Addison-Wesley
193 
194 // Work derived from:
195 
196 /*
197    A C-program for MT19937, with initialization improved 2002/1/26.
198    Coded by Takuji Nishimura and Makoto Matsumoto.
199 
200    Before using, initialize the state by using init_genrand(seed)
201    or init_by_array(init_key, key_length).
202 
203    Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
204    All rights reserved.
205 
206    Redistribution and use in source and binary forms, with or without
207    modification, are permitted provided that the following conditions
208    are met:
209 
210      1. Redistributions of source code must retain the above copyright
211         notice, this list of conditions and the following disclaimer.
212 
213      2. Redistributions in binary form must reproduce the above copyright
214         notice, this list of conditions and the following disclaimer in the
215         documentation and/or other materials provided with the distribution.
216 
217      3. The names of its contributors may not be used to endorse or promote
218         products derived from this software without specific prior written
219         permission.
220 
221    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
222    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
223    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
224    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
225    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
226    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
227    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
228    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
229    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
230    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
231    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
232 
233 
234    Any feedback is very welcome.
235    http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
236    email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
237 */
238 
239 /**
240  * Test if Rng is a random-number generator. The overload
241  * taking a ElementType also makes sure that the Rng generates
242  * values of that type.
243  *
244  * A random-number generator has at least the following features:
245  * $(UL
246  *   $(LI it's an InputRange)
247  *   $(LI it has a 'bool isUniformRandom' field readable in CTFE)
248  * )
249  */
250 template isUniformRNG(Rng, ElementType)
251 {
252     enum bool isUniformRNG = .isUniformRNG!Rng &&
253         is(std.range.primitives.ElementType!Rng == ElementType);
254 }
255 
256 /**
257  * ditto
258  */
259 template isUniformRNG(Rng)
260 {
261     enum bool isUniformRNG = isInputRange!Rng &&
262         is(typeof(
263         {
264             static assert(Rng.isUniformRandom); //tag
265         }));
266 }
267 
268 ///
269 @safe unittest
270 {
271     struct NoRng
272     {
273         @property uint front() {return 0;}
274         @property bool empty() {return false;}
275         void popFront() {}
276     }
277     static assert(!isUniformRNG!(NoRng));
278 
279     struct validRng
280     {
281         @property uint front() {return 0;}
282         @property bool empty() {return false;}
283         void popFront() {}
284 
285         enum isUniformRandom = true;
286     }
287     static assert(isUniformRNG!(validRng, uint));
288     static assert(isUniformRNG!(validRng));
289 }
290 
291 @safe unittest
292 {
293     // two-argument predicate should not require @property on `front`
294     // https://issues.dlang.org/show_bug.cgi?id=19837
295     struct Rng
296     {
297         float front() {return 0;}
298         void popFront() {}
299         enum empty = false;
300         enum isUniformRandom = true;
301     }
302     static assert(isUniformRNG!(Rng, float));
303 }
304 
305 /**
306  * Test if Rng is seedable. The overload
307  * taking a SeedType also makes sure that the Rng can be seeded with SeedType.
308  *
309  * A seedable random-number generator has the following additional features:
310  * $(UL
311  *   $(LI it has a 'seed(ElementType)' function)
312  * )
313  */
314 template isSeedable(Rng, SeedType)
315 {
316     enum bool isSeedable = isUniformRNG!(Rng) &&
317         is(typeof(
318         {
319             Rng r = void;              // can define a Rng object
320             SeedType s = void;
321             r.seed(s); // can seed a Rng
322         }));
323 }
324 
325 ///ditto
326 template isSeedable(Rng)
327 {
328     enum bool isSeedable = isUniformRNG!Rng &&
329         is(typeof(
330         {
331             Rng r = void;                     // can define a Rng object
332             alias SeedType = typeof(r.front);
333             SeedType s = void;
334             r.seed(s); // can seed a Rng
335         }));
336 }
337 
338 ///
339 @safe unittest
340 {
341     struct validRng
342     {
343         @property uint front() {return 0;}
344         @property bool empty() {return false;}
345         void popFront() {}
346 
347         enum isUniformRandom = true;
348     }
349     static assert(!isSeedable!(validRng, uint));
350     static assert(!isSeedable!(validRng));
351 
352     struct seedRng
353     {
354         @property uint front() {return 0;}
355         @property bool empty() {return false;}
356         void popFront() {}
357         void seed(uint val){}
358         enum isUniformRandom = true;
359     }
360     static assert(isSeedable!(seedRng, uint));
361     static assert(!isSeedable!(seedRng, ulong));
362     static assert(isSeedable!(seedRng));
363 }
364 
365 @safe @nogc pure nothrow unittest
366 {
367     struct NoRng
368     {
369         @property uint front() {return 0;}
370         @property bool empty() {return false;}
371         void popFront() {}
372     }
373     static assert(!isUniformRNG!(NoRng, uint));
374     static assert(!isUniformRNG!(NoRng));
375     static assert(!isSeedable!(NoRng, uint));
376     static assert(!isSeedable!(NoRng));
377 
378     struct NoRng2
379     {
380         @property uint front() {return 0;}
381         @property bool empty() {return false;}
382         void popFront() {}
383 
384         enum isUniformRandom = false;
385     }
386     static assert(!isUniformRNG!(NoRng2, uint));
387     static assert(!isUniformRNG!(NoRng2));
388     static assert(!isSeedable!(NoRng2, uint));
389     static assert(!isSeedable!(NoRng2));
390 
391     struct NoRng3
392     {
393         @property bool empty() {return false;}
394         void popFront() {}
395 
396         enum isUniformRandom = true;
397     }
398     static assert(!isUniformRNG!(NoRng3, uint));
399     static assert(!isUniformRNG!(NoRng3));
400     static assert(!isSeedable!(NoRng3, uint));
401     static assert(!isSeedable!(NoRng3));
402 
403     struct validRng
404     {
405         @property uint front() {return 0;}
406         @property bool empty() {return false;}
407         void popFront() {}
408 
409         enum isUniformRandom = true;
410     }
411     static assert(isUniformRNG!(validRng, uint));
412     static assert(isUniformRNG!(validRng));
413     static assert(!isSeedable!(validRng, uint));
414     static assert(!isSeedable!(validRng));
415 
416     struct seedRng
417     {
418         @property uint front() {return 0;}
419         @property bool empty() {return false;}
420         void popFront() {}
421         void seed(uint val){}
422         enum isUniformRandom = true;
423     }
424     static assert(isUniformRNG!(seedRng, uint));
425     static assert(isUniformRNG!(seedRng));
426     static assert(isSeedable!(seedRng, uint));
427     static assert(!isSeedable!(seedRng, ulong));
428     static assert(isSeedable!(seedRng));
429 }
430 
431 /**
432 Linear Congruential generator. When m = 0, no modulus is used.
433  */
434 struct LinearCongruentialEngine(UIntType, UIntType a, UIntType c, UIntType m)
435 if (isUnsigned!UIntType)
436 {
437     ///Mark this as a Rng
438     enum bool isUniformRandom = true;
439     /// Does this generator have a fixed range? ($(D_PARAM true)).
440     enum bool hasFixedRange = true;
441     /// Lowest generated value (`1` if $(D c == 0), `0` otherwise).
442     enum UIntType min = ( c == 0 ? 1 : 0 );
443     /// Highest generated value ($(D modulus - 1)).
444     enum UIntType max = m - 1;
445 /**
446 The parameters of this distribution. The random number is $(D_PARAM x
447 = (x * multipler + increment) % modulus).
448  */
449     enum UIntType multiplier = a;
450     ///ditto
451     enum UIntType increment = c;
452     ///ditto
453     enum UIntType modulus = m;
454 
455     static assert(isIntegral!(UIntType));
456     static assert(m == 0 || a < m);
457     static assert(m == 0 || c < m);
458     static assert(m == 0 ||
459             (cast(ulong) a * (m-1) + c) % m == (c < a ? c - a + m : c - a));
460 
461     // Check for maximum range
462     private static ulong gcd(ulong a, ulong b) @safe pure nothrow @nogc
463     {
464         while (b)
465         {
466             auto t = b;
467             b = a % b;
468             a = t;
469         }
470         return a;
471     }
472 
473     private static ulong primeFactorsOnly(ulong n) @safe pure nothrow @nogc
474     {
475         ulong result = 1;
476         ulong iter = 2;
477         for (; n >= iter * iter; iter += 2 - (iter == 2))
478         {
479             if (n % iter) continue;
480             result *= iter;
481             do
482             {
483                 n /= iter;
484             } while (n % iter == 0);
485         }
486         return result * n;
487     }
488 
489     @safe pure nothrow unittest
490     {
491         static assert(primeFactorsOnly(100) == 10);
492         //writeln(primeFactorsOnly(11));
493         static assert(primeFactorsOnly(11) == 11);
494         static assert(primeFactorsOnly(7 * 7 * 7 * 11 * 15 * 11) == 7 * 11 * 15);
495         static assert(primeFactorsOnly(129 * 2) == 129 * 2);
496         // enum x = primeFactorsOnly(7 * 7 * 7 * 11 * 15);
497         // static assert(x == 7 * 11 * 15);
498     }
499 
500     private static bool properLinearCongruentialParameters(ulong m,
501             ulong a, ulong c) @safe pure nothrow @nogc
502     {
503         if (m == 0)
504         {
505             static if (is(UIntType == uint))
506             {
507                 // Assume m is uint.max + 1
508                 m = (1uL << 32);
509             }
510             else
511             {
512                 return false;
513             }
514         }
515         // Bounds checking
516         if (a == 0 || a >= m || c >= m) return false;
517         // c and m are relatively prime
518         if (c > 0 && gcd(c, m) != 1) return false;
519         // a - 1 is divisible by all prime factors of m
520         if ((a - 1) % primeFactorsOnly(m)) return false;
521         // if a - 1 is multiple of 4, then m is a  multiple of 4 too.
522         if ((a - 1) % 4 == 0 && m % 4) return false;
523         // Passed all tests
524         return true;
525     }
526 
527     // check here
528     static assert(c == 0 || properLinearCongruentialParameters(m, a, c),
529             "Incorrect instantiation of LinearCongruentialEngine");
530 
531 /**
532 Constructs a $(D_PARAM LinearCongruentialEngine) generator seeded with
533 `x0`.
534  */
535     this(UIntType x0) @safe pure nothrow @nogc
536     {
537         seed(x0);
538     }
539 
540 /**
541    (Re)seeds the generator.
542 */
543     void seed(UIntType x0 = 1) @safe pure nothrow @nogc
544     {
545         _x = modulus ? (x0 % modulus) : x0;
546         static if (c == 0)
547         {
548             //Necessary to prevent generator from outputting an endless series of zeroes.
549             if (_x == 0)
550                 _x = max;
551         }
552         popFront();
553     }
554 
555 /**
556    Advances the random sequence.
557 */
558     void popFront() @safe pure nothrow @nogc
559     {
560         static if (m)
561         {
562             static if (is(UIntType == uint) && m == uint.max)
563             {
564                 immutable ulong
565                     x = (cast(ulong) a * _x + c),
566                     v = x >> 32,
567                     w = x & uint.max;
568                 immutable y = cast(uint)(v + w);
569                 _x = (y < v || y == uint.max) ? (y + 1) : y;
570             }
571             else static if (is(UIntType == uint) && m == int.max)
572             {
573                 immutable ulong
574                     x = (cast(ulong) a * _x + c),
575                     v = x >> 31,
576                     w = x & int.max;
577                 immutable uint y = cast(uint)(v + w);
578                 _x = (y >= int.max) ? (y - int.max) : y;
579             }
580             else
581             {
582                 _x = cast(UIntType) ((cast(ulong) a * _x + c) % m);
583             }
584         }
585         else
586         {
587             _x = a * _x + c;
588         }
589     }
590 
591 /**
592    Returns the current number in the random sequence.
593 */
594     @property UIntType front() const @safe pure nothrow @nogc
595     {
596         return _x;
597     }
598 
599 ///
600     @property typeof(this) save() const @safe pure nothrow @nogc
601     {
602         return this;
603     }
604 
605 /**
606 Always `false` (random generators are infinite ranges).
607  */
608     enum bool empty = false;
609 
610     // https://issues.dlang.org/show_bug.cgi?id=21610
611     static if (m)
612     {
613         private UIntType _x = (a + c) % m;
614     }
615     else
616     {
617         private UIntType _x = a + c;
618     }
619 }
620 
621 /// Declare your own linear congruential engine
622 @safe unittest
623 {
624     alias CPP11LCG = LinearCongruentialEngine!(uint, 48271, 0, 2_147_483_647);
625 
626     // seed with a constant
627     auto rnd = CPP11LCG(42);
628     auto n = rnd.front; // same for each run
629     assert(n == 2027382);
630 }
631 
632 /// Declare your own linear congruential engine
633 @safe unittest
634 {
635     // glibc's LCG
636     alias GLibcLCG = LinearCongruentialEngine!(uint, 1103515245, 12345, 2_147_483_648);
637 
638     // Seed with an unpredictable value
639     auto rnd = GLibcLCG(unpredictableSeed);
640     auto n = rnd.front; // different across runs
641 }
642 
643 /// Declare your own linear congruential engine
644 @safe unittest
645 {
646     // Visual C++'s LCG
647     alias MSVCLCG = LinearCongruentialEngine!(uint, 214013, 2531011, 0);
648 
649     // seed with a constant
650     auto rnd = MSVCLCG(1);
651     auto n = rnd.front; // same for each run
652     assert(n == 2745024);
653 }
654 
655 // Ensure that unseeded LCGs produce correct values
656 @safe unittest
657 {
658     alias LGE = LinearCongruentialEngine!(uint, 10000, 19682, 19683);
659 
660     LGE rnd;
661     assert(rnd.front == 9999);
662 }
663 
664 /**
665 Define $(D_PARAM LinearCongruentialEngine) generators with well-chosen
666 parameters. `MinstdRand0` implements Park and Miller's "minimal
667 standard" $(HTTP
668 wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator,
669 generator) that uses 16807 for the multiplier. `MinstdRand`
670 implements a variant that has slightly better spectral behavior by
671 using the multiplier 48271. Both generators are rather simplistic.
672  */
673 alias MinstdRand0 = LinearCongruentialEngine!(uint, 16_807, 0, 2_147_483_647);
674 /// ditto
675 alias MinstdRand = LinearCongruentialEngine!(uint, 48_271, 0, 2_147_483_647);
676 
677 ///
678 @safe @nogc unittest
679 {
680     // seed with a constant
681     auto rnd0 = MinstdRand0(1);
682     auto n = rnd0.front;
683      // same for each run
684     assert(n == 16807);
685 
686     // Seed with an unpredictable value
687     rnd0.seed(unpredictableSeed);
688     n = rnd0.front; // different across runs
689 }
690 
691 @safe @nogc unittest
692 {
693     import std.range;
694     static assert(isForwardRange!MinstdRand);
695     static assert(isUniformRNG!MinstdRand);
696     static assert(isUniformRNG!MinstdRand0);
697     static assert(isUniformRNG!(MinstdRand, uint));
698     static assert(isUniformRNG!(MinstdRand0, uint));
699     static assert(isSeedable!MinstdRand);
700     static assert(isSeedable!MinstdRand0);
701     static assert(isSeedable!(MinstdRand, uint));
702     static assert(isSeedable!(MinstdRand0, uint));
703 
704     // The correct numbers are taken from The Database of Integer Sequences
705     // http://www.research.att.com/~njas/sequences/eisBTfry00128.txt
706     enum ulong[20] checking0 = [
707         16807UL,282475249,1622650073,984943658,1144108930,470211272,
708         101027544,1457850878,1458777923,2007237709,823564440,1115438165,
709         1784484492,74243042,114807987,1137522503,1441282327,16531729,
710         823378840,143542612 ];
711     //auto rnd0 = MinstdRand0(1);
712     MinstdRand0 rnd0;
713 
714     foreach (e; checking0)
715     {
716         assert(rnd0.front == e);
717         rnd0.popFront();
718     }
719     // Test the 10000th invocation
720     // Correct value taken from:
721     // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2461.pdf
722     rnd0.seed();
723     popFrontN(rnd0, 9999);
724     assert(rnd0.front == 1043618065);
725 
726     // Test MinstdRand
727     enum ulong[6] checking = [48271UL,182605794,1291394886,1914720637,2078669041,
728                      407355683];
729     //auto rnd = MinstdRand(1);
730     MinstdRand rnd;
731     foreach (e; checking)
732     {
733         assert(rnd.front == e);
734         rnd.popFront();
735     }
736 
737     // Test the 10000th invocation
738     // Correct value taken from:
739     // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2461.pdf
740     rnd.seed();
741     popFrontN(rnd, 9999);
742     assert(rnd.front == 399268537);
743 
744     // Check .save works
745     static foreach (Type; std.meta.AliasSeq!(MinstdRand0, MinstdRand))
746     {{
747         auto rnd1 = Type(123_456_789);
748         rnd1.popFront();
749         // https://issues.dlang.org/show_bug.cgi?id=15853
750         auto rnd2 = ((const ref Type a) => a.save())(rnd1);
751         assert(rnd1 == rnd2);
752         // Enable next test when RNGs are reference types
753         version (none) { assert(rnd1 !is rnd2); }
754         for (auto i = 0; i < 3; i++, rnd1.popFront, rnd2.popFront)
755             assert(rnd1.front() == rnd2.front());
756     }}
757 }
758 
759 @safe @nogc unittest
760 {
761     auto rnd0 = MinstdRand0(MinstdRand0.modulus);
762     auto n = rnd0.front;
763     rnd0.popFront();
764     assert(n != rnd0.front);
765 }
766 
767 /**
768 The $(LINK2 https://en.wikipedia.org/wiki/Mersenne_Twister, Mersenne Twister) generator.
769  */
770 struct MersenneTwisterEngine(UIntType, size_t w, size_t n, size_t m, size_t r,
771                              UIntType a, size_t u, UIntType d, size_t s,
772                              UIntType b, size_t t,
773                              UIntType c, size_t l, UIntType f)
774 if (isUnsigned!UIntType)
775 {
776     static assert(0 < w && w <= UIntType.sizeof * 8);
777     static assert(1 <= m && m <= n);
778     static assert(0 <= r && 0 <= u && 0 <= s && 0 <= t && 0 <= l);
779     static assert(r <= w && u <= w && s <= w && t <= w && l <= w);
780     static assert(0 <= a && 0 <= b && 0 <= c);
781     static assert(n <= ptrdiff_t.max);
782 
783     ///Mark this as a Rng
784     enum bool isUniformRandom = true;
785 
786 /**
787 Parameters for the generator.
788 */
789     enum size_t   wordSize   = w;
790     enum size_t   stateSize  = n; /// ditto
791     enum size_t   shiftSize  = m; /// ditto
792     enum size_t   maskBits   = r; /// ditto
793     enum UIntType xorMask    = a; /// ditto
794     enum size_t   temperingU = u; /// ditto
795     enum UIntType temperingD = d; /// ditto
796     enum size_t   temperingS = s; /// ditto
797     enum UIntType temperingB = b; /// ditto
798     enum size_t   temperingT = t; /// ditto
799     enum UIntType temperingC = c; /// ditto
800     enum size_t   temperingL = l; /// ditto
801     enum UIntType initializationMultiplier = f; /// ditto
802 
803     /// Smallest generated value (0).
804     enum UIntType min = 0;
805     /// Largest generated value.
806     enum UIntType max = UIntType.max >> (UIntType.sizeof * 8u - w);
807     // note, `max` also serves as a bitmask for the lowest `w` bits
808     static assert(a <= max && b <= max && c <= max && f <= max);
809 
810     /// The default seed value.
811     enum UIntType defaultSeed = 5489u;
812 
813     // Bitmasks used in the 'twist' part of the algorithm
814     private enum UIntType lowerMask = (cast(UIntType) 1u << r) - 1,
815                           upperMask = (~lowerMask) & max;
816 
817     /*
818        Collection of all state variables
819        used by the generator
820     */
821     private struct State
822     {
823         /*
824            State array of the generator.  This
825            is iterated through backwards (from
826            last element to first), providing a
827            few extra compiler optimizations by
828            comparison to the forward iteration
829            used in most implementations.
830         */
831         UIntType[n] data;
832 
833         /*
834            Cached copy of most recently updated
835            element of `data` state array, ready
836            to be tempered to generate next
837            `front` value
838         */
839         UIntType z;
840 
841         /*
842            Most recently generated random variate
843         */
844         UIntType front;
845 
846         /*
847            Index of the entry in the `data`
848            state array that will be twisted
849            in the next `popFront()` call
850         */
851         size_t index;
852     }
853 
854     /*
855        State variables used by the generator;
856        initialized to values equivalent to
857        explicitly seeding the generator with
858        `defaultSeed`
859     */
860     private State state = defaultState();
861     /* NOTE: the above is a workaround to ensure
862        backwards compatibility with the original
863        implementation, which permitted implicit
864        construction.  With `@disable this();`
865        it would not be necessary. */
866 
867 /**
868    Constructs a MersenneTwisterEngine object.
869 */
870     this(UIntType value) @safe pure nothrow @nogc
871     {
872         seed(value);
873     }
874 
875     /**
876        Generates the default initial state for a Mersenne
877        Twister; equivalent to the internal state obtained
878        by calling `seed(defaultSeed)`
879     */
880     private static State defaultState() @safe pure nothrow @nogc
881     {
882         if (!__ctfe) assert(false);
883         State mtState;
884         seedImpl(defaultSeed, mtState);
885         return mtState;
886     }
887 
888 /**
889    Seeds a MersenneTwisterEngine object.
890    Note:
891    This seed function gives 2^w starting points (the lowest w bits of
892    the value provided will be used). To allow the RNG to be started
893    in any one of its internal states use the seed overload taking an
894    InputRange.
895 */
896     void seed()(UIntType value = defaultSeed) @safe pure nothrow @nogc
897     {
898         this.seedImpl(value, this.state);
899     }
900 
901     /**
902        Implementation of the seeding mechanism, which
903        can be used with an arbitrary `State` instance
904     */
905     private static void seedImpl(UIntType value, ref State mtState) @nogc
906     {
907         mtState.data[$ - 1] = value;
908         static if (max != UIntType.max)
909         {
910             mtState.data[$ - 1] &= max;
911         }
912 
913         foreach_reverse (size_t i, ref e; mtState.data[0 .. $ - 1])
914         {
915             e = f * (mtState.data[i + 1] ^ (mtState.data[i + 1] >> (w - 2))) + cast(UIntType)(n - (i + 1));
916             static if (max != UIntType.max)
917             {
918                 e &= max;
919             }
920         }
921 
922         mtState.index = n - 1;
923 
924         /* double popFront() to guarantee both `mtState.z`
925            and `mtState.front` are derived from the newly
926            set values in `mtState.data` */
927         MersenneTwisterEngine.popFrontImpl(mtState);
928         MersenneTwisterEngine.popFrontImpl(mtState);
929     }
930 
931 /**
932    Seeds a MersenneTwisterEngine object using an InputRange.
933 
934    Throws:
935    `Exception` if the InputRange didn't provide enough elements to seed the generator.
936    The number of elements required is the 'n' template parameter of the MersenneTwisterEngine struct.
937  */
938     void seed(T)(T range)
939     if (isInputRange!T && is(immutable ElementType!T == immutable UIntType))
940     {
941         this.seedImpl(range, this.state);
942     }
943 
944     /**
945        Implementation of the range-based seeding mechanism,
946        which can be used with an arbitrary `State` instance
947     */
948     private static void seedImpl(T)(T range, ref State mtState)
949     if (isInputRange!T && is(immutable ElementType!T == immutable UIntType))
950     {
951         size_t j;
952         for (j = 0; j < n && !range.empty; ++j, range.popFront())
953         {
954             ptrdiff_t idx = n - j - 1;
955             mtState.data[idx] = range.front;
956         }
957 
958         mtState.index = n - 1;
959 
960         if (range.empty && j < n)
961         {
962             import core.internal.string : UnsignedStringBuf, unsignedToTempString;
963 
964             UnsignedStringBuf buf = void;
965             string s = "MersenneTwisterEngine.seed: Input range didn't provide enough elements: Need ";
966             s ~= unsignedToTempString(n, buf) ~ " elements.";
967             throw new Exception(s);
968         }
969 
970         /* double popFront() to guarantee both `mtState.z`
971            and `mtState.front` are derived from the newly
972            set values in `mtState.data` */
973         MersenneTwisterEngine.popFrontImpl(mtState);
974         MersenneTwisterEngine.popFrontImpl(mtState);
975     }
976 
977 /**
978    Advances the generator.
979 */
980     void popFront() @safe pure nothrow @nogc
981     {
982         this.popFrontImpl(this.state);
983     }
984 
985     /*
986        Internal implementation of `popFront()`, which
987        can be used with an arbitrary `State` instance
988     */
989     private static void popFrontImpl(ref State mtState) @nogc
990     {
991         /* This function blends two nominally independent
992            processes: (i) calculation of the next random
993            variate `mtState.front` from the cached previous
994            `data` entry `z`, and (ii) updating the value
995            of `data[index]` and `mtState.z` and advancing
996            the `index` value to the next in sequence.
997 
998            By interweaving the steps involved in these
999            procedures, rather than performing each of
1000            them separately in sequence, the variables
1001            are kept 'hot' in CPU registers, allowing
1002            for significantly faster performance. */
1003         ptrdiff_t index = mtState.index;
1004         ptrdiff_t next = index - 1;
1005         if (next < 0)
1006             next = n - 1;
1007         auto z = mtState.z;
1008         ptrdiff_t conj = index - m;
1009         if (conj < 0)
1010             conj = index - m + n;
1011 
1012         static if (d == UIntType.max)
1013         {
1014             z ^= (z >> u);
1015         }
1016         else
1017         {
1018             z ^= (z >> u) & d;
1019         }
1020 
1021         auto q = mtState.data[index] & upperMask;
1022         auto p = mtState.data[next] & lowerMask;
1023         z ^= (z << s) & b;
1024         auto y = q | p;
1025         auto x = y >> 1;
1026         z ^= (z << t) & c;
1027         if (y & 1)
1028             x ^= a;
1029         auto e = mtState.data[conj] ^ x;
1030         z ^= (z >> l);
1031         mtState.z = mtState.data[index] = e;
1032         mtState.index = next;
1033 
1034         /* technically we should take the lowest `w`
1035            bits here, but if the tempering bitmasks
1036            `b` and `c` are set correctly, this should
1037            be unnecessary */
1038         mtState.front = z;
1039     }
1040 
1041 /**
1042    Returns the current random value.
1043  */
1044     @property UIntType front() @safe const pure nothrow @nogc
1045     {
1046         return this.state.front;
1047     }
1048 
1049 ///
1050     @property typeof(this) save() @safe const pure nothrow @nogc
1051     {
1052         return this;
1053     }
1054 
1055 /**
1056 Always `false`.
1057  */
1058     enum bool empty = false;
1059 }
1060 
1061 ///
1062 @safe unittest
1063 {
1064     // seed with a constant
1065     Mt19937 gen;
1066     auto n = gen.front; // same for each run
1067     assert(n == 3499211612);
1068 
1069     // Seed with an unpredictable value
1070     gen.seed(unpredictableSeed);
1071     n = gen.front; // different across runs
1072 }
1073 
1074 /**
1075 A `MersenneTwisterEngine` instantiated with the parameters of the
1076 original engine $(HTTP math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html,
1077 MT19937), generating uniformly-distributed 32-bit numbers with a
1078 period of 2 to the power of 19937. Recommended for random number
1079 generation unless memory is severely restricted, in which case a $(LREF
1080 LinearCongruentialEngine) would be the generator of choice.
1081  */
1082 alias Mt19937 = MersenneTwisterEngine!(uint, 32, 624, 397, 31,
1083                                        0x9908b0df, 11, 0xffffffff, 7,
1084                                        0x9d2c5680, 15,
1085                                        0xefc60000, 18, 1_812_433_253);
1086 
1087 ///
1088 @safe @nogc unittest
1089 {
1090     // seed with a constant
1091     Mt19937 gen;
1092     auto n = gen.front; // same for each run
1093     assert(n == 3499211612);
1094 
1095     // Seed with an unpredictable value
1096     gen.seed(unpredictableSeed);
1097     n = gen.front; // different across runs
1098 }
1099 
1100 @safe nothrow unittest
1101 {
1102     import std.algorithm;
1103     import std.range;
1104     static assert(isUniformRNG!Mt19937);
1105     static assert(isUniformRNG!(Mt19937, uint));
1106     static assert(isSeedable!Mt19937);
1107     static assert(isSeedable!(Mt19937, uint));
1108     static assert(isSeedable!(Mt19937, typeof(map!((a) => unpredictableSeed)(repeat(0)))));
1109     Mt19937 gen;
1110     assert(gen.front == 3499211612);
1111     popFrontN(gen, 9999);
1112     assert(gen.front == 4123659995);
1113     try { gen.seed(iota(624u)); } catch (Exception) { assert(false); }
1114     assert(gen.front == 3708921088u);
1115     popFrontN(gen, 9999);
1116     assert(gen.front == 165737292u);
1117 }
1118 
1119 /**
1120 A `MersenneTwisterEngine` instantiated with the parameters of the
1121 original engine $(HTTP en.wikipedia.org/wiki/Mersenne_Twister,
1122 MT19937-64), generating uniformly-distributed 64-bit numbers with a
1123 period of 2 to the power of 19937.
1124 */
1125 alias Mt19937_64 = MersenneTwisterEngine!(ulong, 64, 312, 156, 31,
1126                                           0xb5026f5aa96619e9, 29, 0x5555555555555555, 17,
1127                                           0x71d67fffeda60000, 37,
1128                                           0xfff7eee000000000, 43, 6_364_136_223_846_793_005);
1129 
1130 ///
1131 @safe @nogc unittest
1132 {
1133     // Seed with a constant
1134     auto gen = Mt19937_64(12345);
1135     auto n = gen.front; // same for each run
1136     assert(n == 6597103971274460346);
1137 
1138     // Seed with an unpredictable value
1139     gen.seed(unpredictableSeed!ulong);
1140     n = gen.front; // different across runs
1141 }
1142 
1143 @safe nothrow unittest
1144 {
1145     import std.algorithm;
1146     import std.range;
1147     static assert(isUniformRNG!Mt19937_64);
1148     static assert(isUniformRNG!(Mt19937_64, ulong));
1149     static assert(isSeedable!Mt19937_64);
1150     static assert(isSeedable!(Mt19937_64, ulong));
1151     static assert(isSeedable!(Mt19937_64, typeof(map!((a) => unpredictableSeed!ulong)(repeat(0)))));
1152     Mt19937_64 gen;
1153     assert(gen.front == 14514284786278117030uL);
1154     popFrontN(gen, 9999);
1155     assert(gen.front == 9981545732273789042uL);
1156     try { gen.seed(iota(312uL)); } catch (Exception) { assert(false); }
1157     assert(gen.front == 14660652410669508483uL);
1158     popFrontN(gen, 9999);
1159     assert(gen.front == 15956361063660440239uL);
1160 }
1161 
1162 @safe unittest
1163 {
1164     import std.algorithm;
1165     import std.exception;
1166     import std.range;
1167 
1168     Mt19937 gen;
1169 
1170     assertThrown(gen.seed(map!((a) => 123_456_789U)(repeat(0, 623))));
1171 
1172     gen.seed(123_456_789U.repeat(624));
1173     //infinite Range
1174     gen.seed(123_456_789U.repeat);
1175 }
1176 
1177 @safe @nogc pure nothrow unittest
1178 {
1179     uint a, b;
1180     {
1181         Mt19937 gen;
1182         a = gen.front;
1183     }
1184     {
1185         Mt19937 gen;
1186         gen.popFront();
1187         //popFrontN(gen, 1);  // skip 1 element
1188         b = gen.front;
1189     }
1190     assert(a != b);
1191 }
1192 
1193 @safe @nogc unittest
1194 {
1195     // Check .save works
1196     static foreach (Type; std.meta.AliasSeq!(Mt19937, Mt19937_64))
1197     {{
1198         auto gen1 = Type(123_456_789);
1199         gen1.popFront();
1200         // https://issues.dlang.org/show_bug.cgi?id=15853
1201         auto gen2 = ((const ref Type a) => a.save())(gen1);
1202         assert(gen1 == gen2);  // Danger, Will Robinson -- no opEquals for MT
1203         // Enable next test when RNGs are reference types
1204         version (none) { assert(gen1 !is gen2); }
1205         for (auto i = 0; i < 100; i++, gen1.popFront, gen2.popFront)
1206             assert(gen1.front() == gen2.front());
1207     }}
1208 }
1209 
1210 // https://issues.dlang.org/show_bug.cgi?id=11690
1211 @safe @nogc pure nothrow unittest
1212 {
1213     alias MT(UIntType, uint w) = MersenneTwisterEngine!(UIntType, w, 624, 397, 31,
1214                                                         0x9908b0df, 11, 0xffffffff, 7,
1215                                                         0x9d2c5680, 15,
1216                                                         0xefc60000, 18, 1812433253);
1217 
1218     static immutable ulong[] expectedFirstValue = [3499211612uL, 3499211612uL,
1219                                   171143175841277uL, 1145028863177033374uL];
1220 
1221     static immutable ulong[] expected10kValue = [4123659995uL, 4123659995uL,
1222                                 51991688252792uL, 3031481165133029945uL];
1223 
1224     static foreach (i, R; std.meta.AliasSeq!(MT!(uint, 32), MT!(ulong, 32), MT!(ulong, 48), MT!(ulong, 64)))
1225     {{
1226         auto a = R();
1227         a.seed(a.defaultSeed); // checks that some alternative paths in `seed` are utilized
1228         assert(a.front == expectedFirstValue[i]);
1229         a.popFrontN(9999);
1230         assert(a.front == expected10kValue[i]);
1231     }}
1232 }
1233 
1234 /++
1235 Xorshift generator.
1236 Implemented according to $(HTTP www.jstatsoft.org/v08/i14/paper, Xorshift RNGs)
1237 (Marsaglia, 2003) when the size is small. For larger sizes the generator
1238 uses Sebastino Vigna's optimization of using an index to avoid needing
1239 to rotate the internal array.
1240 
1241 Period is `2 ^^ nbits - 1` except for a legacy 192-bit uint version (see
1242 note below).
1243 
1244 Params:
1245     UIntType = Word size of this xorshift generator and the return type
1246                of `opCall`.
1247     nbits = The number of bits of state of this generator. This must be
1248            a positive multiple of the size in bits of UIntType. If
1249            nbits is large this struct may occupy slightly more memory
1250            than this so it can use a circular counter instead of
1251            shifting the entire array.
1252     sa = The direction and magnitude of the 1st shift. Positive
1253          means left, negative means right.
1254     sb = The direction and magnitude of the 2nd shift. Positive
1255          means left, negative means right.
1256     sc = The direction and magnitude of the 3rd shift. Positive
1257          means left, negative means right.
1258 
1259 Note:
1260 For historical compatibility when `nbits == 192` and `UIntType` is `uint`
1261 a legacy hybrid PRNG is used consisting of a 160-bit xorshift combined
1262 with a 32-bit counter. This combined generator has period equal to the
1263 least common multiple of `2^^160 - 1` and `2^^32`.
1264 
1265 Previous versions of `XorshiftEngine` did not provide any mechanism to specify
1266 the directions of the shifts, taking each shift as an unsigned magnitude.
1267 For backwards compatibility, because three shifts in the same direction
1268 cannot result in a full-period XorshiftEngine, when all three of `sa`, `sb`,
1269 `sc, are positive `XorshiftEngine` treats them as unsigned magnitudes and
1270 uses shift directions to match the old behavior of `XorshiftEngine`.
1271 
1272 Not every set of shifts results in a full-period xorshift generator.
1273 The template does not currently at compile-time perform a full check
1274 for maximum period but in a future version might reject parameters
1275 resulting in shorter periods.
1276 +/
1277 struct XorshiftEngine(UIntType, uint nbits, int sa, int sb, int sc)
1278 if (isUnsigned!UIntType && !(sa > 0 && sb > 0 && sc > 0))
1279 {
1280     static assert(nbits > 0 && nbits % (UIntType.sizeof * 8) == 0,
1281         "nbits must be an even multiple of "~UIntType.stringof
1282         ~".sizeof * 8, not "~nbits.stringof~".");
1283 
1284     static assert(!((sa >= 0) == (sb >= 0) && (sa >= 0) == (sc >= 0))
1285         && (sa * sb * sc != 0),
1286         "shifts cannot be zero and cannot all be in same direction: cannot be ["
1287         ~sa.stringof~", "~sb.stringof~", "~sc.stringof~"].");
1288 
1289     static assert(sa != sb && sb != sc,
1290         "consecutive shifts with the same magnitude and direction would partially or completely cancel!");
1291 
1292     static assert(UIntType.sizeof == uint.sizeof || UIntType.sizeof == ulong.sizeof,
1293         "XorshiftEngine currently does not support type " ~ UIntType.sizeof
1294         ~ " because it does not have a `seed` implementation for arrays "
1295         ~ " of element types other than uint and ulong.");
1296 
1297   public:
1298     ///Mark this as a Rng
1299     enum bool isUniformRandom = true;
1300     /// Always `false` (random generators are infinite ranges).
1301     enum empty = false;
1302     /// Smallest generated value.
1303     enum UIntType min = _state.length == 1 ? 1 : 0;
1304     /// Largest generated value.
1305     enum UIntType max = UIntType.max;
1306 
1307 
1308   private:
1309     // Legacy 192 bit uint hybrid counter/xorshift.
1310     enum bool isLegacy192Bit = UIntType.sizeof == uint.sizeof && nbits == 192;
1311 
1312     // Shift magnitudes.
1313     enum a = (sa < 0 ? -sa : sa);
1314     enum b = (sb < 0 ? -sb : sb);
1315     enum c = (sc < 0 ? -sc : sc);
1316 
1317     // Shift expressions to mix in.
1318     enum shiftA(string expr) = `((`~expr~`) `~(sa > 0 ? `<< a)` : ` >>> a)`);
1319     enum shiftB(string expr) = `((`~expr~`) `~(sb > 0 ? `<< b)` : ` >>> b)`);
1320     enum shiftC(string expr) = `((`~expr~`) `~(sc > 0 ? `<< c)` : ` >>> c)`);
1321 
1322     enum N = nbits / (UIntType.sizeof * 8);
1323 
1324     // For N <= 2 it is strictly worse to use an index.
1325     // Informal third-party benchmarks suggest that for `ulong` it is
1326     // faster to use an index when N == 4. For `uint` we err on the side
1327     // of not increasing the struct's size and only switch to the other
1328     // implementation when N > 4.
1329     enum useIndex = !isLegacy192Bit && (UIntType.sizeof >= ulong.sizeof ? N > 3 : N > 4);
1330     static if (useIndex)
1331     {
1332         enum initialIndex = N - 1;
1333         uint _index = initialIndex;
1334     }
1335 
1336     static if (N == 1 && UIntType.sizeof <= uint.sizeof)
1337     {
1338         UIntType[N] _state = [cast(UIntType) 2_463_534_242];
1339     }
1340     else static if (isLegacy192Bit)
1341     {
1342         UIntType[N] _state = [123_456_789, 362_436_069, 521_288_629, 88_675_123, 5_783_321, 6_615_241];
1343         UIntType       value_;
1344     }
1345     else static if (N <= 5 && UIntType.sizeof <= uint.sizeof)
1346     {
1347         UIntType[N] _state = [
1348             cast(UIntType) 123_456_789,
1349             cast(UIntType) 362_436_069,
1350             cast(UIntType) 521_288_629,
1351             cast(UIntType)  88_675_123,
1352             cast(UIntType)   5_783_321][0 .. N];
1353     }
1354     else
1355     {
1356         UIntType[N] _state = ()
1357         {
1358             static if (UIntType.sizeof < ulong.sizeof)
1359             {
1360                 uint x0 = 123_456_789;
1361                 enum uint m = 1_812_433_253U;
1362             }
1363             else static if (UIntType.sizeof <= ulong.sizeof)
1364             {
1365                 ulong x0 = 123_456_789;
1366                 enum ulong m = 6_364_136_223_846_793_005UL;
1367             }
1368             else
1369             {
1370                 static assert(0, "Phobos Error: Xorshift has no instantiation rule for "
1371                     ~ UIntType.stringof);
1372             }
1373             enum uint rshift = typeof(x0).sizeof * 8 - 2;
1374             UIntType[N] result = void;
1375             foreach (i, ref e; result)
1376             {
1377                 e = cast(UIntType) (x0 = (m * (x0 ^ (x0 >>> rshift)) + i + 1));
1378                 if (e == 0)
1379                     e = cast(UIntType) (i + 1);
1380             }
1381             return result;
1382         }();
1383     }
1384 
1385 
1386   public:
1387     /++
1388     Constructs a `XorshiftEngine` generator seeded with $(D_PARAM x0).
1389 
1390     Params:
1391         x0 = value used to deterministically initialize internal state
1392     +/
1393     this()(UIntType x0) @safe pure nothrow @nogc
1394     {
1395         seed(x0);
1396     }
1397 
1398 
1399     /++
1400     (Re)seeds the generator.
1401 
1402     Params:
1403         x0 = value used to deterministically initialize internal state
1404     +/
1405     void seed()(UIntType x0) @safe pure nothrow @nogc
1406     {
1407         static if (useIndex)
1408             _index = initialIndex;
1409 
1410         static if (UIntType.sizeof == uint.sizeof)
1411         {
1412             // Initialization routine from MersenneTwisterEngine.
1413             foreach (uint i, ref e; _state)
1414             {
1415                 e = (x0 = (1_812_433_253U * (x0 ^ (x0 >> 30)) + i + 1));
1416                 // Xorshift requires merely that not every word of the internal
1417                 // array is 0. For historical compatibility the 32-bit word version
1418                 // has the stronger requirement that not any word of the state
1419                 // array is 0 after initial seeding.
1420                 if (e == 0)
1421                     e = (i + 1);
1422             }
1423         }
1424         else static if (UIntType.sizeof == ulong.sizeof)
1425         {
1426             static if (N > 1)
1427             {
1428                 // Initialize array using splitmix64 as recommended by Sebastino Vigna.
1429                 // By construction the array will not be all zeroes.
1430                 // http://xoroshiro.di.unimi.it/splitmix64.c
1431                 foreach (ref e; _state)
1432                 {
1433                     ulong z = (x0 += 0x9e37_79b9_7f4a_7c15UL);
1434                     z = (z ^ (z >>> 30)) * 0xbf58_476d_1ce4_e5b9UL;
1435                     z = (z ^ (z >>> 27)) * 0x94d0_49bb_1331_11ebUL;
1436                     e = z ^ (z >>> 31);
1437                 }
1438             }
1439             else
1440             {
1441                 // Apply a transformation when N == 1 instead of just copying x0
1442                 // directly because it's not unlikely that a user might initialize
1443                 // a PRNG with small counting numbers (e.g. 1, 2, 3) that have the
1444                 // statistically rare property of having only 1 or 2 non-zero bits.
1445                 // Additionally we need to ensure that the internal state is not
1446                 // entirely zero.
1447                 if (x0 != 0)
1448                     _state[0] = x0 * 6_364_136_223_846_793_005UL;
1449                 else
1450                     _state[0] = typeof(this).init._state[0];
1451             }
1452         }
1453         else
1454         {
1455             static assert(0, "Phobos Error: Xorshift has no `seed` implementation for "
1456                 ~ UIntType.stringof);
1457         }
1458 
1459         popFront();
1460     }
1461 
1462 
1463     /**
1464      * Returns the current number in the random sequence.
1465      */
1466     @property
1467     UIntType front() const @safe pure nothrow @nogc
1468     {
1469         static if (isLegacy192Bit)
1470             return value_;
1471         else static if (!useIndex)
1472             return _state[N-1];
1473         else
1474             return _state[_index];
1475     }
1476 
1477 
1478     /**
1479      * Advances the random sequence.
1480      */
1481     void popFront() @safe pure nothrow @nogc
1482     {
1483         alias s = _state;
1484         static if (isLegacy192Bit)
1485         {
1486             auto x = _state[0] ^ mixin(shiftA!`s[0]`);
1487             static foreach (i; 0 .. N-2)
1488                 s[i] = s[i + 1];
1489             s[N-2] = s[N-2] ^ mixin(shiftC!`s[N-2]`) ^ x ^ mixin(shiftB!`x`);
1490             value_ = s[N-2] + (s[N-1] += 362_437);
1491         }
1492         else static if (N == 1)
1493         {
1494             s[0] ^= mixin(shiftA!`s[0]`);
1495             s[0] ^= mixin(shiftB!`s[0]`);
1496             s[0] ^= mixin(shiftC!`s[0]`);
1497         }
1498         else static if (!useIndex)
1499         {
1500             auto x = s[0] ^ mixin(shiftA!`s[0]`);
1501             static foreach (i; 0 .. N-1)
1502                 s[i] = s[i + 1];
1503             s[N-1] = s[N-1] ^ mixin(shiftC!`s[N-1]`) ^ x ^ mixin(shiftB!`x`);
1504         }
1505         else
1506         {
1507             assert(_index < N); // Invariant.
1508             const sIndexMinus1 = s[_index];
1509             static if ((N & (N - 1)) == 0)
1510                 _index = (_index + 1) & typeof(_index)(N - 1);
1511             else
1512             {
1513                 if (++_index >= N)
1514                     _index = 0;
1515             }
1516             auto x = s[_index];
1517             x ^= mixin(shiftA!`x`);
1518             s[_index] = sIndexMinus1 ^ mixin(shiftC!`sIndexMinus1`) ^ x ^ mixin(shiftB!`x`);
1519         }
1520     }
1521 
1522 
1523     /**
1524      * Captures a range state.
1525      */
1526     @property
1527     typeof(this) save() const @safe pure nothrow @nogc
1528     {
1529         return this;
1530     }
1531 
1532 private:
1533     // Workaround for a DScanner bug. If we remove this `private:` DScanner
1534     // gives erroneous warnings about missing documentation for public symbols
1535     // later in the module.
1536 }
1537 
1538 /// ditto
1539 template XorshiftEngine(UIntType, int bits, int a, int b, int c)
1540 if (isUnsigned!UIntType && a > 0 && b > 0 && c > 0)
1541 {
1542     // Compatibility with old parameterizations without explicit shift directions.
1543     static if (bits == UIntType.sizeof * 8)
1544         alias XorshiftEngine = .XorshiftEngine!(UIntType, bits, a, -b, c);//left, right, left
1545     else static if (bits == 192 && UIntType.sizeof == uint.sizeof)
1546         alias XorshiftEngine = .XorshiftEngine!(UIntType, bits, -a, b, c);//right, left, left
1547     else
1548         alias XorshiftEngine = .XorshiftEngine!(UIntType, bits, a, -b, -c);//left, right, right
1549 }
1550 
1551 ///
1552 @safe unittest
1553 {
1554     alias Xorshift96  = XorshiftEngine!(uint, 96,  10, 5,  26);
1555     auto rnd = Xorshift96(42);
1556     auto num = rnd.front;  // same for each run
1557     assert(num == 2704588748);
1558 }
1559 
1560 
1561 /**
1562  * Define `XorshiftEngine` generators with well-chosen parameters. See each bits examples of "Xorshift RNGs".
1563  * `Xorshift` is a Xorshift128's alias because 128bits implementation is mostly used.
1564  */
1565 alias Xorshift32  = XorshiftEngine!(uint, 32,  13, 17, 15) ;
1566 alias Xorshift64  = XorshiftEngine!(uint, 64,  10, 13, 10); /// ditto
1567 alias Xorshift96  = XorshiftEngine!(uint, 96,  10, 5,  26); /// ditto
1568 alias Xorshift128 = XorshiftEngine!(uint, 128, 11, 8,  19); /// ditto
1569 alias Xorshift160 = XorshiftEngine!(uint, 160, 2,  1,  4);  /// ditto
1570 alias Xorshift192 = XorshiftEngine!(uint, 192, 2,  1,  4);  /// ditto
1571 alias Xorshift    = Xorshift128;                            /// ditto
1572 
1573 ///
1574 @safe @nogc unittest
1575 {
1576     // Seed with a constant
1577     auto rnd = Xorshift(1);
1578     auto num = rnd.front;  // same for each run
1579     assert(num == 1405313047);
1580 
1581     // Seed with an unpredictable value
1582     rnd.seed(unpredictableSeed);
1583     num = rnd.front; // different across rnd
1584 }
1585 
1586 @safe @nogc unittest
1587 {
1588     import std.range;
1589     static assert(isForwardRange!Xorshift);
1590     static assert(isUniformRNG!Xorshift);
1591     static assert(isUniformRNG!(Xorshift, uint));
1592     static assert(isSeedable!Xorshift);
1593     static assert(isSeedable!(Xorshift, uint));
1594 
1595     static assert(Xorshift32.min == 1);
1596 
1597     // Result from reference implementation.
1598     static ulong[][] checking = [
1599         [2463534242UL, 901999875, 3371835698, 2675058524, 1053936272, 3811264849,
1600         472493137, 3856898176, 2131710969, 2312157505],
1601         [362436069UL, 2113136921, 19051112, 3010520417, 951284840, 1213972223,
1602         3173832558, 2611145638, 2515869689, 2245824891],
1603         [521288629UL, 1950277231, 185954712, 1582725458, 3580567609, 2303633688,
1604         2394948066, 4108622809, 1116800180, 3357585673],
1605         [88675123UL, 3701687786, 458299110, 2500872618, 3633119408, 516391518,
1606         2377269574, 2599949379, 717229868, 137866584],
1607         [5783321UL, 393427209, 1947109840, 565829276, 1006220149, 971147905,
1608         1436324242, 2800460115, 1484058076, 3823330032],
1609         [0UL, 246875399, 3690007200, 1264581005, 3906711041, 1866187943, 2481925219,
1610         2464530826, 1604040631, 3653403911],
1611         [16749904790159980466UL, 14489774923612894650UL, 148813570191443371UL,
1612             6529783008780612886UL, 10182425759614080046UL, 16549659571055687844UL,
1613             542957868271744939UL, 9459127085596028450UL, 16001049981702441780UL,
1614             7351634712593111741],
1615         [14750058843113249055UL, 17731577314455387619UL, 1314705253499959044UL,
1616             3113030620614841056UL, 9468075444678629182UL, 13962152036600088141UL,
1617             9030205609946043947UL, 1856726150434672917UL, 8098922200110395314UL,
1618             2772699174618556175UL],
1619     ];
1620 
1621     alias XorshiftTypes = std.meta.AliasSeq!(Xorshift32, Xorshift64, Xorshift96,
1622         Xorshift128, Xorshift160, Xorshift192, Xorshift64_64, Xorshift128_64);
1623 
1624     foreach (I, Type; XorshiftTypes)
1625     {
1626         Type rnd;
1627 
1628         foreach (e; checking[I])
1629         {
1630             assert(rnd.front == e);
1631             rnd.popFront();
1632         }
1633     }
1634 
1635     // Check .save works
1636     foreach (Type; XorshiftTypes)
1637     {
1638         auto rnd1 = Type(123_456_789);
1639         rnd1.popFront();
1640         // https://issues.dlang.org/show_bug.cgi?id=15853
1641         auto rnd2 = ((const ref Type a) => a.save())(rnd1);
1642         assert(rnd1 == rnd2);
1643         // Enable next test when RNGs are reference types
1644         version (none) { assert(rnd1 !is rnd2); }
1645         for (auto i = 0; i <= Type.sizeof / 4; i++, rnd1.popFront, rnd2.popFront)
1646             assert(rnd1.front() == rnd2.front());
1647     }
1648 }
1649 
1650 
1651 /* A complete list of all pseudo-random number generators implemented in
1652  * std.random.  This can be used to confirm that a given function or
1653  * object is compatible with all the pseudo-random number generators
1654  * available.  It is enabled only in unittest mode.
1655  */
1656 @safe @nogc unittest
1657 {
1658     foreach (Rng; PseudoRngTypes)
1659     {
1660         static assert(isUniformRNG!Rng);
1661         auto rng = Rng(123_456_789);
1662     }
1663 }
1664 
1665 version (CRuntime_Bionic)
1666     version = SecureARC4Random; // ChaCha20
1667 version (Darwin)
1668     version = SecureARC4Random; // AES
1669 version (OpenBSD)
1670     version = SecureARC4Random; // ChaCha20
1671 version (NetBSD)
1672     version = SecureARC4Random; // ChaCha20
1673 
1674 version (CRuntime_UClibc)
1675     version = LegacyARC4Random; // ARC4
1676 version (FreeBSD)
1677     version = LegacyARC4Random; // ARC4
1678 version (DragonFlyBSD)
1679     version = LegacyARC4Random; // ARC4
1680 version (BSD)
1681     version = LegacyARC4Random; // Unknown implementation
1682 
1683 // For the current purpose of unpredictableSeed the difference between
1684 // a secure arc4random implementation and a legacy implementation is
1685 // unimportant. The source code documents this distinction in case in the
1686 // future Phobos is altered to require cryptographically secure sources
1687 // of randomness, and also so other people reading this source code (as
1688 // Phobos is often looked to as an example of good D programming practices)
1689 // do not mistakenly use insecure versions of arc4random in contexts where
1690 // cryptographically secure sources of randomness are needed.
1691 
1692 // Performance note: ChaCha20 is about 70% faster than ARC4, contrary to
1693 // what one might assume from it being more secure.
1694 
1695 version (SecureARC4Random)
1696     version = AnyARC4Random;
1697 version (LegacyARC4Random)
1698     version = AnyARC4Random;
1699 
1700 version (AnyARC4Random)
1701 {
1702     extern(C) private @nogc nothrow
1703     {
1704         uint arc4random() @safe;
1705         void arc4random_buf(scope void* buf, size_t nbytes) @system;
1706     }
1707 }
1708 else
1709 {
1710     private ulong bootstrapSeed() @nogc nothrow
1711     {
1712         // https://issues.dlang.org/show_bug.cgi?id=19580
1713         // previously used `ulong result = void` to start with an arbitary value
1714         // but using an uninitialized variable's value is undefined behavior
1715         // and enabled unwanted optimizations on non-DMD compilers.
1716         ulong result;
1717         enum ulong m = 0xc6a4_a793_5bd1_e995UL; // MurmurHash2_64A constant.
1718         void updateResult(ulong x)
1719         {
1720             x *= m;
1721             x = (x ^ (x >>> 47)) * m;
1722             result = (result ^ x) * m;
1723         }
1724         import core.thread : getpid, Thread;
1725         import core.time : MonoTime;
1726 
1727         updateResult(cast(ulong) cast(void*) Thread.getThis());
1728         updateResult(cast(ulong) getpid());
1729         updateResult(cast(ulong) MonoTime.currTime.ticks);
1730         result = (result ^ (result >>> 47)) * m;
1731         return result ^ (result >>> 47);
1732     }
1733 
1734     // If we don't have arc4random and we don't have RDRAND fall back to this.
1735     private ulong fallbackSeed() @nogc nothrow
1736     {
1737         // Bit avalanche function from MurmurHash3.
1738         static ulong fmix64(ulong k) @nogc nothrow pure @safe
1739         {
1740             k = (k ^ (k >>> 33)) * 0xff51afd7ed558ccd;
1741             k = (k ^ (k >>> 33)) * 0xc4ceb9fe1a85ec53;
1742             return k ^ (k >>> 33);
1743         }
1744         // Using SplitMix algorithm with constant gamma.
1745         // Chosen gamma is the odd number closest to 2^^64
1746         // divided by the silver ratio (1.0L + sqrt(2.0L)).
1747         enum gamma = 0x6a09e667f3bcc909UL;
1748         import core.atomic : has64BitCAS;
1749         static if (has64BitCAS)
1750         {
1751             import core.atomic : MemoryOrder, atomicLoad, atomicOp, atomicStore, cas;
1752             shared static ulong seed;
1753             shared static bool initialized;
1754             if (0 == atomicLoad!(MemoryOrder.raw)(initialized))
1755             {
1756                 cas(&seed, 0UL, fmix64(bootstrapSeed()));
1757                 atomicStore!(MemoryOrder.rel)(initialized, true);
1758             }
1759             return fmix64(atomicOp!"+="(seed, gamma));
1760         }
1761         else
1762         {
1763             static ulong seed;
1764             static bool initialized;
1765             if (!initialized)
1766             {
1767                 seed = fmix64(bootstrapSeed());
1768                 initialized = true;
1769             }
1770             return fmix64(seed += gamma);
1771         }
1772     }
1773 }
1774 
1775 version (linux)
1776 {
1777     // `getrandom()` was introduced in Linux 3.17.
1778 
1779     // Shim for missing bindings in druntime
1780     version (none)
1781         import core.sys.linux.sys.random : getrandom;
1782     else
1783     {
1784         import core.sys.posix.sys.types : ssize_t;
1785         extern extern(C) ssize_t getrandom(
1786             void* buf,
1787             size_t buflen,
1788             uint flags,
1789         ) @system nothrow @nogc;
1790     }
1791 }
1792 
1793 version (Windows)
1794 {
1795     pragma(lib, "Bcrypt.lib");
1796 
1797     private bool bcryptGenRandom(T)(out T result) @trusted
1798     {
1799         import core.sys.windows.windef : PUCHAR, ULONG;
1800         import core.sys.windows.ntdef : NT_SUCCESS;
1801         import core.sys.windows.bcrypt : BCryptGenRandom, BCRYPT_USE_SYSTEM_PREFERRED_RNG;
1802 
1803         const gotRandom = BCryptGenRandom(
1804             null,
1805             cast(PUCHAR) &result,
1806             ULONG(T.sizeof),
1807             BCRYPT_USE_SYSTEM_PREFERRED_RNG,
1808         );
1809 
1810         return NT_SUCCESS(gotRandom);
1811     }
1812 }
1813 
1814 /**
1815 A "good" seed for initializing random number engines. Initializing
1816 with $(D_PARAM unpredictableSeed) makes engines generate different
1817 random number sequences every run.
1818 
1819 This function utilizes the system $(I cryptographically-secure pseudo-random
1820 number generator (CSPRNG)) or $(I pseudo-random number generator (PRNG))
1821 where available and implemented (currently `arc4random` on applicable BSD
1822 systems, `getrandom` on Linux or `BCryptGenRandom` on Windows) to generate
1823 “high quality” pseudo-random numbers – if possible.
1824 As a consequence, calling it may block under certain circumstances (typically
1825 during early boot when the system's entropy pool has not yet been
1826 initialized).
1827 
1828 On x86 CPU models which support the `RDRAND` instruction, that will be used
1829 when no more specialized randomness source is implemented.
1830 
1831 In the future, further platform-specific PRNGs may be incorporated.
1832 
1833 Warning:
1834 $(B This function must not be used for cryptographic purposes.)
1835 Despite being implemented for certain targets, there are no guarantees
1836 that it sources its randomness from a CSPRNG.
1837 The implementation also includes a fallback option that provides very little
1838 randomness and is used when no better source of randomness is available or
1839 integrated on the target system.
1840 As written earlier, this function only aims to provide randomness for seeding
1841 ordinary (non-cryptographic) PRNG engines.
1842 
1843 Returns:
1844 A single unsigned integer seed value, different on each successive call
1845 Note:
1846 In general periodically 'reseeding' a PRNG does not improve its quality
1847 and in some cases may harm it. For an extreme example the Mersenne
1848 Twister has `2 ^^ 19937 - 1` distinct states but after `seed(uint)` is
1849 called it can only be in one of `2 ^^ 32` distinct states regardless of
1850 how excellent the source of entropy is.
1851 */
1852 @property uint unpredictableSeed() @trusted nothrow @nogc
1853 {
1854     version (linux)
1855     {
1856         uint buffer;
1857 
1858         /*
1859             getrandom(2):
1860             If the _urandom_ source has been initialized, reads of up to
1861             256 bytes will always return as many bytes as requested and
1862             will not be interrupted by signals. No such guarantees apply
1863             for larger buffer sizes.
1864             */
1865         static assert(buffer.sizeof <= 256);
1866 
1867         const status = (() @trusted => getrandom(&buffer, buffer.sizeof, 0))();
1868         assert(status == buffer.sizeof);
1869 
1870         return buffer;
1871     }
1872     else version (Windows)
1873     {
1874         uint result;
1875         if (!bcryptGenRandom!uint(result))
1876         {
1877             version (none)
1878                 return fallbackSeed();
1879             else
1880                 assert(false, "BCryptGenRandom() failed.");
1881         }
1882         return result;
1883     }
1884     else version (AnyARC4Random)
1885     {
1886         return arc4random();
1887     }
1888     else
1889     {
1890         version (InlineAsm_X86_Any)
1891         {
1892             import core.cpuid : hasRdrand;
1893             if (hasRdrand)
1894             {
1895                 uint result;
1896                 asm @nogc nothrow
1897                 {
1898                     db 0x0f, 0xc7, 0xf0; // rdrand EAX
1899                     jnc LnotUsingRdrand;
1900                     mov result, EAX;
1901                     // Some AMD CPUs shipped with bugs where RDRAND could fail
1902                     // but still set the carry flag to 1. In those cases the
1903                     // output will be -1.
1904                     cmp EAX, 0xffff_ffff;
1905                     jne LusingRdrand;
1906                     // If result was -1 verify RDAND isn't constantly returning -1.
1907                     db 0x0f, 0xc7, 0xf0;
1908                     jnc LusingRdrand;
1909                     cmp EAX, 0xffff_ffff;
1910                     je LnotUsingRdrand;
1911                 }
1912             LusingRdrand:
1913                 return result;
1914             }
1915         LnotUsingRdrand:
1916         }
1917         return cast(uint) fallbackSeed();
1918     }
1919 }
1920 
1921 /// ditto
1922 template unpredictableSeed(UIntType)
1923 if (isUnsigned!UIntType)
1924 {
1925     static if (is(UIntType == uint))
1926         alias unpredictableSeed = .unpredictableSeed;
1927     else static if (!is(Unqual!UIntType == UIntType))
1928         alias unpredictableSeed = .unpredictableSeed!(Unqual!UIntType);
1929     else
1930         /// ditto
1931         @property UIntType unpredictableSeed() @nogc nothrow @trusted
1932         {
1933             version (linux)
1934             {
1935                 UIntType buffer;
1936 
1937                 /*
1938                     getrandom(2):
1939                     If the _urandom_ source has been initialized, reads of up to
1940                     256 bytes will always return as many bytes as requested and
1941                     will not be interrupted by signals. No such guarantees apply
1942                     for larger buffer sizes.
1943                  */
1944                 static assert(buffer.sizeof <= 256);
1945 
1946                 const status = (() @trusted => getrandom(&buffer, buffer.sizeof, 0))();
1947                 assert(status == buffer.sizeof);
1948 
1949                 return buffer;
1950             }
1951             else version (Windows)
1952             {
1953                 UIntType result;
1954                 if (!bcryptGenRandom!UIntType(result))
1955                 {
1956                     version (none)
1957                         return fallbackSeed();
1958                     else
1959                         assert(false, "BCryptGenRandom() failed.");
1960                 }
1961                 return result;
1962             }
1963             else version (AnyARC4Random)
1964             {
1965                 static if (UIntType.sizeof <= uint.sizeof)
1966                 {
1967                     return cast(UIntType) arc4random();
1968                 }
1969                 else
1970                 {
1971                     UIntType result = void;
1972                     arc4random_buf(&result, UIntType.sizeof);
1973                     return result;
1974                 }
1975             }
1976             else
1977             {
1978                 version (InlineAsm_X86_Any)
1979                 {
1980                     import core.cpuid : hasRdrand;
1981                     if (hasRdrand)
1982                     {
1983                         static if (UIntType.sizeof <= uint.sizeof)
1984                         {
1985                             uint result;
1986                             asm @nogc nothrow
1987                             {
1988                                 db 0x0f, 0xc7, 0xf0; // rdrand EAX
1989                                 jnc LnotUsingRdrand;
1990                                 mov result, EAX;
1991                                 // Some AMD CPUs shipped with bugs where RDRAND could fail
1992                                 // but still set the carry flag to 1. In those cases the
1993                                 // output will be -1.
1994                                 cmp EAX, 0xffff_ffff;
1995                                 jne LusingRdrand;
1996                                 // If result was -1 verify RDAND isn't constantly returning -1.
1997                                 db 0x0f, 0xc7, 0xf0;
1998                                 jnc LusingRdrand;
1999                                 cmp EAX, 0xffff_ffff;
2000                                 je LnotUsingRdrand;
2001                             }
2002                         LusingRdrand:
2003                             return cast(UIntType) result;
2004                         }
2005                         else version (D_InlineAsm_X86_64)
2006                         {
2007                             ulong result;
2008                             asm @nogc nothrow
2009                             {
2010                                 db 0x48, 0x0f, 0xc7, 0xf0; // rdrand RAX
2011                                 jnc LnotUsingRdrand;
2012                                 mov result, RAX;
2013                                 // Some AMD CPUs shipped with bugs where RDRAND could fail
2014                                 // but still set the carry flag to 1. In those cases the
2015                                 // output will be -1.
2016                                 cmp RAX, 0xffff_ffff_ffff_ffff;
2017                                 jne LusingRdrand;
2018                                 // If result was -1 verify RDAND isn't constantly returning -1.
2019                                 db 0x48, 0x0f, 0xc7, 0xf0;
2020                                 jnc LusingRdrand;
2021                                 cmp RAX, 0xffff_ffff_ffff_ffff;
2022                                 je LnotUsingRdrand;
2023                             }
2024                         LusingRdrand:
2025                             return result;
2026                         }
2027                         else
2028                         {
2029                             uint resultLow, resultHigh;
2030                             asm @nogc nothrow
2031                             {
2032                                 db 0x0f, 0xc7, 0xf0; // rdrand EAX
2033                                 jnc LnotUsingRdrand;
2034                                 mov resultLow, EAX;
2035                                 db 0x0f, 0xc7, 0xf0; // rdrand EAX
2036                                 jnc LnotUsingRdrand;
2037                                 mov resultHigh, EAX;
2038                             }
2039                             if (resultLow != uint.max || resultHigh != uint.max) // Protect against AMD RDRAND bug.
2040                                 return ((cast(ulong) resultHigh) << 32) ^ resultLow;
2041                         }
2042                     }
2043                 LnotUsingRdrand:
2044                 }
2045                 return cast(UIntType) fallbackSeed();
2046             }
2047         }
2048 }
2049 
2050 ///
2051 @safe @nogc unittest
2052 {
2053     auto rnd = Random(unpredictableSeed);
2054     auto n = rnd.front;
2055     static assert(is(typeof(n) == uint));
2056 }
2057 
2058 /**
2059 The "default", "favorite", "suggested" random number generator type on
2060 the current platform. It is an alias for one of the previously-defined
2061 generators. You may want to use it if (1) you need to generate some
2062 nice random numbers, and (2) you don't care for the minutiae of the
2063 method being used.
2064  */
2065 
2066 alias Random = Mt19937;
2067 
2068 @safe @nogc unittest
2069 {
2070     static assert(isUniformRNG!Random);
2071     static assert(isUniformRNG!(Random, uint));
2072     static assert(isSeedable!Random);
2073     static assert(isSeedable!(Random, uint));
2074 }
2075 
2076 /**
2077 Global random number generator used by various functions in this
2078 module whenever no generator is specified. It is allocated per-thread
2079 and initialized to an unpredictable value for each thread.
2080 
2081 Returns:
2082 A singleton instance of the default random number generator
2083  */
2084 @property ref Random rndGen() @safe nothrow @nogc
2085 {
2086     static Random result;
2087     static bool initialized;
2088     if (!initialized)
2089     {
2090         static if (isSeedable!(Random, ulong))
2091             result.seed(unpredictableSeed!ulong); // Avoid unnecessary copy.
2092         else static if (is(Random : MersenneTwisterEngine!Params, Params...))
2093             initMTEngine(result);
2094         else static if (isSeedable!(Random, uint))
2095             result.seed(unpredictableSeed!uint); // Avoid unnecessary copy.
2096         else
2097             result = Random(unpredictableSeed);
2098         initialized = true;
2099     }
2100     return result;
2101 }
2102 
2103 ///
2104 @safe nothrow @nogc unittest
2105 {
2106     import std.algorithm.iteration : sum;
2107     import std.range : take;
2108     auto rnd = rndGen;
2109     assert(rnd.take(3).sum > 0);
2110 }
2111 
2112 /+
2113 Initialize a 32-bit MersenneTwisterEngine from 64 bits of entropy.
2114 This is private and accepts no seed as a parameter, freeing the internal
2115 implementaton from any need for stability across releases.
2116 +/
2117 private void initMTEngine(MTEngine)(scope ref MTEngine mt)
2118 if (is(MTEngine : MersenneTwisterEngine!Params, Params...))
2119 {
2120     pragma(inline, false); // Called no more than once per thread by rndGen.
2121     ulong seed = unpredictableSeed!ulong;
2122     static if (is(typeof(mt.seed(seed))))
2123     {
2124         mt.seed(seed);
2125     }
2126     else
2127     {
2128         alias UIntType = typeof(mt.front());
2129         if (seed == 0) seed = -1; // Any number but 0 is fine.
2130         uint s0 = cast(uint) seed;
2131         uint s1 = cast(uint) (seed >> 32);
2132         foreach (ref e; mt.state.data)
2133         {
2134             //http://xoshiro.di.unimi.it/xoroshiro64starstar.c
2135             const tmp = s0 * 0x9E3779BB;
2136             e = ((tmp << 5) | (tmp >> (32 - 5))) * 5;
2137             static if (MTEngine.max != UIntType.max) { e &= MTEngine.max; }
2138 
2139             const tmp1 = s0 ^ s1;
2140             s0 = ((s0 << 26) | (s0 >> (32 - 26))) ^ tmp1 ^ (tmp1 << 9);
2141             s1 = (tmp1 << 13) | (tmp1 >> (32 - 13));
2142         }
2143 
2144         mt.state.index = mt.state.data.length - 1;
2145         // double popFront() to guarantee both `mt.state.z`
2146         // and `mt.state.front` are derived from the newly
2147         // set values in `mt.state.data`.
2148         mt.popFront();
2149         mt.popFront();
2150     }
2151 }
2152 
2153 /**
2154 Generates a number between `a` and `b`. The `boundaries`
2155 parameter controls the shape of the interval (open vs. closed on
2156 either side). Valid values for `boundaries` are `"[]"`, $(D
2157 "$(LPAREN)]"), `"[$(RPAREN)"`, and `"()"`. The default interval
2158 is closed to the left and open to the right. The version that does not
2159 take `urng` uses the default generator `rndGen`.
2160 
2161 Params:
2162     a = lower bound of the _uniform distribution
2163     b = upper bound of the _uniform distribution
2164     urng = (optional) random number generator to use;
2165            if not specified, defaults to `rndGen`
2166 
2167 Returns:
2168     A single random variate drawn from the _uniform distribution
2169     between `a` and `b`, whose type is the common type of
2170     these parameters
2171  */
2172 auto uniform(string boundaries = "[)", T1, T2)
2173 (T1 a, T2 b)
2174 if (!is(CommonType!(T1, T2) == void))
2175 {
2176     return uniform!(boundaries, T1, T2, Random)(a, b, rndGen);
2177 }
2178 
2179 ///
2180 @safe unittest
2181 {
2182     auto rnd = Random(unpredictableSeed);
2183 
2184     // Generate an integer in [0, 1023]
2185     auto a = uniform(0, 1024, rnd);
2186     assert(0 <= a && a < 1024);
2187 
2188     // Generate a float in [0, 1)
2189     auto b = uniform(0.0f, 1.0f, rnd);
2190     assert(0 <= b && b < 1);
2191 
2192     // Generate a float in [0, 1]
2193     b = uniform!"[]"(0.0f, 1.0f, rnd);
2194     assert(0 <= b && b <= 1);
2195 
2196     // Generate a float in (0, 1)
2197     b = uniform!"()"(0.0f, 1.0f, rnd);
2198     assert(0 < b && b < 1);
2199 }
2200 
2201 /// Create an array of random numbers using range functions and UFCS
2202 @safe unittest
2203 {
2204     import std.array : array;
2205     import std.range : generate, takeExactly;
2206 
2207     int[] arr = generate!(() => uniform(0, 100)).takeExactly(10).array;
2208     assert(arr.length == 10);
2209     assert(arr[0] >= 0 && arr[0] < 100);
2210 }
2211 
2212 @safe unittest
2213 {
2214     MinstdRand0 gen;
2215     foreach (i; 0 .. 20)
2216     {
2217         auto x = uniform(0.0, 15.0, gen);
2218         assert(0 <= x && x < 15);
2219     }
2220     foreach (i; 0 .. 20)
2221     {
2222         auto x = uniform!"[]"('a', 'z', gen);
2223         assert('a' <= x && x <= 'z');
2224     }
2225 
2226     foreach (i; 0 .. 20)
2227     {
2228         auto x = uniform('a', 'z', gen);
2229         assert('a' <= x && x < 'z');
2230     }
2231 
2232     foreach (i; 0 .. 20)
2233     {
2234         immutable ubyte a = 0;
2235             immutable ubyte b = 15;
2236         auto x = uniform(a, b, gen);
2237             assert(a <= x && x < b);
2238     }
2239 }
2240 
2241 // Implementation of uniform for floating-point types
2242 /// ditto
2243 auto uniform(string boundaries = "[)",
2244         T1, T2, UniformRandomNumberGenerator)
2245 (T1 a, T2 b, ref UniformRandomNumberGenerator urng)
2246 if (isFloatingPoint!(CommonType!(T1, T2)) && isUniformRNG!UniformRandomNumberGenerator)
2247 {
2248     import std.conv : text;
2249     import std.exception : enforce;
2250     alias NumberType = Unqual!(CommonType!(T1, T2));
2251     static if (boundaries[0] == '(')
2252     {
2253         import std.math.operations : nextafter;
2254         NumberType _a = nextafter(cast(NumberType) a, NumberType.infinity);
2255     }
2256     else
2257     {
2258         NumberType _a = a;
2259     }
2260     static if (boundaries[1] == ')')
2261     {
2262         import std.math.operations : nextafter;
2263         NumberType _b = nextafter(cast(NumberType) b, -NumberType.infinity);
2264     }
2265     else
2266     {
2267         NumberType _b = b;
2268     }
2269     enforce(_a <= _b,
2270             text("std.random.uniform(): invalid bounding interval ",
2271                     boundaries[0], a, ", ", b, boundaries[1]));
2272     NumberType result =
2273         _a + (_b - _a) * cast(NumberType) (urng.front - urng.min)
2274         / (urng.max - urng.min);
2275     urng.popFront();
2276     return result;
2277 }
2278 
2279 // Implementation of uniform for integral types
2280 /+ Description of algorithm and suggestion of correctness:
2281 
2282 The modulus operator maps an integer to a small, finite space. For instance, `x
2283 % 3` will map whatever x is into the range [0 .. 3). 0 maps to 0, 1 maps to 1, 2
2284 maps to 2, 3 maps to 0, and so on infinitely. As long as the integer is
2285 uniformly chosen from the infinite space of all non-negative integers then `x %
2286 3` will uniformly fall into that range.
2287 
2288 (Non-negative is important in this case because some definitions of modulus,
2289 namely the one used in computers generally, map negative numbers differently to
2290 (-3 .. 0]. `uniform` does not use negative number modulus, thus we can safely
2291 ignore that fact.)
2292 
2293 The issue with computers is that integers have a finite space they must fit in,
2294 and our uniformly chosen random number is picked in that finite space. So, that
2295 method is not sufficient. You can look at it as the integer space being divided
2296 into "buckets" and every bucket after the first bucket maps directly into that
2297 first bucket. `[0, 1, 2]`, `[3, 4, 5]`, ... When integers are finite, then the
2298 last bucket has the chance to be "incomplete": `[uint.max - 3, uint.max - 2,
2299 uint.max - 1]`, `[uint.max]` ... (the last bucket only has 1!). The issue here
2300 is that _every_ bucket maps _completely_ to the first bucket except for that
2301 last one. The last one doesn't have corresponding mappings to 1 or 2, in this
2302 case, which makes it unfair.
2303 
2304 So, the answer is to simply "reroll" if you're in that last bucket, since it's
2305 the only unfair one. Eventually you'll roll into a fair bucket. Simply, instead
2306 of the meaning of the last bucket being "maps to `[0]`", it changes to "maps to
2307 `[0, 1, 2]`", which is precisely what we want.
2308 
2309 To generalize, `upperDist` represents the size of our buckets (and, thus, the
2310 exclusive upper bound for our desired uniform number). `rnum` is a uniformly
2311 random number picked from the space of integers that a computer can hold (we'll
2312 say `UpperType` represents that type).
2313 
2314 We'll first try to do the mapping into the first bucket by doing `offset = rnum
2315 % upperDist`. We can figure out the position of the front of the bucket we're in
2316 by `bucketFront = rnum - offset`.
2317 
2318 If we start at `UpperType.max` and walk backwards `upperDist - 1` spaces, then
2319 the space we land on is the last acceptable position where a full bucket can
2320 fit:
2321 
2322 ---
2323    bucketFront     UpperType.max
2324       v                 v
2325 [..., 0, 1, 2, ..., upperDist - 1]
2326       ^~~ upperDist - 1 ~~^
2327 ---
2328 
2329 If the bucket starts any later, then it must have lost at least one number and
2330 at least that number won't be represented fairly.
2331 
2332 ---
2333                 bucketFront     UpperType.max
2334                      v                v
2335 [..., upperDist - 1, 0, 1, 2, ..., upperDist - 2]
2336           ^~~~~~~~ upperDist - 1 ~~~~~~~^
2337 ---
2338 
2339 Hence, our condition to reroll is
2340 `bucketFront > (UpperType.max - (upperDist - 1))`
2341 +/
2342 /// ditto
2343 auto uniform(string boundaries = "[)", T1, T2, RandomGen)
2344 (T1 a, T2 b, ref RandomGen rng)
2345 if ((isIntegral!(CommonType!(T1, T2)) || isSomeChar!(CommonType!(T1, T2))) &&
2346      isUniformRNG!RandomGen)
2347 {
2348     import std.conv : text, unsigned;
2349     import std.exception : enforce;
2350     alias ResultType = Unqual!(CommonType!(T1, T2));
2351     static if (boundaries[0] == '(')
2352     {
2353         enforce(a < ResultType.max,
2354                 text("std.random.uniform(): invalid left bound ", a));
2355         ResultType lower = cast(ResultType) (a + 1);
2356     }
2357     else
2358     {
2359         ResultType lower = a;
2360     }
2361 
2362     static if (boundaries[1] == ']')
2363     {
2364         enforce(lower <= b,
2365                 text("std.random.uniform(): invalid bounding interval ",
2366                         boundaries[0], a, ", ", b, boundaries[1]));
2367         /* Cannot use this next optimization with dchar, as dchar
2368          * only partially uses its full bit range
2369          */
2370         static if (!is(ResultType == dchar))
2371         {
2372             if (b == ResultType.max && lower == ResultType.min)
2373             {
2374                 // Special case - all bits are occupied
2375                 return std.random.uniform!ResultType(rng);
2376             }
2377         }
2378         auto upperDist = unsigned(b - lower) + 1u;
2379     }
2380     else
2381     {
2382         enforce(lower < b,
2383                 text("std.random.uniform(): invalid bounding interval ",
2384                         boundaries[0], a, ", ", b, boundaries[1]));
2385         auto upperDist = unsigned(b - lower);
2386     }
2387 
2388     assert(upperDist != 0);
2389 
2390     alias UpperType = typeof(upperDist);
2391     static assert(UpperType.min == 0);
2392 
2393     UpperType offset, rnum, bucketFront;
2394     do
2395     {
2396         rnum = uniform!UpperType(rng);
2397         offset = rnum % upperDist;
2398         bucketFront = rnum - offset;
2399     } // while we're in an unfair bucket...
2400     while (bucketFront > (UpperType.max - (upperDist - 1)));
2401 
2402     return cast(ResultType)(lower + offset);
2403 }
2404 
2405 ///
2406 @safe unittest
2407 {
2408     import std.conv : to;
2409     import std.meta : AliasSeq;
2410     import std.range.primitives : isForwardRange;
2411     import std.traits : isIntegral, isSomeChar;
2412 
2413     auto gen = Mt19937(123_456_789);
2414     static assert(isForwardRange!(typeof(gen)));
2415 
2416     auto a = uniform(0, 1024, gen);
2417     assert(0 <= a && a <= 1024);
2418     auto b = uniform(0.0f, 1.0f, gen);
2419     assert(0 <= b && b < 1, to!string(b));
2420     auto c = uniform(0.0, 1.0);
2421     assert(0 <= c && c < 1);
2422 
2423     static foreach (T; AliasSeq!(char, wchar, dchar, byte, ubyte, short, ushort,
2424                           int, uint, long, ulong, float, double, real))
2425     {{
2426         T lo = 0, hi = 100;
2427 
2428         // Try tests with each of the possible bounds
2429         {
2430             T init = uniform(lo, hi);
2431             size_t i = 50;
2432             while (--i && uniform(lo, hi) == init) {}
2433             assert(i > 0);
2434         }
2435         {
2436             T init = uniform!"[)"(lo, hi);
2437             size_t i = 50;
2438             while (--i && uniform(lo, hi) == init) {}
2439             assert(i > 0);
2440         }
2441         {
2442             T init = uniform!"(]"(lo, hi);
2443             size_t i = 50;
2444             while (--i && uniform(lo, hi) == init) {}
2445             assert(i > 0);
2446         }
2447         {
2448             T init = uniform!"()"(lo, hi);
2449             size_t i = 50;
2450             while (--i && uniform(lo, hi) == init) {}
2451             assert(i > 0);
2452         }
2453         {
2454             T init = uniform!"[]"(lo, hi);
2455             size_t i = 50;
2456             while (--i && uniform(lo, hi) == init) {}
2457             assert(i > 0);
2458         }
2459 
2460         /* Test case with closed boundaries covering whole range
2461          * of integral type
2462          */
2463         static if (isIntegral!T || isSomeChar!T)
2464         {
2465             foreach (immutable _; 0 .. 100)
2466             {
2467                 auto u = uniform!"[]"(T.min, T.max);
2468                 static assert(is(typeof(u) == T));
2469                 assert(T.min <= u, "Lower bound violation for uniform!\"[]\" with " ~ T.stringof);
2470                 assert(u <= T.max, "Upper bound violation for uniform!\"[]\" with " ~ T.stringof);
2471             }
2472         }
2473     }}
2474 
2475     auto reproRng = Xorshift(239842);
2476 
2477     static foreach (T; AliasSeq!(char, wchar, dchar, byte, ubyte, short,
2478                           ushort, int, uint, long, ulong))
2479     {{
2480         T lo = T.min + 10, hi = T.max - 10;
2481         T init = uniform(lo, hi, reproRng);
2482         size_t i = 50;
2483         while (--i && uniform(lo, hi, reproRng) == init) {}
2484         assert(i > 0);
2485     }}
2486 
2487     {
2488         bool sawLB = false, sawUB = false;
2489         foreach (i; 0 .. 50)
2490         {
2491             auto x = uniform!"[]"('a', 'd', reproRng);
2492             if (x == 'a') sawLB = true;
2493             if (x == 'd') sawUB = true;
2494             assert('a' <= x && x <= 'd');
2495         }
2496         assert(sawLB && sawUB);
2497     }
2498 
2499     {
2500         bool sawLB = false, sawUB = false;
2501         foreach (i; 0 .. 50)
2502         {
2503             auto x = uniform('a', 'd', reproRng);
2504             if (x == 'a') sawLB = true;
2505             if (x == 'c') sawUB = true;
2506             assert('a' <= x && x < 'd');
2507         }
2508         assert(sawLB && sawUB);
2509     }
2510 
2511     {
2512         bool sawLB = false, sawUB = false;
2513         foreach (i; 0 .. 50)
2514         {
2515             immutable int lo = -2, hi = 2;
2516             auto x = uniform!"()"(lo, hi, reproRng);
2517             if (x == (lo+1)) sawLB = true;
2518             if (x == (hi-1)) sawUB = true;
2519             assert(lo < x && x < hi);
2520         }
2521         assert(sawLB && sawUB);
2522     }
2523 
2524     {
2525         bool sawLB = false, sawUB = false;
2526         foreach (i; 0 .. 50)
2527         {
2528             immutable ubyte lo = 0, hi = 5;
2529             auto x = uniform(lo, hi, reproRng);
2530             if (x == lo) sawLB = true;
2531             if (x == (hi-1)) sawUB = true;
2532             assert(lo <= x && x < hi);
2533         }
2534         assert(sawLB && sawUB);
2535     }
2536 
2537     {
2538         foreach (i; 0 .. 30)
2539         {
2540             assert(i == uniform(i, i+1, reproRng));
2541         }
2542     }
2543 }
2544 
2545 /+
2546 Generates an unsigned integer in the half-open range `[0, k)`.
2547 Non-public because we locally guarantee `k > 0`.
2548 
2549 Params:
2550     k = unsigned exclusive upper bound; caller guarantees this is non-zero
2551     rng = random number generator to use
2552 
2553 Returns:
2554     Pseudo-random unsigned integer strictly less than `k`.
2555 +/
2556 private UInt _uniformIndex(UniformRNG, UInt = size_t)(const UInt k, ref UniformRNG rng)
2557 if (isUnsigned!UInt && isUniformRNG!UniformRNG)
2558 {
2559     alias ResultType = UInt;
2560     alias UpperType = Unsigned!(typeof(k - 0));
2561     alias upperDist = k;
2562 
2563     assert(upperDist != 0);
2564 
2565     // For backwards compatibility use same algorithm as uniform(0, k, rng).
2566     UpperType offset, rnum, bucketFront;
2567     do
2568     {
2569         rnum = uniform!UpperType(rng);
2570         offset = rnum % upperDist;
2571         bucketFront = rnum - offset;
2572     } // while we're in an unfair bucket...
2573     while (bucketFront > (UpperType.max - (upperDist - 1)));
2574 
2575     return cast(ResultType) offset;
2576 }
2577 
2578 pure @safe unittest
2579 {
2580     // For backwards compatibility check that _uniformIndex(k, rng)
2581     // has the same result as uniform(0, k, rng).
2582     auto rng1 = Xorshift(123_456_789);
2583     auto rng2 = rng1.save();
2584     const size_t k = (1U << 31) - 1;
2585     assert(_uniformIndex(k, rng1) == uniform(0, k, rng2));
2586 }
2587 
2588 /**
2589 Generates a uniformly-distributed number in the range $(D [T.min,
2590 T.max]) for any integral or character type `T`. If no random
2591 number generator is passed, uses the default `rndGen`.
2592 
2593 If an `enum` is used as type, the random variate is drawn with
2594 equal probability from any of the possible values of the enum `E`.
2595 
2596 Params:
2597     urng = (optional) random number generator to use;
2598            if not specified, defaults to `rndGen`
2599 
2600 Returns:
2601     Random variate drawn from the _uniform distribution across all
2602     possible values of the integral, character or enum type `T`.
2603  */
2604 auto uniform(T, UniformRandomNumberGenerator)
2605 (ref UniformRandomNumberGenerator urng)
2606 if (!is(T == enum) && (isIntegral!T || isSomeChar!T) && isUniformRNG!UniformRandomNumberGenerator)
2607 {
2608     /* dchar does not use its full bit range, so we must
2609      * revert to the uniform with specified bounds
2610      */
2611     static if (is(immutable T == immutable dchar))
2612     {
2613         return uniform!"[]"(T.min, T.max, urng);
2614     }
2615     else
2616     {
2617         auto r = urng.front;
2618         urng.popFront();
2619         static if (T.sizeof <= r.sizeof)
2620         {
2621             return cast(T) r;
2622         }
2623         else
2624         {
2625             static assert(T.sizeof == 8 && r.sizeof == 4);
2626             T r1 = urng.front | (cast(T) r << 32);
2627             urng.popFront();
2628             return r1;
2629         }
2630     }
2631 }
2632 
2633 /// Ditto
2634 auto uniform(T)()
2635 if (!is(T == enum) && (isIntegral!T || isSomeChar!T))
2636 {
2637     return uniform!T(rndGen);
2638 }
2639 
2640 ///
2641 @safe unittest
2642 {
2643     auto rnd = MinstdRand0(42);
2644 
2645     assert(rnd.uniform!ubyte == 102);
2646     assert(rnd.uniform!ulong == 4838462006927449017);
2647 
2648     enum Fruit { apple, mango, pear }
2649     version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
2650     assert(rnd.uniform!Fruit == Fruit.mango);
2651 }
2652 
2653 @safe unittest
2654 {
2655     // https://issues.dlang.org/show_bug.cgi?id=21383
2656     auto rng1 = Xorshift32(123456789);
2657     auto rng2 = rng1.save;
2658     assert(rng1.uniform!dchar == rng2.uniform!dchar);
2659     // https://issues.dlang.org/show_bug.cgi?id=21384
2660     assert(rng1.uniform!(const shared dchar) <= dchar.max);
2661     // https://issues.dlang.org/show_bug.cgi?id=8671
2662     double t8671 = 1.0 - uniform(0.0, 1.0);
2663 }
2664 
2665 @safe unittest
2666 {
2667     static foreach (T; std.meta.AliasSeq!(char, wchar, dchar, byte, ubyte, short, ushort,
2668                           int, uint, long, ulong))
2669     {{
2670         T init = uniform!T();
2671         size_t i = 50;
2672         while (--i && uniform!T() == init) {}
2673         assert(i > 0);
2674 
2675         foreach (immutable _; 0 .. 100)
2676         {
2677             auto u = uniform!T();
2678             static assert(is(typeof(u) == T));
2679             assert(T.min <= u, "Lower bound violation for uniform!" ~ T.stringof);
2680             assert(u <= T.max, "Upper bound violation for uniform!" ~ T.stringof);
2681         }
2682     }}
2683 }
2684 
2685 /// ditto
2686 auto uniform(E, UniformRandomNumberGenerator)
2687 (ref UniformRandomNumberGenerator urng)
2688 if (is(E == enum) && isUniformRNG!UniformRandomNumberGenerator)
2689 {
2690     static immutable E[EnumMembers!E.length] members = [EnumMembers!E];
2691     return members[std.random.uniform(0, members.length, urng)];
2692 }
2693 
2694 /// Ditto
2695 auto uniform(E)()
2696 if (is(E == enum))
2697 {
2698     return uniform!E(rndGen);
2699 }
2700 
2701 @safe unittest
2702 {
2703     enum Fruit { Apple = 12, Mango = 29, Pear = 72 }
2704     foreach (_; 0 .. 100)
2705     {
2706         foreach (f; [uniform!Fruit(), rndGen.uniform!Fruit()])
2707         {
2708             assert(f == Fruit.Apple || f == Fruit.Mango || f == Fruit.Pear);
2709         }
2710     }
2711 }
2712 
2713 /**
2714  * Generates a uniformly-distributed floating point number of type
2715  * `T` in the range [0, 1$(RPAREN).  If no random number generator is
2716  * specified, the default RNG `rndGen` will be used as the source
2717  * of randomness.
2718  *
2719  * `uniform01` offers a faster generation of random variates than
2720  * the equivalent $(D uniform!"[$(RPAREN)"(0.0, 1.0)) and so may be preferred
2721  * for some applications.
2722  *
2723  * Params:
2724  *     rng = (optional) random number generator to use;
2725  *           if not specified, defaults to `rndGen`
2726  *
2727  * Returns:
2728  *     Floating-point random variate of type `T` drawn from the _uniform
2729  *     distribution across the half-open interval [0, 1$(RPAREN).
2730  *
2731  */
2732 T uniform01(T = double)()
2733 if (isFloatingPoint!T)
2734 {
2735     return uniform01!T(rndGen);
2736 }
2737 
2738 /// ditto
2739 T uniform01(T = double, UniformRNG)(ref UniformRNG rng)
2740 if (isFloatingPoint!T && isUniformRNG!UniformRNG)
2741 out (result)
2742 {
2743     assert(0 <= result);
2744     assert(result < 1);
2745 }
2746 do
2747 {
2748     alias R = typeof(rng.front);
2749     static if (isIntegral!R)
2750     {
2751         enum T factor = 1 / (T(1) + rng.max - rng.min);
2752     }
2753     else static if (isFloatingPoint!R)
2754     {
2755         enum T factor = 1 / (rng.max - rng.min);
2756     }
2757     else
2758     {
2759         static assert(false);
2760     }
2761 
2762     while (true)
2763     {
2764         immutable T u = (rng.front - rng.min) * factor;
2765         rng.popFront();
2766 
2767         static if (isIntegral!R && T.mant_dig >= (8 * R.sizeof))
2768         {
2769             /* If RNG variates are integral and T has enough precision to hold
2770              * R without loss, we're guaranteed by the definition of factor
2771              * that precisely u < 1.
2772              */
2773             return u;
2774         }
2775         else
2776         {
2777             /* Otherwise we have to check whether u is beyond the assumed range
2778              * because of the loss of precision, or for another reason, a
2779              * floating-point RNG can return a variate that is exactly equal to
2780              * its maximum.
2781              */
2782             if (u < 1)
2783             {
2784                 return u;
2785             }
2786         }
2787     }
2788 
2789     // Shouldn't ever get here.
2790     assert(false);
2791 }
2792 
2793 ///
2794 @safe @nogc unittest
2795 {
2796     import std.math.operations : feqrel;
2797 
2798     auto rnd = MinstdRand0(42);
2799 
2800     // Generate random numbers in the range in the range [0, 1)
2801     auto u1 = uniform01(rnd);
2802     assert(u1 >= 0 && u1 < 1);
2803 
2804     auto u2 = rnd.uniform01!float;
2805     assert(u2 >= 0 && u2 < 1);
2806 
2807     // Confirm that the random values with the initial seed 42 are 0.000328707 and 0.524587
2808     assert(u1.feqrel(0.000328707) > 20);
2809     assert(u2.feqrel(0.524587) > 20);
2810 }
2811 
2812 @safe @nogc unittest
2813 {
2814     import std.meta;
2815     static foreach (UniformRNG; PseudoRngTypes)
2816     {{
2817 
2818         static foreach (T; std.meta.AliasSeq!(float, double, real))
2819         {{
2820             UniformRNG rng = UniformRNG(123_456_789);
2821 
2822             auto a = uniform01();
2823             assert(is(typeof(a) == double));
2824             assert(0 <= a && a < 1);
2825 
2826             auto b = uniform01(rng);
2827             assert(is(typeof(a) == double));
2828             assert(0 <= b && b < 1);
2829 
2830             auto c = uniform01!T();
2831             assert(is(typeof(c) == T));
2832             assert(0 <= c && c < 1);
2833 
2834             auto d = uniform01!T(rng);
2835             assert(is(typeof(d) == T));
2836             assert(0 <= d && d < 1);
2837 
2838             T init = uniform01!T(rng);
2839             size_t i = 50;
2840             while (--i && uniform01!T(rng) == init) {}
2841             assert(i > 0);
2842             assert(i < 50);
2843         }}
2844     }}
2845 }
2846 
2847 /**
2848 Generates a uniform probability distribution of size `n`, i.e., an
2849 array of size `n` of positive numbers of type `F` that sum to
2850 `1`. If `useThis` is provided, it is used as storage.
2851  */
2852 F[] uniformDistribution(F = double)(size_t n, F[] useThis = null)
2853 if (isFloatingPoint!F)
2854 {
2855     import std.numeric : normalize;
2856     useThis.length = n;
2857     foreach (ref e; useThis)
2858     {
2859         e = uniform(0.0, 1);
2860     }
2861     normalize(useThis);
2862     return useThis;
2863 }
2864 
2865 ///
2866 @safe unittest
2867 {
2868     import std.algorithm.iteration : reduce;
2869     import std.math.operations : isClose;
2870 
2871     auto a = uniformDistribution(5);
2872     assert(a.length == 5);
2873     assert(isClose(reduce!"a + b"(a), 1));
2874 
2875     a = uniformDistribution(10, a);
2876     assert(a.length == 10);
2877     assert(isClose(reduce!"a + b"(a), 1));
2878 }
2879 
2880 /**
2881 Returns a random, uniformly chosen, element `e` from the supplied
2882 $(D Range range). If no random number generator is passed, the default
2883 `rndGen` is used.
2884 
2885 Params:
2886     range = a random access range that has the `length` property defined
2887     urng = (optional) random number generator to use;
2888            if not specified, defaults to `rndGen`
2889 
2890 Returns:
2891     A single random element drawn from the `range`. If it can, it will
2892     return a `ref` to the $(D range element), otherwise it will return
2893     a copy.
2894  */
2895 auto ref choice(Range, RandomGen = Random)(Range range, ref RandomGen urng)
2896 if (isRandomAccessRange!Range && hasLength!Range && isUniformRNG!RandomGen)
2897 {
2898     assert(range.length > 0,
2899            __PRETTY_FUNCTION__ ~ ": invalid Range supplied. Range cannot be empty");
2900 
2901     return range[uniform(size_t(0), $, urng)];
2902 }
2903 
2904 /// ditto
2905 auto ref choice(Range)(Range range)
2906 {
2907     return choice(range, rndGen);
2908 }
2909 
2910 /// ditto
2911 auto ref choice(Range, RandomGen = Random)(ref Range range, ref RandomGen urng)
2912 if (isRandomAccessRange!Range && hasLength!Range && isUniformRNG!RandomGen)
2913 {
2914     assert(range.length > 0,
2915            __PRETTY_FUNCTION__ ~ ": invalid Range supplied. Range cannot be empty");
2916     return range[uniform(size_t(0), $, urng)];
2917 }
2918 
2919 /// ditto
2920 auto ref choice(Range)(ref Range range)
2921 {
2922     return choice(range, rndGen);
2923 }
2924 
2925 ///
2926 @safe unittest
2927 {
2928     auto rnd = MinstdRand0(42);
2929 
2930     auto elem  = [1, 2, 3, 4, 5].choice(rnd);
2931     version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
2932     assert(elem == 3);
2933 }
2934 
2935 @safe unittest
2936 {
2937     import std.algorithm.searching : canFind;
2938 
2939     static class MyTestClass
2940     {
2941         int x;
2942 
2943         this(int x)
2944         {
2945             this.x = x;
2946         }
2947     }
2948 
2949     MyTestClass[] testClass;
2950     foreach (i; 0 .. 5)
2951     {
2952         testClass ~= new MyTestClass(i);
2953     }
2954 
2955     auto elem = choice(testClass);
2956 
2957     assert(canFind!((ref MyTestClass a, ref MyTestClass b) => a.x == b.x)(testClass, elem),
2958            "Choice did not return a valid element from the given Range");
2959 }
2960 
2961 @system unittest
2962 {
2963     import std.algorithm.iteration : map;
2964     import std.algorithm.searching : canFind;
2965 
2966     auto array = [1, 2, 3, 4, 5];
2967     auto elemAddr = &choice(array);
2968 
2969     assert(array.map!((ref e) => &e).canFind(elemAddr),
2970            "Choice did not return a ref to an element from the given Range");
2971     assert(array.canFind(*(cast(int *)(elemAddr))),
2972            "Choice did not return a valid element from the given Range");
2973 }
2974 
2975 @safe unittest // https://issues.dlang.org/show_bug.cgi?id=18631
2976 {
2977     auto rng = MinstdRand0(42);
2978     const a = [0,1,2];
2979     const(int[]) b = [0, 1, 2];
2980     auto x = choice(a);
2981     auto y = choice(b);
2982     auto z = choice(cast(const)[1, 2, 3]);
2983     auto x1 = choice(a, rng);
2984     auto y1 = choice(b, rng);
2985     auto z1 = choice(cast(const)[1, 2, 3], rng);
2986 }
2987 
2988 @safe unittest // Ref range (https://issues.dlang.org/show_bug.cgi?id=18631 PR)
2989 {
2990     struct TestRange
2991     {
2992         int x;
2993         ref int front() return {return x;}
2994         ref int back() return {return x;}
2995         void popFront() {}
2996         void popBack() {}
2997         bool empty = false;
2998         TestRange save() {return this;}
2999         size_t length = 10;
3000         alias opDollar = length;
3001         ref int opIndex(size_t i) return {return x;}
3002     }
3003 
3004     TestRange r = TestRange(10);
3005     int* s = &choice(r);
3006 }
3007 
3008 /**
3009 Shuffles elements of `r` using `gen` as a shuffler. `r` must be
3010 a random-access range with length.  If no RNG is specified, `rndGen`
3011 will be used.
3012 
3013 Params:
3014     r = random-access range whose elements are to be shuffled
3015     gen = (optional) random number generator to use; if not
3016           specified, defaults to `rndGen`
3017 Returns:
3018     The shuffled random-access range.
3019 */
3020 
3021 Range randomShuffle(Range, RandomGen)(Range r, ref RandomGen gen)
3022 if (isRandomAccessRange!Range && isUniformRNG!RandomGen)
3023 {
3024     import std.algorithm.mutation : swapAt;
3025     const n = r.length;
3026     foreach (i; 0 .. n)
3027     {
3028         r.swapAt(i, i + _uniformIndex(n - i, gen));
3029     }
3030     return r;
3031 }
3032 
3033 /// ditto
3034 Range randomShuffle(Range)(Range r)
3035 if (isRandomAccessRange!Range)
3036 {
3037     return randomShuffle(r, rndGen);
3038 }
3039 
3040 ///
3041 @safe unittest
3042 {
3043     auto rnd = MinstdRand0(42);
3044 
3045     auto arr = [1, 2, 3, 4, 5].randomShuffle(rnd);
3046     version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
3047     assert(arr == [3, 5, 2, 4, 1]);
3048 }
3049 
3050 @safe unittest
3051 {
3052     int[10] sa = void;
3053     int[10] sb = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
3054     import std.algorithm.sorting : sort;
3055     foreach (RandomGen; PseudoRngTypes)
3056     {
3057         sa[] = sb[];
3058         auto a = sa[];
3059         auto b = sb[];
3060         auto gen = RandomGen(123_456_789);
3061         randomShuffle(a, gen);
3062         sort(a);
3063         assert(a == b);
3064         randomShuffle(a);
3065         sort(a);
3066         assert(a == b);
3067     }
3068     // For backwards compatibility verify randomShuffle(r, gen)
3069     // is equivalent to partialShuffle(r, 0, r.length, gen).
3070     auto gen1 = Xorshift(123_456_789);
3071     auto gen2 = gen1.save();
3072     sa[] = sb[];
3073     // @nogc std.random.randomShuffle.
3074     // https://issues.dlang.org/show_bug.cgi?id=19156
3075     () @nogc nothrow pure { randomShuffle(sa[], gen1); }();
3076     partialShuffle(sb[], sb.length, gen2);
3077     assert(sa[] == sb[]);
3078 }
3079 
3080 // https://issues.dlang.org/show_bug.cgi?id=18501
3081 @safe unittest
3082 {
3083     import std.algorithm.comparison : among;
3084     auto r = randomShuffle([0,1]);
3085     assert(r.among([0,1],[1,0]));
3086 }
3087 
3088 /**
3089 Partially shuffles the elements of `r` such that upon returning $(D r[0 .. n])
3090 is a random subset of `r` and is randomly ordered.  $(D r[n .. r.length])
3091 will contain the elements not in $(D r[0 .. n]).  These will be in an undefined
3092 order, but will not be random in the sense that their order after
3093 `partialShuffle` returns will not be independent of their order before
3094 `partialShuffle` was called.
3095 
3096 `r` must be a random-access range with length.  `n` must be less than
3097 or equal to `r.length`.  If no RNG is specified, `rndGen` will be used.
3098 
3099 Params:
3100     r = random-access range whose elements are to be shuffled
3101     n = number of elements of `r` to shuffle (counting from the beginning);
3102         must be less than `r.length`
3103     gen = (optional) random number generator to use; if not
3104           specified, defaults to `rndGen`
3105 Returns:
3106     The shuffled random-access range.
3107 */
3108 Range partialShuffle(Range, RandomGen)(Range r, in size_t n, ref RandomGen gen)
3109 if (isRandomAccessRange!Range && isUniformRNG!RandomGen)
3110 {
3111     import std.algorithm.mutation : swapAt;
3112     import std.exception : enforce;
3113     enforce(n <= r.length, "n must be <= r.length for partialShuffle.");
3114     foreach (i; 0 .. n)
3115     {
3116         r.swapAt(i, uniform(i, r.length, gen));
3117     }
3118     return r;
3119 }
3120 
3121 /// ditto
3122 Range partialShuffle(Range)(Range r, in size_t n)
3123 if (isRandomAccessRange!Range)
3124 {
3125     return partialShuffle(r, n, rndGen);
3126 }
3127 
3128 ///
3129 @safe unittest
3130 {
3131     auto rnd = MinstdRand0(42);
3132 
3133     auto arr = [1, 2, 3, 4, 5, 6];
3134     arr = arr.dup.partialShuffle(1, rnd);
3135 
3136     version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
3137     assert(arr == [2, 1, 3, 4, 5, 6]); // 1<->2
3138 
3139     arr = arr.dup.partialShuffle(2, rnd);
3140     version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
3141     assert(arr == [1, 4, 3, 2, 5, 6]); // 1<->2, 2<->4
3142 
3143     arr = arr.dup.partialShuffle(3, rnd);
3144     version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
3145     assert(arr == [5, 4, 6, 2, 1, 3]); // 1<->5, 2<->4, 3<->6
3146 }
3147 
3148 @safe unittest
3149 {
3150     import std.algorithm;
3151     foreach (RandomGen; PseudoRngTypes)
3152     {
3153         auto a = [0, 1, 1, 2, 3];
3154         auto b = a.dup;
3155 
3156         // Pick a fixed seed so that the outcome of the statistical
3157         // test below is deterministic.
3158         auto gen = RandomGen(12345);
3159 
3160         // NUM times, pick LEN elements from the array at random.
3161         immutable int LEN = 2;
3162         immutable int NUM = 750;
3163         int[][] chk;
3164         foreach (step; 0 .. NUM)
3165         {
3166             partialShuffle(a, LEN, gen);
3167             chk ~= a[0 .. LEN].dup;
3168         }
3169 
3170         // Check that each possible a[0 .. LEN] was produced at least once.
3171         // For a perfectly random RandomGen, the probability that each
3172         // particular combination failed to appear would be at most
3173         // 0.95 ^^ NUM which is approximately 1,962e-17.
3174         // As long as hardware failure (e.g. bit flip) probability
3175         // is higher, we are fine with this unittest.
3176         sort(chk);
3177         assert(equal(uniq(chk), [       [0,1], [0,2], [0,3],
3178                                  [1,0], [1,1], [1,2], [1,3],
3179                                  [2,0], [2,1],        [2,3],
3180                                  [3,0], [3,1], [3,2],      ]));
3181 
3182         // Check that all the elements are still there.
3183         sort(a);
3184         assert(equal(a, b));
3185     }
3186 }
3187 
3188 /**
3189 Get a random index into a list of weights corresponding to each index
3190 
3191 Similar to rolling a die with relative probabilities stored in `proportions`.
3192 Returns the index in `proportions` that was chosen.
3193 
3194 Note:
3195     Usually, dice are 'fair', meaning that each side has equal probability
3196     to come up, in which case `1 + uniform(0, 6)` can simply be used.
3197     In future Phobos versions, this function might get renamed to something like
3198     `weightedChoice` to avoid confusion.
3199 
3200 Params:
3201     rnd = (optional) random number generator to use; if not
3202           specified, defaults to `rndGen`
3203     proportions = forward range or list of individual values
3204                   whose elements correspond to the probabilities
3205                   with which to choose the corresponding index
3206                   value
3207 
3208 Returns:
3209     Random variate drawn from the index values
3210     [0, ... `proportions.length` - 1], with the probability
3211     of getting an individual index value `i` being proportional to
3212     `proportions[i]`.
3213 */
3214 size_t dice(Rng, Num)(ref Rng rnd, Num[] proportions...)
3215 if (isNumeric!Num && isForwardRange!Rng)
3216 {
3217     return diceImpl(rnd, proportions);
3218 }
3219 
3220 /// Ditto
3221 size_t dice(R, Range)(ref R rnd, Range proportions)
3222 if (isForwardRange!Range && isNumeric!(ElementType!Range) && !isArray!Range)
3223 {
3224     return diceImpl(rnd, proportions);
3225 }
3226 
3227 /// Ditto
3228 size_t dice(Range)(Range proportions)
3229 if (isForwardRange!Range && isNumeric!(ElementType!Range) && !isArray!Range)
3230 {
3231     return diceImpl(rndGen, proportions);
3232 }
3233 
3234 /// Ditto
3235 size_t dice(Num)(Num[] proportions...)
3236 if (isNumeric!Num)
3237 {
3238     return diceImpl(rndGen, proportions);
3239 }
3240 
3241 ///
3242 @safe unittest
3243 {
3244     auto d6  = 1 + dice(1, 1, 1, 1, 1, 1); // fair dice roll
3245     auto d6b = 1 + dice(2, 1, 1, 1, 1, 1); // double the chance to roll '1'
3246 
3247     auto x = dice(0.5, 0.5);   // x is 0 or 1 in equal proportions
3248     auto y = dice(50, 50);     // y is 0 or 1 in equal proportions
3249     auto z = dice(70, 20, 10); // z is 0 70% of the time, 1 20% of the time,
3250                                // and 2 10% of the time
3251 }
3252 
3253 ///
3254 @safe unittest
3255 {
3256     auto rnd = MinstdRand0(42);
3257     auto z = rnd.dice(70, 20, 10);
3258     assert(z == 0);
3259     z = rnd.dice(30, 20, 40, 10);
3260     assert(z == 2);
3261 }
3262 
3263 private size_t diceImpl(Rng, Range)(ref Rng rng, scope Range proportions)
3264 if (isForwardRange!Range && isNumeric!(ElementType!Range) && isForwardRange!Rng)
3265 in
3266 {
3267     import std.algorithm.searching : all;
3268     assert(proportions.save.all!"a >= 0");
3269 }
3270 do
3271 {
3272     import std.algorithm.iteration : reduce;
3273     import std.exception : enforce;
3274     double sum = reduce!"a + b"(0.0, proportions.save);
3275     enforce(sum > 0, "Proportions in a dice cannot sum to zero");
3276     immutable point = uniform(0.0, sum, rng);
3277     assert(point < sum);
3278     auto mass = 0.0;
3279 
3280     size_t i = 0;
3281     foreach (e; proportions)
3282     {
3283         mass += e;
3284         if (point < mass) return i;
3285         i++;
3286     }
3287     // this point should not be reached
3288     assert(false);
3289 }
3290 
3291 ///
3292 @safe unittest
3293 {
3294     auto rnd = Xorshift(123_456_789);
3295     auto i = dice(rnd, 0.0, 100.0);
3296     assert(i == 1);
3297     i = dice(rnd, 100.0, 0.0);
3298     assert(i == 0);
3299 
3300     i = dice(100U, 0U);
3301     assert(i == 0);
3302 }
3303 
3304 /+ @nogc bool array designed for RandomCover.
3305 - constructed with an invariable length
3306 - small length means 0 alloc and bit field (if up to 32(x86) or 64(x64) choices to cover)
3307 - bigger length means non-GC heap allocation(s) and dealloc. +/
3308 private struct RandomCoverChoices
3309 {
3310     private size_t* buffer;
3311     private immutable size_t _length;
3312     private immutable bool hasPackedBits;
3313     private enum BITS_PER_WORD = typeof(buffer[0]).sizeof * 8;
3314 
3315     void opAssign(T)(T) @disable;
3316 
3317     this(this) pure nothrow @nogc @trusted
3318     {
3319         import core.stdc.string : memcpy;
3320         import std.internal.memory : enforceMalloc;
3321 
3322         if (!hasPackedBits && buffer !is null)
3323         {
3324             const nBytesToAlloc = size_t.sizeof * (_length / BITS_PER_WORD + int(_length % BITS_PER_WORD != 0));
3325             void* nbuffer = enforceMalloc(nBytesToAlloc);
3326             buffer = cast(size_t*) memcpy(nbuffer, buffer, nBytesToAlloc);
3327         }
3328     }
3329 
3330     this(size_t numChoices) pure nothrow @nogc @trusted
3331     {
3332         import std.internal.memory : enforceCalloc;
3333 
3334         _length = numChoices;
3335         hasPackedBits = _length <= size_t.sizeof * 8;
3336         if (!hasPackedBits)
3337         {
3338             const nWordsToAlloc = _length / BITS_PER_WORD + int(_length % BITS_PER_WORD != 0);
3339             buffer = cast(size_t*) enforceCalloc(nWordsToAlloc, BITS_PER_WORD / 8);
3340         }
3341     }
3342 
3343     size_t length() const pure nothrow @nogc @safe @property {return _length;}
3344 
3345     ~this() pure nothrow @nogc @trusted
3346     {
3347         import core.memory : pureFree;
3348 
3349         if (!hasPackedBits && buffer !is null)
3350             pureFree(buffer);
3351     }
3352 
3353     bool opIndex(size_t index) const pure nothrow @nogc @trusted
3354     {
3355         assert(index < _length);
3356         import core.bitop : bt;
3357         if (!hasPackedBits)
3358             return cast(bool) bt(buffer, index);
3359         else
3360             return ((cast(size_t) buffer) >> index) & size_t(1);
3361     }
3362 
3363     void opIndexAssign(bool value, size_t index) pure nothrow @nogc @trusted
3364     {
3365         assert(index < _length);
3366         if (!hasPackedBits)
3367         {
3368             import core.bitop : btr, bts;
3369             if (value)
3370                 bts(buffer, index);
3371             else
3372                 btr(buffer, index);
3373         }
3374         else
3375         {
3376             if (value)
3377                 (*cast(size_t*) &buffer) |= size_t(1) << index;
3378             else
3379                 (*cast(size_t*) &buffer) &= ~(size_t(1) << index);
3380         }
3381     }
3382 }
3383 
3384 @safe @nogc nothrow unittest
3385 {
3386     static immutable lengths = [3, 32, 65, 256];
3387     foreach (length; lengths)
3388     {
3389         RandomCoverChoices c = RandomCoverChoices(length);
3390         assert(c.hasPackedBits == (length <= size_t.sizeof * 8));
3391         c[0] = true;
3392         c[2] = true;
3393         assert(c[0]);
3394         assert(!c[1]);
3395         assert(c[2]);
3396         c[0] = false;
3397         c[1] = true;
3398         c[2] = false;
3399         assert(!c[0]);
3400         assert(c[1]);
3401         assert(!c[2]);
3402     }
3403 }
3404 
3405 /**
3406 Covers a given range `r` in a random manner, i.e. goes through each
3407 element of `r` once and only once, just in a random order. `r`
3408 must be a random-access range with length.
3409 
3410 If no random number generator is passed to `randomCover`, the
3411 thread-global RNG rndGen will be used internally.
3412 
3413 Params:
3414     r = random-access range to cover
3415     rng = (optional) random number generator to use;
3416           if not specified, defaults to `rndGen`
3417 
3418 Returns:
3419     Range whose elements consist of the elements of `r`,
3420     in random order.  Will be a forward range if both `r` and
3421     `rng` are forward ranges, an
3422     $(REF_ALTTEXT input range, isInputRange, std,range,primitives) otherwise.
3423 */
3424 struct RandomCover(Range, UniformRNG = void)
3425 if (isRandomAccessRange!Range && (isUniformRNG!UniformRNG || is(UniformRNG == void)))
3426 {
3427     private Range _input;
3428     private RandomCoverChoices _chosen;
3429     private size_t _current;
3430     private size_t _alreadyChosen = 0;
3431     private bool _isEmpty = false;
3432 
3433     static if (is(UniformRNG == void))
3434     {
3435         this(Range input)
3436         {
3437             _input = input;
3438             _chosen = RandomCoverChoices(_input.length);
3439             if (_input.empty)
3440             {
3441                 _isEmpty = true;
3442             }
3443             else
3444             {
3445                 _current = _uniformIndex(_chosen.length, rndGen);
3446             }
3447         }
3448     }
3449     else
3450     {
3451         private UniformRNG _rng;
3452 
3453         this(Range input, ref UniformRNG rng)
3454         {
3455             _input = input;
3456             _rng = rng;
3457             _chosen = RandomCoverChoices(_input.length);
3458             if (_input.empty)
3459             {
3460                 _isEmpty = true;
3461             }
3462             else
3463             {
3464                 _current = _uniformIndex(_chosen.length, rng);
3465             }
3466         }
3467 
3468         this(Range input, UniformRNG rng)
3469         {
3470             this(input, rng);
3471         }
3472     }
3473 
3474     static if (hasLength!Range)
3475     {
3476         @property size_t length()
3477         {
3478             return _input.length - _alreadyChosen;
3479         }
3480     }
3481 
3482     @property auto ref front()
3483     {
3484         assert(!_isEmpty);
3485         return _input[_current];
3486     }
3487 
3488     void popFront()
3489     {
3490         assert(!_isEmpty);
3491 
3492         size_t k = _input.length - _alreadyChosen - 1;
3493         if (k == 0)
3494         {
3495             _isEmpty = true;
3496             ++_alreadyChosen;
3497             return;
3498         }
3499 
3500         size_t i;
3501         foreach (e; _input)
3502         {
3503             if (_chosen[i] || i == _current) { ++i; continue; }
3504             // Roll a dice with k faces
3505             static if (is(UniformRNG == void))
3506             {
3507                 auto chooseMe = _uniformIndex(k, rndGen) == 0;
3508             }
3509             else
3510             {
3511                 auto chooseMe = _uniformIndex(k, _rng) == 0;
3512             }
3513             assert(k > 1 || chooseMe);
3514             if (chooseMe)
3515             {
3516                 _chosen[_current] = true;
3517                 _current = i;
3518                 ++_alreadyChosen;
3519                 return;
3520             }
3521             --k;
3522             ++i;
3523         }
3524     }
3525 
3526     static if (isForwardRange!UniformRNG)
3527     {
3528         @property typeof(this) save()
3529         {
3530             auto ret = this;
3531             ret._input = _input.save;
3532             ret._rng = _rng.save;
3533             return ret;
3534         }
3535     }
3536 
3537     @property bool empty() const { return _isEmpty; }
3538 }
3539 
3540 /// Ditto
3541 auto randomCover(Range, UniformRNG)(Range r, auto ref UniformRNG rng)
3542 if (isRandomAccessRange!Range && isUniformRNG!UniformRNG)
3543 {
3544     return RandomCover!(Range, UniformRNG)(r, rng);
3545 }
3546 
3547 /// Ditto
3548 auto randomCover(Range)(Range r)
3549 if (isRandomAccessRange!Range)
3550 {
3551     return RandomCover!(Range, void)(r);
3552 }
3553 
3554 ///
3555 @safe unittest
3556 {
3557     import std.algorithm.comparison : equal;
3558     import std.range : iota;
3559     auto rnd = MinstdRand0(42);
3560 
3561     version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
3562     assert(10.iota.randomCover(rnd).equal([7, 4, 2, 0, 1, 6, 8, 3, 9, 5]));
3563 }
3564 
3565 @safe unittest // cover RandomCoverChoices postblit for heap storage
3566 {
3567     import std.array : array;
3568     import std.range : iota;
3569     auto a = 1337.iota.randomCover().array;
3570     assert(a.length == 1337);
3571 }
3572 
3573 @nogc nothrow pure @safe unittest
3574 {
3575     // Optionally @nogc std.random.randomCover
3576     // https://issues.dlang.org/show_bug.cgi?id=14001
3577     auto rng = Xorshift(123_456_789);
3578     static immutable int[] sa = [1, 2, 3, 4, 5];
3579     auto r = randomCover(sa, rng);
3580     assert(!r.empty);
3581     const x = r.front;
3582     r.popFront();
3583     assert(!r.empty);
3584     const y = r.front;
3585     assert(x != y);
3586 }
3587 
3588 @safe unittest
3589 {
3590     import std.algorithm;
3591     import std.conv;
3592     int[] a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ];
3593     int[] c;
3594     static foreach (UniformRNG; std.meta.AliasSeq!(void, PseudoRngTypes))
3595     {{
3596         static if (is(UniformRNG == void))
3597         {
3598             auto rc = randomCover(a);
3599             static assert(isInputRange!(typeof(rc)));
3600             static assert(!isForwardRange!(typeof(rc)));
3601         }
3602         else
3603         {
3604             auto rng = UniformRNG(123_456_789);
3605             auto rc = randomCover(a, rng);
3606             static assert(isForwardRange!(typeof(rc)));
3607             // check for constructor passed a value-type RNG
3608             auto rc2 = RandomCover!(int[], UniformRNG)(a, UniformRNG(987_654_321));
3609             static assert(isForwardRange!(typeof(rc2)));
3610             auto rcEmpty = randomCover(c, rng);
3611             assert(rcEmpty.length == 0);
3612         }
3613 
3614         int[] b = new int[9];
3615         uint i;
3616         foreach (e; rc)
3617         {
3618             //writeln(e);
3619             b[i++] = e;
3620         }
3621         sort(b);
3622         assert(a == b, text(b));
3623     }}
3624 }
3625 
3626 @safe unittest
3627 {
3628     // https://issues.dlang.org/show_bug.cgi?id=12589
3629     int[] r = [];
3630     auto rc = randomCover(r);
3631     assert(rc.length == 0);
3632     assert(rc.empty);
3633 
3634     // https://issues.dlang.org/show_bug.cgi?id=16724
3635     import std.range : iota;
3636     auto range = iota(10);
3637     auto randy = range.randomCover;
3638 
3639     for (int i=1; i <= range.length; i++)
3640     {
3641         randy.popFront;
3642         assert(randy.length == range.length - i);
3643     }
3644 }
3645 
3646 // RandomSample
3647 /**
3648 Selects a random subsample out of `r`, containing exactly `n`
3649 elements. The order of elements is the same as in the original
3650 range. The total length of `r` must be known. If `total` is
3651 passed in, the total number of sample is considered to be $(D
3652 total). Otherwise, `RandomSample` uses `r.length`.
3653 
3654 Params:
3655     r = range to sample from
3656     n = number of elements to include in the sample;
3657         must be less than or equal to the total number
3658         of elements in `r` and/or the parameter
3659         `total` (if provided)
3660     total = (semi-optional) number of elements of `r`
3661             from which to select the sample (counting from
3662             the beginning); must be less than or equal to
3663             the total number of elements in `r` itself.
3664             May be omitted if `r` has the `.length`
3665             property and the sample is to be drawn from
3666             all elements of `r`.
3667     rng = (optional) random number generator to use;
3668           if not specified, defaults to `rndGen`
3669 
3670 Returns:
3671     Range whose elements consist of a randomly selected subset of
3672     the elements of `r`, in the same order as these elements
3673     appear in `r` itself.  Will be a forward range if both `r`
3674     and `rng` are forward ranges, an input range otherwise.
3675 
3676 `RandomSample` implements Jeffrey Scott Vitter's Algorithm D
3677 (see Vitter $(HTTP dx.doi.org/10.1145/358105.893, 1984), $(HTTP
3678 dx.doi.org/10.1145/23002.23003, 1987)), which selects a sample
3679 of size `n` in O(n) steps and requiring O(n) random variates,
3680 regardless of the size of the data being sampled.  The exception
3681 to this is if traversing k elements on the input range is itself
3682 an O(k) operation (e.g. when sampling lines from an input file),
3683 in which case the sampling calculation will inevitably be of
3684 O(total).
3685 
3686 RandomSample will throw an exception if `total` is verifiably
3687 less than the total number of elements available in the input,
3688 or if $(D n > total).
3689 
3690 If no random number generator is passed to `randomSample`, the
3691 thread-global RNG rndGen will be used internally.
3692 */
3693 struct RandomSample(Range, UniformRNG = void)
3694 if (isInputRange!Range && (isUniformRNG!UniformRNG || is(UniformRNG == void)))
3695 {
3696     private size_t _available, _toSelect;
3697     private enum ushort _alphaInverse = 13; // Vitter's recommended value.
3698     private double _Vprime;
3699     private Range _input;
3700     private size_t _index;
3701     private enum Skip { None, A, D }
3702     private Skip _skip = Skip.None;
3703 
3704     // If we're using the default thread-local random number generator then
3705     // we shouldn't store a copy of it here.  UniformRNG == void is a sentinel
3706     // for this.  If we're using a user-specified generator then we have no
3707     // choice but to store a copy.
3708     static if (is(UniformRNG == void))
3709     {
3710         static if (hasLength!Range)
3711         {
3712             this(Range input, size_t howMany)
3713             {
3714                 _input = input;
3715                 initialize(howMany, input.length);
3716             }
3717         }
3718 
3719         this(Range input, size_t howMany, size_t total)
3720         {
3721             _input = input;
3722             initialize(howMany, total);
3723         }
3724     }
3725     else
3726     {
3727         UniformRNG _rng;
3728 
3729         static if (hasLength!Range)
3730         {
3731             this(Range input, size_t howMany, ref scope UniformRNG rng)
3732             {
3733                 _rng = rng;
3734                 _input = input;
3735                 initialize(howMany, input.length);
3736             }
3737 
3738             this(Range input, size_t howMany, UniformRNG rng)
3739             {
3740                 this(input, howMany, rng);
3741             }
3742         }
3743 
3744         this(Range input, size_t howMany, size_t total, ref scope UniformRNG rng)
3745         {
3746             _rng = rng;
3747             _input = input;
3748             initialize(howMany, total);
3749         }
3750 
3751         this(Range input, size_t howMany, size_t total, UniformRNG rng)
3752         {
3753             this(input, howMany, total, rng);
3754         }
3755     }
3756 
3757     private void initialize(size_t howMany, size_t total)
3758     {
3759         import std.conv : text;
3760         import std.exception : enforce;
3761         _available = total;
3762         _toSelect = howMany;
3763         enforce(_toSelect <= _available,
3764                 text("RandomSample: cannot sample ", _toSelect,
3765                      " items when only ", _available, " are available"));
3766         static if (hasLength!Range)
3767         {
3768             enforce(_available <= _input.length,
3769                     text("RandomSample: specified ", _available,
3770                          " items as available when input contains only ",
3771                          _input.length));
3772         }
3773     }
3774 
3775     private void initializeFront()
3776     {
3777         assert(_skip == Skip.None);
3778         // We can save ourselves a random variate by checking right
3779         // at the beginning if we should use Algorithm A.
3780         if ((_alphaInverse * _toSelect) > _available)
3781         {
3782             _skip = Skip.A;
3783         }
3784         else
3785         {
3786             _skip = Skip.D;
3787             _Vprime = newVprime(_toSelect);
3788         }
3789         prime();
3790     }
3791 
3792 /**
3793    Range primitives.
3794 */
3795     @property bool empty() const
3796     {
3797         return _toSelect == 0;
3798     }
3799 
3800 /// Ditto
3801     @property auto ref front()
3802     {
3803         assert(!empty);
3804         // The first sample point must be determined here to avoid
3805         // having it always correspond to the first element of the
3806         // input.  The rest of the sample points are determined each
3807         // time we call popFront().
3808         if (_skip == Skip.None)
3809         {
3810             initializeFront();
3811         }
3812         return _input.front;
3813     }
3814 
3815 /// Ditto
3816     void popFront()
3817     {
3818         // First we need to check if the sample has
3819         // been initialized in the first place.
3820         if (_skip == Skip.None)
3821         {
3822             initializeFront();
3823         }
3824 
3825         _input.popFront();
3826         --_available;
3827         --_toSelect;
3828         ++_index;
3829         prime();
3830     }
3831 
3832 /// Ditto
3833     static if (isForwardRange!Range && isForwardRange!UniformRNG)
3834     {
3835         static if (is(typeof(((const UniformRNG* p) => (*p).save)(null)) : UniformRNG)
3836             && is(typeof(((const Range* p) => (*p).save)(null)) : Range))
3837         {
3838             @property typeof(this) save() const
3839             {
3840                 auto ret = RandomSample.init;
3841                 foreach (fieldIndex, ref val; this.tupleof)
3842                 {
3843                     static if (is(typeof(val) == const(Range)) || is(typeof(val) == const(UniformRNG)))
3844                         ret.tupleof[fieldIndex] = val.save;
3845                     else
3846                         ret.tupleof[fieldIndex] = val;
3847                 }
3848                 return ret;
3849             }
3850         }
3851         else
3852         {
3853             @property typeof(this) save()
3854             {
3855                 auto ret = this;
3856                 ret._input = _input.save;
3857                 ret._rng = _rng.save;
3858                 return ret;
3859             }
3860         }
3861     }
3862 
3863 /// Ditto
3864     @property size_t length() const
3865     {
3866         return _toSelect;
3867     }
3868 
3869 /**
3870 Returns the index of the visited record.
3871  */
3872     @property size_t index()
3873     {
3874         if (_skip == Skip.None)
3875         {
3876             initializeFront();
3877         }
3878         return _index;
3879     }
3880 
3881     private size_t skip()
3882     {
3883         assert(_skip != Skip.None);
3884 
3885         // Step D1: if the number of points still to select is greater
3886         // than a certain proportion of the remaining data points, i.e.
3887         // if n >= alpha * N where alpha = 1/13, we carry out the
3888         // sampling with Algorithm A.
3889         if (_skip == Skip.A)
3890         {
3891             return skipA();
3892         }
3893         else if ((_alphaInverse * _toSelect) > _available)
3894         {
3895             // We shouldn't get here unless the current selected
3896             // algorithm is D.
3897             assert(_skip == Skip.D);
3898             _skip = Skip.A;
3899             return skipA();
3900         }
3901         else
3902         {
3903             assert(_skip == Skip.D);
3904             return skipD();
3905         }
3906     }
3907 
3908 /*
3909 Vitter's Algorithm A, used when the ratio of needed sample values
3910 to remaining data values is sufficiently large.
3911 */
3912     private size_t skipA()
3913     {
3914         size_t s;
3915         double v, quot, top;
3916 
3917         if (_toSelect == 1)
3918         {
3919             static if (is(UniformRNG == void))
3920             {
3921                 s = uniform(0, _available);
3922             }
3923             else
3924             {
3925                 s = uniform(0, _available, _rng);
3926             }
3927         }
3928         else
3929         {
3930             v = 0;
3931             top = _available - _toSelect;
3932             quot = top / _available;
3933 
3934             static if (is(UniformRNG == void))
3935             {
3936                 v = uniform!"()"(0.0, 1.0);
3937             }
3938             else
3939             {
3940                 v = uniform!"()"(0.0, 1.0, _rng);
3941             }
3942 
3943             while (quot > v)
3944             {
3945                 ++s;
3946                 quot *= (top - s) / (_available - s);
3947             }
3948         }
3949 
3950         return s;
3951     }
3952 
3953 /*
3954 Randomly reset the value of _Vprime.
3955 */
3956     private double newVprime(size_t remaining)
3957     {
3958         static if (is(UniformRNG == void))
3959         {
3960             double r = uniform!"()"(0.0, 1.0);
3961         }
3962         else
3963         {
3964             double r = uniform!"()"(0.0, 1.0, _rng);
3965         }
3966 
3967         return r ^^ (1.0 / remaining);
3968     }
3969 
3970 /*
3971 Vitter's Algorithm D.  For an extensive description of the algorithm
3972 and its rationale, see:
3973 
3974   * Vitter, J.S. (1984), "Faster methods for random sampling",
3975     Commun. ACM 27(7): 703--718
3976 
3977   * Vitter, J.S. (1987) "An efficient algorithm for sequential random
3978     sampling", ACM Trans. Math. Softw. 13(1): 58-67.
3979 
3980 Variable names are chosen to match those in Vitter's paper.
3981 */
3982     private size_t skipD()
3983     {
3984         import std.math.traits : isNaN;
3985         import std.math.rounding : trunc;
3986         // Confirm that the check in Step D1 is valid and we
3987         // haven't been sent here by mistake
3988         assert((_alphaInverse * _toSelect) <= _available);
3989 
3990         // Now it's safe to use the standard Algorithm D mechanism.
3991         if (_toSelect > 1)
3992         {
3993             size_t s;
3994             size_t qu1 = 1 + _available - _toSelect;
3995             double x, y1;
3996 
3997             assert(!_Vprime.isNaN());
3998 
3999             while (true)
4000             {
4001                 // Step D2: set values of x and u.
4002                 while (1)
4003                 {
4004                     x = _available * (1-_Vprime);
4005                     s = cast(size_t) trunc(x);
4006                     if (s < qu1)
4007                         break;
4008                     _Vprime = newVprime(_toSelect);
4009                 }
4010 
4011                 static if (is(UniformRNG == void))
4012                 {
4013                     double u = uniform!"()"(0.0, 1.0);
4014                 }
4015                 else
4016                 {
4017                     double u = uniform!"()"(0.0, 1.0, _rng);
4018                 }
4019 
4020                 y1 = (u * (cast(double) _available) / qu1) ^^ (1.0/(_toSelect - 1));
4021 
4022                 _Vprime = y1 * ((-x/_available)+1.0) * ( qu1/( (cast(double) qu1) - s ) );
4023 
4024                 // Step D3: if _Vprime <= 1.0 our work is done and we return S.
4025                 // Otherwise ...
4026                 if (_Vprime > 1.0)
4027                 {
4028                     size_t top = _available - 1, limit;
4029                     double y2 = 1.0, bottom;
4030 
4031                     if (_toSelect > (s+1))
4032                     {
4033                         bottom = _available - _toSelect;
4034                         limit = _available - s;
4035                     }
4036                     else
4037                     {
4038                         bottom = _available - (s+1);
4039                         limit = qu1;
4040                     }
4041 
4042                     foreach (size_t t; limit .. _available)
4043                     {
4044                         y2 *= top/bottom;
4045                         top--;
4046                         bottom--;
4047                     }
4048 
4049                     // Step D4: decide whether or not to accept the current value of S.
4050                     if (_available/(_available-x) < y1 * (y2 ^^ (1.0/(_toSelect-1))))
4051                     {
4052                         // If it's not acceptable, we generate a new value of _Vprime
4053                         // and go back to the start of the for (;;) loop.
4054                         _Vprime = newVprime(_toSelect);
4055                     }
4056                     else
4057                     {
4058                         // If it's acceptable we generate a new value of _Vprime
4059                         // based on the remaining number of sample points needed,
4060                         // and return S.
4061                         _Vprime = newVprime(_toSelect-1);
4062                         return s;
4063                     }
4064                 }
4065                 else
4066                 {
4067                     // Return if condition D3 satisfied.
4068                     return s;
4069                 }
4070             }
4071         }
4072         else
4073         {
4074             // If only one sample point remains to be taken ...
4075             return cast(size_t) trunc(_available * _Vprime);
4076         }
4077     }
4078 
4079     private void prime()
4080     {
4081         if (empty)
4082         {
4083             return;
4084         }
4085         assert(_available && _available >= _toSelect);
4086         immutable size_t s = skip();
4087         assert(s + _toSelect <= _available);
4088         static if (hasLength!Range)
4089         {
4090             assert(s + _toSelect <= _input.length);
4091         }
4092         assert(!_input.empty);
4093         _input.popFrontExactly(s);
4094         _index += s;
4095         _available -= s;
4096         assert(_available > 0);
4097     }
4098 }
4099 
4100 /// Ditto
4101 auto randomSample(Range)(Range r, size_t n, size_t total)
4102 if (isInputRange!Range)
4103 {
4104     return RandomSample!(Range, void)(r, n, total);
4105 }
4106 
4107 /// Ditto
4108 auto randomSample(Range)(Range r, size_t n)
4109 if (isInputRange!Range && hasLength!Range)
4110 {
4111     return RandomSample!(Range, void)(r, n, r.length);
4112 }
4113 
4114 /// Ditto
4115 auto randomSample(Range, UniformRNG)(Range r, size_t n, size_t total, auto ref UniformRNG rng)
4116 if (isInputRange!Range && isUniformRNG!UniformRNG)
4117 {
4118     return RandomSample!(Range, UniformRNG)(r, n, total, rng);
4119 }
4120 
4121 /// Ditto
4122 auto randomSample(Range, UniformRNG)(Range r, size_t n, auto ref UniformRNG rng)
4123 if (isInputRange!Range && hasLength!Range && isUniformRNG!UniformRNG)
4124 {
4125     return RandomSample!(Range, UniformRNG)(r, n, r.length, rng);
4126 }
4127 
4128 ///
4129 @safe unittest
4130 {
4131     import std.algorithm.comparison : equal;
4132     import std.range : iota;
4133     auto rnd = MinstdRand0(42);
4134     assert(10.iota.randomSample(3, rnd).equal([7, 8, 9]));
4135 }
4136 
4137 @system unittest
4138 {
4139     // @system because it takes the address of a local
4140     import std.conv : text;
4141     import std.exception;
4142     import std.range;
4143     // For test purposes, an infinite input range
4144     struct TestInputRange
4145     {
4146         private auto r = recurrence!"a[n-1] + 1"(0);
4147         bool empty() @property const pure nothrow { return r.empty; }
4148         auto front() @property pure nothrow { return r.front; }
4149         void popFront() pure nothrow { r.popFront(); }
4150     }
4151     static assert(isInputRange!TestInputRange);
4152     static assert(!isForwardRange!TestInputRange);
4153 
4154     const(int)[] a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ];
4155 
4156     foreach (UniformRNG; PseudoRngTypes)
4157     (){ // avoid workaround optimizations for large functions
4158         // https://issues.dlang.org/show_bug.cgi?id=2396
4159         auto rng = UniformRNG(1234);
4160         /* First test the most general case: randomSample of input range, with and
4161          * without a specified random number generator.
4162          */
4163         static assert(isInputRange!(typeof(randomSample(TestInputRange(), 5, 10))));
4164         static assert(isInputRange!(typeof(randomSample(TestInputRange(), 5, 10, rng))));
4165         static assert(!isForwardRange!(typeof(randomSample(TestInputRange(), 5, 10))));
4166         static assert(!isForwardRange!(typeof(randomSample(TestInputRange(), 5, 10, rng))));
4167         // test case with range initialized by direct call to struct
4168         {
4169             auto sample =
4170                 RandomSample!(TestInputRange, UniformRNG)
4171                              (TestInputRange(), 5, 10, UniformRNG(987_654_321));
4172             static assert(isInputRange!(typeof(sample)));
4173             static assert(!isForwardRange!(typeof(sample)));
4174         }
4175 
4176         /* Now test the case of an input range with length.  We ignore the cases
4177          * already covered by the previous tests.
4178          */
4179         static assert(isInputRange!(typeof(randomSample(TestInputRange().takeExactly(10), 5))));
4180         static assert(isInputRange!(typeof(randomSample(TestInputRange().takeExactly(10), 5, rng))));
4181         static assert(!isForwardRange!(typeof(randomSample(TestInputRange().takeExactly(10), 5))));
4182         static assert(!isForwardRange!(typeof(randomSample(TestInputRange().takeExactly(10), 5, rng))));
4183         // test case with range initialized by direct call to struct
4184         {
4185             auto sample =
4186                 RandomSample!(typeof(TestInputRange().takeExactly(10)), UniformRNG)
4187                              (TestInputRange().takeExactly(10), 5, 10, UniformRNG(654_321_987));
4188             static assert(isInputRange!(typeof(sample)));
4189             static assert(!isForwardRange!(typeof(sample)));
4190         }
4191 
4192         // Now test the case of providing a forward range as input.
4193         static assert(!isForwardRange!(typeof(randomSample(a, 5))));
4194         static if (isForwardRange!UniformRNG)
4195         {
4196             static assert(isForwardRange!(typeof(randomSample(a, 5, rng))));
4197             // ... and test with range initialized directly
4198             {
4199                 auto sample =
4200                     RandomSample!(const(int)[], UniformRNG)
4201                                  (a, 5, UniformRNG(321_987_654));
4202                 static assert(isForwardRange!(typeof(sample)));
4203             }
4204         }
4205         else
4206         {
4207             static assert(isInputRange!(typeof(randomSample(a, 5, rng))));
4208             static assert(!isForwardRange!(typeof(randomSample(a, 5, rng))));
4209             // ... and test with range initialized directly
4210             {
4211                 auto sample =
4212                     RandomSample!(const(int)[], UniformRNG)
4213                                  (a, 5, UniformRNG(789_123_456));
4214                 static assert(isInputRange!(typeof(sample)));
4215                 static assert(!isForwardRange!(typeof(sample)));
4216             }
4217         }
4218 
4219         /* Check that randomSample will throw an error if we claim more
4220          * items are available than there actually are, or if we try to
4221          * sample more items than are available. */
4222         assert(collectExceptionMsg(
4223             randomSample(a, 5, 15)
4224         ) == "RandomSample: specified 15 items as available when input contains only 10");
4225         assert(collectExceptionMsg(
4226             randomSample(a, 15)
4227         ) == "RandomSample: cannot sample 15 items when only 10 are available");
4228         assert(collectExceptionMsg(
4229             randomSample(a, 9, 8)
4230         ) == "RandomSample: cannot sample 9 items when only 8 are available");
4231         assert(collectExceptionMsg(
4232             randomSample(TestInputRange(), 12, 11)
4233         ) == "RandomSample: cannot sample 12 items when only 11 are available");
4234 
4235         /* Check that sampling algorithm never accidentally overruns the end of
4236          * the input range.  If input is an InputRange without .length, this
4237          * relies on the user specifying the total number of available items
4238          * correctly.
4239          */
4240         {
4241             uint i = 0;
4242             foreach (e; randomSample(a, a.length))
4243             {
4244                 assert(e == i);
4245                 ++i;
4246             }
4247             assert(i == a.length);
4248 
4249             i = 0;
4250             foreach (e; randomSample(TestInputRange(), 17, 17))
4251             {
4252                 assert(e == i);
4253                 ++i;
4254             }
4255             assert(i == 17);
4256         }
4257 
4258 
4259         // Check length properties of random samples.
4260         assert(randomSample(a, 5).length == 5);
4261         assert(randomSample(a, 5, 10).length == 5);
4262         assert(randomSample(a, 5, rng).length == 5);
4263         assert(randomSample(a, 5, 10, rng).length == 5);
4264         assert(randomSample(TestInputRange(), 5, 10).length == 5);
4265         assert(randomSample(TestInputRange(), 5, 10, rng).length == 5);
4266 
4267         // ... and emptiness!
4268         assert(randomSample(a, 0).empty);
4269         assert(randomSample(a, 0, 5).empty);
4270         assert(randomSample(a, 0, rng).empty);
4271         assert(randomSample(a, 0, 5, rng).empty);
4272         assert(randomSample(TestInputRange(), 0, 10).empty);
4273         assert(randomSample(TestInputRange(), 0, 10, rng).empty);
4274 
4275         /* Test that the (lazy) evaluation of random samples works correctly.
4276          *
4277          * We cover 2 different cases: a sample where the ratio of sample points
4278          * to total points is greater than the threshold for using Algorithm, and
4279          * one where the ratio is small enough (< 1/13) for Algorithm D to be used.
4280          *
4281          * For each, we also cover the case with and without a specified RNG.
4282          */
4283         {
4284             // Small sample/source ratio, no specified RNG.
4285             uint i = 0;
4286             foreach (e; randomSample(randomCover(a), 5))
4287             {
4288                 ++i;
4289             }
4290             assert(i == 5);
4291 
4292             // Small sample/source ratio, specified RNG.
4293             i = 0;
4294             foreach (e; randomSample(randomCover(a), 5, rng))
4295             {
4296                 ++i;
4297             }
4298             assert(i == 5);
4299 
4300             // Large sample/source ratio, no specified RNG.
4301             i = 0;
4302             foreach (e; randomSample(TestInputRange(), 123, 123_456))
4303             {
4304                 ++i;
4305             }
4306             assert(i == 123);
4307 
4308             // Large sample/source ratio, specified RNG.
4309             i = 0;
4310             foreach (e; randomSample(TestInputRange(), 123, 123_456, rng))
4311             {
4312                 ++i;
4313             }
4314             assert(i == 123);
4315 
4316             /* Sample/source ratio large enough to start with Algorithm D,
4317              * small enough to switch to Algorithm A.
4318              */
4319             i = 0;
4320             foreach (e; randomSample(TestInputRange(), 10, 131))
4321             {
4322                 ++i;
4323             }
4324             assert(i == 10);
4325         }
4326 
4327         // Test that the .index property works correctly
4328         {
4329             auto sample1 = randomSample(TestInputRange(), 654, 654_321);
4330             for (; !sample1.empty; sample1.popFront())
4331             {
4332                 assert(sample1.front == sample1.index);
4333             }
4334 
4335             auto sample2 = randomSample(TestInputRange(), 654, 654_321, rng);
4336             for (; !sample2.empty; sample2.popFront())
4337             {
4338                 assert(sample2.front == sample2.index);
4339             }
4340 
4341             /* Check that it also works if .index is called before .front.
4342              * See: https://issues.dlang.org/show_bug.cgi?id=10322
4343              */
4344             auto sample3 = randomSample(TestInputRange(), 654, 654_321);
4345             for (; !sample3.empty; sample3.popFront())
4346             {
4347                 assert(sample3.index == sample3.front);
4348             }
4349 
4350             auto sample4 = randomSample(TestInputRange(), 654, 654_321, rng);
4351             for (; !sample4.empty; sample4.popFront())
4352             {
4353                 assert(sample4.index == sample4.front);
4354             }
4355         }
4356 
4357         /* Test behaviour if .popFront() is called before sample is read.
4358          * This is a rough-and-ready check that the statistical properties
4359          * are in the ballpark -- not a proper validation of statistical
4360          * quality!  This incidentally also checks for reference-type
4361          * initialization bugs, as the foreach () loop will operate on a
4362          * copy of the popFronted (and hence initialized) sample.
4363          */
4364         {
4365             size_t count0, count1, count99;
4366             foreach (_; 0 .. 50_000)
4367             {
4368                 auto sample = randomSample(iota(100), 5, &rng);
4369                 sample.popFront();
4370                 foreach (s; sample)
4371                 {
4372                     if (s == 0)
4373                     {
4374                         ++count0;
4375                     }
4376                     else if (s == 1)
4377                     {
4378                         ++count1;
4379                     }
4380                     else if (s == 99)
4381                     {
4382                         ++count99;
4383                     }
4384                 }
4385             }
4386             /* Statistical assumptions here: this is a sequential sampling process
4387              * so (i) 0 can only be the first sample point, so _can't_ be in the
4388              * remainder of the sample after .popFront() is called. (ii) By similar
4389              * token, 1 can only be in the remainder if it's the 2nd point of the
4390              * whole sample, and hence if 0 was the first; probability of 0 being
4391              * first and 1 second is 5/100 * 4/99 (thank you, Algorithm S:-) and
4392              * so the mean count of 1 should be about 202.  Finally, 99 can only
4393              * be the _last_ sample point to be picked, so its probability of
4394              * inclusion should be independent of the .popFront() and it should
4395              * occur with frequency 5/100, hence its count should be about 5000.
4396              * Unfortunately we have to set quite a high tolerance because with
4397              * sample size small enough for unittests to run in reasonable time,
4398              * the variance can be quite high.
4399              */
4400             assert(count0 == 0);
4401             assert(count1 < 150, text("1: ", count1, " > 150."));
4402             assert(2_200 < count99, text("99: ", count99, " < 2200."));
4403             assert(count99 < 2_800, text("99: ", count99, " > 2800."));
4404         }
4405 
4406         /* Odd corner-cases: RandomSample has 2 constructors that are not called
4407          * by the randomSample() helper functions, but that can be used if the
4408          * constructor is called directly.  These cover the case of the user
4409          * specifying input but not input length.
4410          */
4411         {
4412             auto input1 = TestInputRange().takeExactly(456_789);
4413             static assert(hasLength!(typeof(input1)));
4414             auto sample1 = RandomSample!(typeof(input1), void)(input1, 789);
4415             static assert(isInputRange!(typeof(sample1)));
4416             static assert(!isForwardRange!(typeof(sample1)));
4417             assert(sample1.length == 789);
4418             assert(sample1._available == 456_789);
4419             uint i = 0;
4420             for (; !sample1.empty; sample1.popFront())
4421             {
4422                 assert(sample1.front == sample1.index);
4423                 ++i;
4424             }
4425             assert(i == 789);
4426 
4427             auto input2 = TestInputRange().takeExactly(456_789);
4428             static assert(hasLength!(typeof(input2)));
4429             auto sample2 = RandomSample!(typeof(input2), typeof(rng))(input2, 789, rng);
4430             static assert(isInputRange!(typeof(sample2)));
4431             static assert(!isForwardRange!(typeof(sample2)));
4432             assert(sample2.length == 789);
4433             assert(sample2._available == 456_789);
4434             i = 0;
4435             for (; !sample2.empty; sample2.popFront())
4436             {
4437                 assert(sample2.front == sample2.index);
4438                 ++i;
4439             }
4440             assert(i == 789);
4441         }
4442 
4443         /* Test that the save property works where input is a forward range,
4444          * and RandomSample is using a (forward range) random number generator
4445          * that is not rndGen.
4446          */
4447         static if (isForwardRange!UniformRNG)
4448         {
4449             auto sample1 = randomSample(a, 5, rng);
4450             // https://issues.dlang.org/show_bug.cgi?id=15853
4451             auto sample2 = ((const ref typeof(sample1) a) => a.save)(sample1);
4452             assert(sample1.array() == sample2.array());
4453         }
4454 
4455         // https://issues.dlang.org/show_bug.cgi?id=8314
4456         {
4457             auto sample(RandomGen)(uint seed) { return randomSample(a, 1, RandomGen(seed)).front; }
4458 
4459             // Start from 1 because not all RNGs accept 0 as seed.
4460             immutable fst = sample!UniformRNG(1);
4461             uint n = 1;
4462             while (sample!UniformRNG(++n) == fst && n < n.max) {}
4463             assert(n < n.max);
4464         }
4465     }();
4466 }