diff options
author | 2011-03-20 16:19:41 +0000 | |
---|---|---|
committer | 2011-03-20 16:20:42 +0000 | |
commit | c4455dd4491879bf64122e863ad4fd8ff9b6dfa5 (patch) | |
tree | cacc73e5ba81819ad9362a3f7d69468add2c64ba | |
parent | 1ea7c642bc74df0d42e0b214c1a13ce7cc7b97e8 (diff) | |
download | paludis-c4455dd4491879bf64122e863ad4fd8ff9b6dfa5.tar.gz paludis-c4455dd4491879bf64122e863ad4fd8ff9b6dfa5.tar.xz |
Use std::random
-rw-r--r-- | configure.ac | 37 | ||||
-rw-r--r-- | paludis/repositories/e/e_repository.cc | 20 | ||||
-rw-r--r-- | paludis/util/files.m4 | 1 | ||||
-rw-r--r-- | paludis/util/random.cc | 37 | ||||
-rw-r--r-- | paludis/util/random.hh | 82 | ||||
-rw-r--r-- | paludis/util/random_TEST.cc | 119 |
6 files changed, 54 insertions, 242 deletions
diff --git a/configure.ac b/configure.ac index 74dcb8f17..469673127 100644 --- a/configure.ac +++ b/configure.ac @@ -783,6 +783,43 @@ int main(int, char **) ]) dnl }}} +dnl {{{ std::random +random_is_tr1= +AC_MSG_CHECKING([for c++0x-compliant <random>]) +AC_COMPILE_IFELSE([AC_LANG_SOURCE([ +#include <random> +#include <ctime> +int main(int, char **) +{ + std::mt19937 rand(std::time(0)); + std::uniform_int_distribution<int> dist(0, 9); + return dist(rand); +} +])], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + AC_MSG_CHECKING([for tr1-compliant <random>]) + AC_COMPILE_IFELSE([AC_LANG_SOURCE([ +#include <random> +#include <ctime> +int main(int, char **) +{ + std::mt19937 rand(std::time(0)); + std::uniform_int<int> dist(0, 9); + return dist(rand); +} + ])], + [AC_MSG_RESULT([yes]) + random_is_tr1=yes], + [AC_MSG_RESULT([no]) + AC_MSG_ERROR([Your compiler does not support <random>])]) + ]) + +if test x$random_is_tr1 = xyes ; then + PALUDIS_CXXFLAGS="${PALUDIS_CXXFLAGS} -DPALUDIS_RANDOM_IS_TR1=1" +fi +dnl }}} + dnl {{{ c++0x default and deleted functions AC_MSG_CHECKING([for c++0x default and deleted functions]) AC_COMPILE_IFELSE([AC_LANG_SOURCE([ diff --git a/paludis/repositories/e/e_repository.cc b/paludis/repositories/e/e_repository.cc index e23350883..0c9f43639 100644 --- a/paludis/repositories/e/e_repository.cc +++ b/paludis/repositories/e/e_repository.cc @@ -82,7 +82,6 @@ #include <paludis/util/options.hh> #include <paludis/util/pimp-impl.hh> #include <paludis/util/process.hh> -#include <paludis/util/random.hh> #include <paludis/util/rmd160.hh> #include <paludis/util/safe_ifstream.hh> #include <paludis/util/safe_ofstream.hh> @@ -98,6 +97,7 @@ #include <paludis/util/wrapped_forward_iterator.hh> #include <paludis/util/wrapped_output_iterator.hh> +#include <random> #include <functional> #include <unordered_map> #include <map> @@ -105,6 +105,7 @@ #include <algorithm> #include <vector> #include <list> +#include <ctime> #include <strings.h> #include <ctype.h> @@ -644,6 +645,19 @@ ERepository::arch_flags() const return _imp->arch_flags; } +namespace +{ + struct Randomator + { + std::mt19937 & rand; + + int operator() (int n) + { + return rand() % n; + } + }; +} + void ERepository::need_mirrors() const { @@ -666,8 +680,8 @@ ERepository::need_mirrors() const if (! ee.empty()) { /* pick up to five random mirrors only */ - static Random r; - std::random_shuffle(next(ee.begin()), ee.end(), r); + std::mt19937 random(std::time(0)); + std::random_shuffle(next(ee.begin()), ee.end(), Randomator{random}); if (ee.size() > 6) ee.resize(6); diff --git a/paludis/util/files.m4 b/paludis/util/files.m4 index d98aae3b3..d475e8f9f 100644 --- a/paludis/util/files.m4 +++ b/paludis/util/files.m4 @@ -64,7 +64,6 @@ add(`pool', `hh', `cc', `impl', `test') add(`pretty_print', `hh', `cc', `test') add(`process', `hh', `cc', `fwd', `gtest', `testscript') add(`pty', `hh', `cc', `gtest') -add(`random', `hh', `cc', `test') add(`realpath', `hh', `cc', `gtest', `testscript') add(`remove_shared_ptr', `hh') add(`return_literal_function', `hh', `cc', `fwd', `gtest') diff --git a/paludis/util/random.cc b/paludis/util/random.cc deleted file mode 100644 index 74bf2d480..000000000 --- a/paludis/util/random.cc +++ /dev/null @@ -1,37 +0,0 @@ -/* vim: set sw=4 sts=4 et foldmethod=syntax : */ - -/* - * Copyright (c) 2006, 2007 Ciaran McCreesh - * - * This file is part of the Paludis package manager. Paludis is free software; - * you can redistribute it and/or modify it under the terms of the GNU General - * Public License version 2, as published by the Free Software Foundation. - * - * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "random.hh" -#include <time.h> - -using namespace paludis; - -uint32_t Random::global_seed(0xdeadbeef ^ ::time(0)); - -Random::Random(uint32_t seed) : - local_seed(seed) -{ -} - -Random::Random() : - local_seed(global_seed ^ ((::time(0) >> 16) | (::time(0) << 16))) -{ - global_seed += local_seed; -} - diff --git a/paludis/util/random.hh b/paludis/util/random.hh deleted file mode 100644 index a5d391fc0..000000000 --- a/paludis/util/random.hh +++ /dev/null @@ -1,82 +0,0 @@ -/* vim: set sw=4 sts=4 et foldmethod=syntax : */ - -/* - * Copyright (c) 2006, 2007, 2008, 2009 Ciaran McCreesh - * - * This file is part of the Paludis package manager. Paludis is free software; - * you can redistribute it and/or modify it under the terms of the GNU General - * Public License version 2, as published by the Free Software Foundation. - * - * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef PALUDIS_GUARD_PALUDIS_UTIL_RANDOM_HH -#define PALUDIS_GUARD_PALUDIS_UTIL_RANDOM_HH 1 - -#include <cstdlib> -#include <inttypes.h> -#include <paludis/util/attributes.hh> - -/** \file - * Declarations for the Random class. - * - * \ingroup g_utils - * - * \section Examples - * - * - None at this time. - */ - -namespace paludis -{ - /** - * A basic random number generator class, which is not suitable for - * cryptography but is fast and reasonably pseudorandom. - * - * See \ref TCppPL 22.7 for justification. See \ref TaoCP2 3.2.1 for the - * basic algorithm and \ref AppCrypt 16.1 for the choice of numbers. - * - * \ingroup g_utils - * \nosubgrouping - */ - class PALUDIS_VISIBLE Random - { - private: - static uint32_t global_seed; - uint32_t local_seed; - - static const uint32_t _a = 2416; - static const uint32_t _b = 374441; - static const uint32_t _m = 1771875; - - public: - ///\name Basic operations - ///\{ - - /// Constructor, with a seed. - Random(uint32_t seed); - - /// Constructor, with a magic random seed. - Random(); - - ///\} - - /// Fetch a random number in (0, max] - template <typename DiffType_> - DiffType_ operator() (DiffType_ max) - { - local_seed = (_a * local_seed + _b) % _m; - double t(static_cast<double>(local_seed) / static_cast<double>(_m)); - return static_cast<DiffType_>(t * max); - } - }; -} - -#endif diff --git a/paludis/util/random_TEST.cc b/paludis/util/random_TEST.cc deleted file mode 100644 index 87bcadd84..000000000 --- a/paludis/util/random_TEST.cc +++ /dev/null @@ -1,119 +0,0 @@ -/* vim: set sw=4 sts=4 et foldmethod=syntax : */ - -/* - * Copyright (c) 2006 Ciaran McCreesh - * - * This file is part of the Paludis package manager. Paludis is free software; - * you can redistribute it and/or modify it under the terms of the GNU General - * Public License version 2, as published by the Free Software Foundation. - * - * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "random.hh" -#include <test/test_framework.hh> -#include <test/test_runner.hh> -#include <vector> -#include <algorithm> - -/** \file - * Test cases for paludis::Random. - * - */ - -using namespace paludis; -using namespace test; - -namespace -{ - struct RandomUpTo - { - Random random; - unsigned max; - - RandomUpTo(const Random & r, const unsigned m) : - random(r), - max(m) - { - } - - int operator() () - { - return random(max); - } - }; - - inline double square(double v) - { - return v * v; - } -} - -namespace test_cases -{ - /** - * \test Test Random distibutions using counts. - * - */ - struct RandomDistributionCountsTest : TestCase - { - RandomDistributionCountsTest() : TestCase("distribution (counts)") { } - - void run() - { - std::vector<int> v; - v.reserve(10000); - std::generate_n(std::back_inserter(v), 10000, RandomUpTo(Random(), 10)); - - TEST_CHECK_EQUAL(0, *std::min_element(v.begin(), v.end())); - TEST_CHECK_EQUAL(9, *std::max_element(v.begin(), v.end())); - for (int i(0) ; i < 10 ; ++i) - { - TEST_CHECK(std::count(v.begin(), v.end(), i) > 1); - TEST_CHECK(std::count(v.begin(), v.end(), i) < 3000); - } - } - } test_random_counts; - - /** - * \test Test Random distibutions using chi square. - * - * This is a chi square test, so it could theoretically fail - * occasionally. See \ref TaoCP2 3.3.1 for details. - */ - struct RandomDistributionChiSquaredTest : TestCase - { - RandomDistributionChiSquaredTest() : TestCase("distribution (chi square)") { } - - void run() - { - int failures(0); - - for (int attempts(0) ; attempts < 3 ; ++ attempts) - { - std::vector<int> v; - v.reserve(10000); - std::generate_n(std::back_inserter(v), 10000, RandomUpTo(Random(), 10)); - - double a(0); - for (int i(0) ; i <= 9 ; ++i) - a += (square(std::count(v.begin(), v.end(), i) - (10000 / 10)) / (10000 / 10)); - - TestMessageSuffix suffix("a=" + stringify(a), true); - TEST_CHECK(true); - if ((a < 2.088) || (a > 21.67)) - ++failures; - } - - TEST_CHECK(failures <= 1); - } - } test_random_chi_square; -} - |