File 2872-Implement-seeding-with-default-algorithm.patch of Package erlang

From 9b8f09a991242b2ff737b3b7cd0e309a5cc1f2d2 Mon Sep 17 00:00:00 2001
From: Raimo Niskanen <raimo@erlang.org>
Date: Tue, 8 Dec 2020 16:44:51 +0100
Subject: [PATCH 2/6] Implement seeding with 'default' algorithm

---
 lib/stdlib/doc/src/rand.xml    | 34 ++++++++++++++++++++++-------
 lib/stdlib/src/rand.erl        | 11 ++++++++--
 lib/stdlib/test/rand_SUITE.erl | 39 ++++++++++++++++++++++------------
 3 files changed, 60 insertions(+), 24 deletions(-)

diff --git a/lib/stdlib/doc/src/rand.xml b/lib/stdlib/doc/src/rand.xml
index ac99736761..0eed1c2e49 100644
--- a/lib/stdlib/doc/src/rand.xml
+++ b/lib/stdlib/doc/src/rand.xml
@@ -310,6 +310,8 @@ tests. We suggest to use a sign test to extract a random Boolean value.</pre>
 	  A list of integers sets the generator's internal state directly,
 	  after algorithm-dependent checks of the value
 	  and masking to the proper word size.
+          The number of integers must be equal to the
+          number of state words in the generator.
 	</p>
 	<p>
 	  An integer is used as the initial state for a SplitMix64 generator.
@@ -432,7 +434,8 @@ tests. We suggest to use a sign test to extract a random Boolean value.</pre>
     </func>
 
     <func>
-      <name name="seed" arity="1" since="OTP 18.0"/>
+      <name name="seed" arity="1" clause_i="1" since="OTP 18.0"/>
+      <name name="seed" arity="1" clause_i="2" since="OTP 24.0"/>
       <fsummary>Seed random number generator.</fsummary>
       <desc>
         <marker id="seed-1"/>
@@ -440,6 +443,8 @@ tests. We suggest to use a sign test to extract a random Boolean value.</pre>
 	  Seeds random number generation with the specifed algorithm and
           time-dependent data if <c><anno>AlgOrStateOrExpState</anno></c>
 	  is an algorithm.
+          <c><anno>Alg</anno>&nbsp;=&nbsp;default</c>
+          is an alias for the default algorithm.
 	</p>
         <p>Otherwise recreates the exported seed in the process dictionary,
           and returns the state. See also
@@ -448,22 +453,30 @@ tests. We suggest to use a sign test to extract a random Boolean value.</pre>
     </func>
 
     <func>
-      <name name="seed" arity="2" since="OTP 18.0"/>
+      <name name="seed" arity="2" clause_i="1" since="OTP 18.0"/>
+      <name name="seed" arity="2" clause_i="2" since="OTP 24.0"/>
       <fsummary>Seed the random number generation.</fsummary>
       <desc>
-        <p>Seeds random number generation with the specified algorithm and
-          integers in the process dictionary and returns the state.</p>
+        <p>
+          Seeds random number generation with the specified algorithm and
+          integers in the process dictionary and returns the state.
+          <c><anno>Alg</anno>&nbsp;=&nbsp;default</c>
+          is an alias for the default algorithm.
+        </p>
       </desc>
     </func>
 
     <func>
-      <name name="seed_s" arity="1" since="OTP 18.0"/>
+      <name name="seed_s" arity="1" clause_i="1" since="OTP 18.0"/>
+      <name name="seed_s" arity="1" clause_i="2" since="OTP 24.0"/>
       <fsummary>Seed random number generator.</fsummary>
       <desc>
         <p>
 	  Seeds random number generation with the specifed algorithm and
           time-dependent data if <c><anno>AlgOrStateOrExpState</anno></c>
 	  is an algorithm.
+          <c><anno>Alg</anno>&nbsp;=&nbsp;default</c>
+          is an alias for the default algorithm.
 	</p>
         <p>Otherwise recreates the exported seed and returns the state.
           See also <seemfa marker="#export_seed/0">
@@ -472,11 +485,16 @@ tests. We suggest to use a sign test to extract a random Boolean value.</pre>
     </func>
 
     <func>
