[Libreoffice-commits] core.git: Branch 'libreoffice-4-4' - basic/inc basic/source

Michael Stahl mstahl at redhat.com
Wed May 20 07:04:02 PDT 2015


 basic/inc/pch/precompiled_sb.hxx |    2 -
 basic/source/runtime/methods.cxx |   46 +++++++++++++++++++++++++++++++++------
 2 files changed, 40 insertions(+), 8 deletions(-)

New commits:
commit 0e5aa443f8f603be6e5ad4ddcec12e5b6fbdff8a
Author: Michael Stahl <mstahl at redhat.com>
Date:   Tue May 19 21:48:55 2015 +0200

    tdf#90110: basic: fix Randomize statement
    
    - time() is used to seed the RNG but since it only has second resolution,
      the same values will be generated if it's called multiple times like
      in the bug report
    
    - BASIC using the global rng would be fine except that BASIC Randomize
      takes an optional parameter to set the seed, which should continue
      to be supported, but should not affect the RNG state for non-BASIC
      users of comphelper::random
    
    (regression from df466d79cb126667cc9d5c108367bfa4f5ce76c8,
     but the old implementation was even more delightfully absurd,
     where Randomize was essentially srand((sal_uInt16)rand()) ...)
    
    Change-Id: I0f30e509de08f933c02ac77c5d932b20e79586c5
    (cherry picked from commit 564fc483931c0aa2872a33023473c7ac36bfedf1)
    Reviewed-on: https://gerrit.libreoffice.org/15818
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/basic/inc/pch/precompiled_sb.hxx b/basic/inc/pch/precompiled_sb.hxx
index e67f28f..ca23122 100644
--- a/basic/inc/pch/precompiled_sb.hxx
+++ b/basic/inc/pch/precompiled_sb.hxx
@@ -31,7 +31,6 @@
 #include <com/sun/star/uno/XInterface.hpp>
 #include <com/sun/star/util/DateTime.hpp>
 #include <comphelper/processfactory.hxx>
-#include <comphelper/random.hxx>
 #include <comphelper/string.hxx>
 #include <cstddef>
 #include <ctype.h>
@@ -45,6 +44,7 @@
 #include <osl/file.hxx>
 #include <osl/process.h>
 #include <osl/time.h>
+#include <random>
 #include <rtl/character.hxx>
 #include <rtl/instance.hxx>
 #include <rtl/math.hxx>
diff --git a/basic/source/runtime/methods.cxx b/basic/source/runtime/methods.cxx
index 545e396..34191ce 100644
--- a/basic/source/runtime/methods.cxx
+++ b/basic/source/runtime/methods.cxx
@@ -47,7 +47,6 @@
 #include "errobject.hxx"
 
 #include <comphelper/processfactory.hxx>
-#include <comphelper/random.hxx>
 #include <comphelper/string.hxx>
 
 #include <com/sun/star/uno/Sequence.hxx>
@@ -61,6 +60,8 @@
 #include <boost/scoped_array.hpp>
 #include <boost/scoped_ptr.hpp>
 
+#include <random>
+
 using namespace comphelper;
 using namespace osl;
 using namespace com::sun::star;
@@ -3518,6 +3519,38 @@ RTLFUNC(Format)
     }
 }
 
+namespace {
+
+// note: BASIC does not use comphelper::random, because
+// Randomize(int) must be supported and should not affect non-BASIC random use
+struct RandomNumberGenerator
+{
+    std::mt19937 global_rng;
+
+    RandomNumberGenerator()
+    {
+        try
+        {
+            std::random_device rd;
+            // initialises the state of the global random number generator
+            // should only be called once.
+            // (note, a few std::variate_generator<> (like normal) have their
+            // own state which would need a reset as well to guarantee identical
+            // sequence of numbers, e.g. via myrand.distribution().reset())
+            global_rng.seed(rd() ^ time(nullptr));
+        }
+        catch (std::runtime_error& e)
+        {
+            SAL_WARN("basic", "Using std::random_device failed: " << e.what());
+            global_rng.seed(time(nullptr));
+        }
+    }
+};
+
+class theRandomNumberGenerator : public rtl::Static<RandomNumberGenerator, theRandomNumberGenerator> {};
+
+}
+
 RTLFUNC(Randomize)
 {
     (void)pBasic;
@@ -3531,12 +3564,9 @@ RTLFUNC(Randomize)
     if( rPar.Count() == 2 )
     {
         nSeed = (int)rPar.Get(1)->GetInteger();
+        theRandomNumberGenerator::get().global_rng.seed(nSeed);
     }
-    else
-    {
-        nSeed = (int)time(NULL);
-    }
-    comphelper::rng::reseed(nSeed);
+    // without parameter, no need to do anything - RNG is seeded at first use
 }
 
 RTLFUNC(Rnd)
@@ -3550,7 +3580,9 @@ RTLFUNC(Rnd)
     }
     else
     {
-        rPar.Get(0)->PutDouble(comphelper::rng::uniform_real_distribution());
+        std::uniform_real_distribution<double> dist(0.0, 1.0);
+        double const tmp(dist(theRandomNumberGenerator::get().global_rng));
+        rPar.Get(0)->PutDouble(tmp);
     }
 }
 


More information about the Libreoffice-commits mailing list