@@ -11,6 +11,7 @@ import mir.math.common;
1111
1212import mir.random;
1313public import mir.random.engine;
14+ import mir.random.variable: isRandomVariable;
1415
1516private enum bool isPassByRef(P) = ! is (P == struct ) && ! is (P == union ) && ! isPointer! P && ! isScalarType! P
1617 && (isFunction! P || isDelegate! P || is (P == class ) || is (P == interface ));
@@ -140,28 +141,28 @@ struct RandomField(alias gen)
140141
141142// / ditto
142143RandomField! (G, D, T) field(T, G, D)(ref G gen, D var)
143- if (isReferenceToSaturatedRandomEngine! G)
144+ if (isReferenceToSaturatedRandomEngine! G && isRandomVariable ! D )
144145{
145146 return typeof (return )(gen, var);
146147}
147148
148149// / ditto
149150RandomField! (gen, D, T) field(alias gen, D, T)(D var)
150- if (isSaturatedRandomEngine! (typeof (gen)))
151+ if (isSaturatedRandomEngine! (typeof (gen)) && isRandomVariable ! D )
151152{
152153 return RandomField! (gen,D,T)(var);
153154}
154155
155156// / ditto
156157auto field (G, D)(ref G gen, D var)
157- if (isReferenceToSaturatedRandomEngine! G)
158+ if (isReferenceToSaturatedRandomEngine! G && isRandomVariable ! D )
158159{
159160 return RandomField! (G, D, Unqual! (typeof (var(deref(gen)))))(gen, var);
160161}
161162
162163// / ditto
163164auto field (alias gen, D)(D var)
164- if (isSaturatedRandomEngine! (typeof (gen)))
165+ if (isSaturatedRandomEngine! (typeof (gen)) && isRandomVariable ! D )
165166{
166167 return RandomField! (gen,D,Unqual! (typeof (var(gen))))(var);
167168}
@@ -268,7 +269,7 @@ Range interface for random distributions and uniform random bit generators.
268269Note: $(UL $(LI The structure holds a pointer to a generator.) $(LI The structure must not be copied (explicitly or implicitly) outside from a function.))
269270+/
270271struct RandomRange (G, D)
271- if (isReferenceToSaturatedRandomEngine! G)
272+ if (isReferenceToSaturatedRandomEngine! G && isRandomVariable ! D )
272273{
273274 private D _var;
274275 private G _gen;
@@ -288,7 +289,7 @@ struct RandomRange(G, D)
288289
289290// / ditto
290291struct RandomRange (alias gen, D)
291- if (isSaturatedRandomEngine! (typeof (gen)))
292+ if (isSaturatedRandomEngine! (typeof (gen)) && isRandomVariable!D )
292293{
293294 private D _var;
294295 private Unqual! (typeof (_var(gen))) _val;
@@ -364,21 +365,21 @@ struct RandomRange(alias gen)
364365}
365366
366367// / ditto
367- RandomRange! (G, D) range(G, D)(ref G gen, D var)
368- if (isReferenceToSaturatedRandomEngine! G)
368+ RandomRange! (G, D) range(G, D)(G gen, D var)
369+ if (isReferenceToSaturatedRandomEngine! G && isRandomVariable ! D )
369370{
370371 return typeof (return )(gen, var);
371372}
372373
373374// / ditto
374- RandomRange! (gen, D) range(alias gen, D)(D var)
375- if (isSaturatedRandomEngine! (typeof (gen)))
375+ RandomRange! (gen, D) range(alias gen = rne , D)(D var)
376+ if (isSaturatedRandomEngine! (typeof (gen)) && isRandomVariable ! D )
376377{
377378 return typeof (return )(var);
378379}
379380
380381// / ditto
381- RandomRange! G range (G)(ref G gen)
382+ RandomRange! G range (G)(G gen)
382383 if (isReferenceToSaturatedRandomEngine! G)
383384{
384385 return typeof (return )(gen);
@@ -743,17 +744,30 @@ void shuffle(Range, G)(scope ref G gen, scope Range range)
743744 }
744745}
745746
747+ // / ditto
748+ void shuffle (Range , G)(scope G* gen, scope Range range)
749+ if (isSaturatedRandomEngine! G && isRandomAccessRange! Range && hasLength! Range )
750+ {
751+ return .shuffle(* gen, range);
752+ }
753+
754+ // / ditto
755+ void shuffle (Range )(scope Range range)
756+ if (isRandomAccessRange! Range && hasLength! Range )
757+ {
758+ return .shuffle(rne, range);
759+ }
760+
746761// /
747762nothrow @safe version(mir_random_test) unittest
748763{
749764 import mir.ndslice.allocation: slice;
750765 import mir.ndslice.topology: iota;
751766 import mir.ndslice.sorting;
752767
753- auto gen = Random (unpredictableSeed);
754768 auto a = iota(10 ).slice;
755769
756- gen. shuffle(a);
770+ shuffle(a);
757771
758772 sort(a);
759773 assert (a == iota(10 ));
@@ -768,15 +782,14 @@ These will be in an undefined order, but will not be random in the sense that th
768782`shuffle` returns will not be independent of their order before
769783`shuffle` was called.
770784Params:
771- gen = random number engine to use
785+ gen = (optional) random number engine to use
772786 range = random-access range with length whose elements are to be shuffled
773787 n = number of elements of `r` to shuffle (counting from the beginning);
774788 must be less than `r.length`
775789Complexity: O(n)
776790+/
777791void shuffle (Range , G)(scope ref G gen, scope Range range, size_t n)
778- if ((isSaturatedRandomEngine! G || isReferenceToSaturatedRandomEngine! G)
779- && isRandomAccessRange! Range && hasLength! Range )
792+ if (isSaturatedRandomEngine! G && isRandomAccessRange! Range && hasLength! Range )
780793{
781794 import std.algorithm.mutation : swapAt;
782795 assert (n <= range.length, " n must be <= range.length for shuffle." );
@@ -789,17 +802,30 @@ void shuffle(Range, G)(scope ref G gen, scope Range range, size_t n)
789802 }
790803}
791804
805+ // / ditto
806+ void shuffle (Range , G)(scope G* gen, scope Range range, size_t n)
807+ if (isSaturatedRandomEngine! G && isRandomAccessRange! Range && hasLength! Range )
808+ {
809+ return .shuffle(* gen, range, n);
810+ }
811+
812+ // / ditto
813+ void shuffle (Range )(scope Range range, size_t n)
814+ if (isRandomAccessRange! Range && hasLength! Range )
815+ {
816+ return .shuffle(rne, range, n);
817+ }
818+
792819// /
793820nothrow @safe version(mir_random_test) unittest
794821{
795822 import mir.ndslice.allocation: slice;
796823 import mir.ndslice.topology: iota;
797824 import mir.ndslice.sorting;
798825
799- auto gen = Random (unpredictableSeed);
800826 auto a = iota(10 ).slice;
801827
802- gen. shuffle(a, 4 );
828+ shuffle(a, 4 );
803829
804830 sort(a);
805831 assert (a == iota(10 ));
0 commit comments