-      <name name="seed_s" arity="2" since="OTP 18.0"/>
+      <name name="seed_s" arity="2" clause_i="1" since="OTP 18.0"/>
+      <name name="seed_s" arity="2" clause_i="2" since="OTP 24.0"/>
       <fsummary>Seed the random number generation.</fsummary>
       <desc>
-        <p>Seeds random number generation with the specified algorithm and
-          integers and returns the state.</p>
+        <p>
+          Seeds random number generation with the specified algorithm and
+          integers and returns the state.
+          <c><anno>Alg</anno>&nbsp;=&nbsp;default</c>
+          is an alias for the default algorithm.
+        </p>
       </desc>
     </func>
 
diff --git a/lib/stdlib/src/rand.erl b/lib/stdlib/src/rand.erl
index b743bd5798..1de78a23ac 100644
--- a/lib/stdlib/src/rand.erl
+++ b/lib/stdlib/src/rand.erl
@@ -248,12 +248,16 @@ export_seed_s({#{type:=Alg}, AlgState}) -> {Alg, AlgState}.
 
 -spec seed(
         AlgOrStateOrExpState :: builtin_alg() | state() | export_state()) ->
+                  state();
+          (Alg :: 'default') ->
                   state().
 seed(Alg) ->
     seed_put(seed_s(Alg)).
 
 -spec seed_s(
         AlgOrStateOrExpState :: builtin_alg() | state() | export_state()) ->
+                    state();
+            (Alg :: 'default') ->
                     state().
 seed_s({AlgHandler, _AlgState} = State) when is_map(AlgHandler) ->
     State;
@@ -268,11 +272,14 @@ seed_s(Alg) ->
 %% seed/2: seeds RNG with the algorithm and given values
 %% and returns the NEW state.
 
--spec seed(Alg :: builtin_alg(),  Seed :: seed()) -> state().
+-spec seed(Alg :: builtin_alg(),  Seed :: seed()) -> state();
+          (Alg :: 'default',  Seed :: seed()) -> state().
 seed(Alg, Seed) ->
     seed_put(seed_s(Alg, Seed)).
 
--spec seed_s(Alg :: builtin_alg(), Seed :: seed()) -> state().
+-spec seed_s(Alg :: builtin_alg(), Seed :: seed()) -> state();
+            (Alg :: 'default', Seed :: seed()) -> state().
+seed_s(default, Seed) -> seed_s(?DEFAULT_ALG_HANDLER, Seed);
 seed_s(Alg, Seed) ->
     {AlgHandler,SeedFun} = mk_alg(Alg),
     AlgState = SeedFun(Seed),
diff --git a/lib/stdlib/test/rand_SUITE.erl b/lib/stdlib/test/rand_SUITE.erl
index d368fb3fc6..230020857f 100644
--- a/lib/stdlib/test/rand_SUITE.erl
+++ b/lib/stdlib/test/rand_SUITE.erl
@@ -85,7 +85,7 @@ algs() ->
 
 %% Test that seed and seed_s and export_seed/0 is working.
 seed(Config) when is_list(Config) ->
-    Algs = algs(),
+    Algs = [default|algs()],
     Test = fun(Alg) ->
 		   try seed_1(Alg)
 		   catch _:Reason:Stacktrace ->
@@ -93,6 +93,13 @@ seed(Config) when is_list(Config) ->
 		   end
 	   end,
     [Test(Alg) || Alg <- Algs],
+    %%
+    %% Check that export_seed/1 returns 'undefined' if there is no seed
+    erase(rand_seed),
+    undefined = rand:export_seed(),
+    %%
+    %% Other seed terms shall not work
+    {'EXIT', _} = (catch rand:seed_s(foobar, os:timestamp())),
     ok.
 
 seed_1(Alg) ->
@@ -121,22 +128,26 @@ seed_1(Alg) ->
     false = (S1 =:= rand:seed_s(Alg)),
     %% Negative integers works
     _ = rand:seed_s(Alg, {-1,-1,-1}),
-    %% Check that export_seed/1 returns 'undefined' if there is no seed
-    erase(rand_seed),
-    undefined = rand:export_seed(),
-
-    %% Other term do not work
-    {'EXIT', _} = (catch rand:seed_s(foobar, os:timestamp())),
+    %%
+    %% Other seed terms shall not work
     {'EXIT', _} = (catch rand:seed_s(Alg, {asd, 1, 1})),
     {'EXIT', _} = (catch rand:seed_s(Alg, {0, 234.1234, 1})),
     {'EXIT', _} = (catch rand:seed_s(Alg, {0, 234, [1, 123, 123]})),
+    {'EXIT', _} = (catch rand:seed_s(Alg, asd)),
+    {'EXIT', _} = (catch rand:seed_s(Alg, make_ref())),
+    {'EXIT', _} = (catch rand:seed_s(Alg, fun () -> 0 end)),
+    {'EXIT', _} = (catch rand:seed_s(Alg, self())),
+    {'EXIT', _} = (catch rand:seed_s(Alg, {1,2})),
+    {'EXIT', _} = (catch rand:seed_s(Alg, {1,2,3,4})),
+    {'EXIT', _} = (catch rand:seed_s(Alg, #{})),
+    {'EXIT', _} = (catch rand:seed_s(Alg, [1|2])),
     ok.
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 %% Check that both APIs are consistent with each other.
 api_eq(_Config) ->
-    Algs = algs(),
+    Algs = [default|algs()],
     Small = fun(Alg) ->
 		    Seed = rand:seed(Alg),
 		    io:format("Seed ~p~n",[rand:export_seed_s(Seed)]),
@@ -182,7 +193,7 @@ api_eq_1(S00) ->
 
 %% Check that uniform/1 returns values within the proper interval.
 interval_int(Config) when is_list(Config) ->
-    Algs = algs(),
+    Algs = [default|algs()],
     Small = fun(Alg) ->
 		    Seed = rand:seed(Alg),
 		    io:format("Seed ~p~n",[rand:export_seed_s(Seed)]),
@@ -216,7 +227,7 @@ interval_int_1(N, Top, Max) ->
 
 %% Check that uniform/0 returns values within the proper interval.
 interval_float(Config) when is_list(Config) ->
-    Algs = algs(),
+    Algs = [default|algs()],
     Test = fun(Alg) ->
 		   _ = rand:seed(Alg),
 		   interval_float_1(100000)
@@ -307,13 +318,13 @@ gen(_, _, _, Acc) -> lists:reverse(Acc).
 basic_stats_uniform_1(Config) when is_list(Config) ->
     ct:timetrap({minutes,15}), %% valgrind needs a lot of time
     [basic_uniform_1(?LOOP, rand:seed_s(Alg), 0.0, array:new([{default, 0}]))
-     || Alg <- algs()],
+     || Alg <- [default|algs()]],
     ok.
 
 basic_stats_uniform_2(Config) when is_list(Config) ->
     ct:timetrap({minutes,15}), %% valgrind needs a lot of time
     [basic_uniform_2(?LOOP, rand:seed_s(Alg), 0, array:new([{default, 0}]))
-     || Alg <- algs()],
+     || Alg <- [default|algs()]],
     ok.
 
 basic_stats_standard_normal(Config) when is_list(Config) ->
@@ -323,7 +334,7 @@ basic_stats_standard_normal(Config) when is_list(Config) ->
     IntendedVariance = 1,
     [basic_normal_1(?LOOP, IntendedMean, IntendedVariance,
                     rand:seed_s(Alg), 0, 0)
-     || Alg <- algs()],
+     || Alg <- [default|algs()]],
     ok.
 
 basic_stats_normal(Config) when is_list(Config) ->
@@ -342,7 +353,7 @@ basic_stats_normal(Config) when is_list(Config) ->
                 [float(IntendedMean), float(IntendedVariance)]),
               [basic_normal_1(?LOOP, IntendedMean, IntendedVariance,
                               rand:seed_s(Alg), 0, 0)
-               || Alg <- algs()]
+               || Alg <- [default|algs()]]
       end,
       IntendedMeanVariancePairs).
 
-- 
2.26.2

openSUSE Build Service is sponsored by