+2019-05-31 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/random.h (random_device::_M_init(const char*, size_t)):
+ Add new private member function.
+ * src/c++11/cow-string-inst.cc (random_device::_M_init(const string&))
+ (random_device::_M_init_pretr1(const string&)): Call new private
+ member with string data.
+ * src/c++11/random.cc (random_device::_M_init(const char*, size_t)):
+ Define.
+ * testsuite/26_numerics/random/random_device/cons/default-cow.cc: New
+ test using COW strings.
+ * testsuite/26_numerics/random/random_device/cons/default.cc: Generate
+ a value from the device.
+ * testsuite/26_numerics/random/random_device/cons/token.cc: Likewise.
+ Fix typo in token string.
+
2019-05-30 Nina Dinka Ranns <dinka.ranns@gmail.com>
LWG2788 basic_string spurious use of a default constructible allocator
result_type _M_getval_pretr1();
double _M_getentropy() const noexcept;
+ void _M_init(const char*, size_t); // not exported from the shared library
+
union
{
struct
#ifdef _GLIBCXX_USE_C99_STDINT_TR1
#include <random>
-#if defined __i386__ || defined __x86_64__
-# include <cpuid.h>
-#endif
-#include <cstdio>
namespace std _GLIBCXX_VISIBILITY(default)
{
void
random_device::_M_init(const std::string& token)
- {
- const char *fname = token.c_str();
-
- if (token == "default")
- {
-#if (defined __i386__ || defined __x86_64__) && defined _GLIBCXX_X86_RDRAND
- unsigned int eax, ebx, ecx, edx;
- // Check availability of cpuid and, for now at least, also the
- // CPU signature for Intel's
- if (__get_cpuid_max(0, &ebx) > 0 && ebx == signature_INTEL_ebx)
- {
- __cpuid(1, eax, ebx, ecx, edx);
- if (ecx & bit_RDRND)
- {
- _M_file = nullptr;
- return;
- }
- }
-#endif
-
- fname = "/dev/urandom";
- }
- else if (token != "/dev/urandom" && token != "/dev/random")
- fail:
- std::__throw_runtime_error(__N("random_device::"
- "random_device(const std::string&)"));
-
- _M_file = static_cast<void*>(std::fopen(fname, "rb"));
- if (!_M_file)
- goto fail;
- }
+ { _M_init(token.c_str(), token.length()); }
void
random_device::_M_init_pretr1(const std::string& token)
- {
- unsigned long __seed = 5489UL;
- if (token != "mt19937")
- {
- const char* __nptr = token.c_str();
- char* __endptr;
- __seed = std::strtoul(__nptr, &__endptr, 0);
- if (*__nptr == '\0' || *__endptr != '\0')
- std::__throw_runtime_error(__N("random_device::random_device"
- "(const std::string&)"));
- }
- _M_mt.seed(__seed);
- }
+ { _M_init(token.c_str(), token.length()); }
} // namespace
#endif
#endif
}
+ // Called by old ABI version of random_device::_M_init(const std::string&).
+ void
+ random_device::_M_init(const char* s, size_t len)
+ {
+ const std::string token(s, len);
+#ifdef USE_MT19937
+ _M_init_pretr1(token);
+#else
+ _M_init(token);
+#endif
+ }
+
void
random_device::_M_fini()
{
--- /dev/null
+// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" }
+// { dg-do run { target c++11 } }
+// { dg-require-effective-target random_device }
+// { dg-require-cstdint "" }
+//
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library 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 library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// C++11 26.5.6 class random_device [rand.device]
+
+#include <random>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ std::random_device x;
+ auto n [[gnu::unused]] = x();
+}
+
+int main()
+{
+ test01();
+}
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// 26.4.6 class random_device [rand.device]
-// 26.4.2.2 Concept RandomNumberEngine [rand.concept.eng]
+// C++11 26.5.6 class random_device [rand.device]
#include <random>
#include <testsuite_hooks.h>
{
std::random_device x;
- VERIFY( x.min() == std::numeric_limits<std::random_device::result_type>::min() );
- VERIFY( x.max() == std::numeric_limits<std::random_device::result_type>::max() );
+ using result_type = std::random_device::result_type;
+ VERIFY( x.min() == std::numeric_limits<result_type>::min() );
+ VERIFY( x.max() == std::numeric_limits<result_type>::max() );
+
+ result_type n [[gnu::unused]] = x();
}
int main()
test01()
{
std::random_device x("default");
-
- VERIFY( x.min() == std::numeric_limits<std::random_device::result_type>::min() );
- VERIFY( x.max() == std::numeric_limits<std::random_device::result_type>::max() );
-
+ using result_type = std::random_device::result_type;
+ VERIFY( x.min() == std::numeric_limits<result_type>::min() );
+ VERIFY( x.max() == std::numeric_limits<result_type>::max() );
}
void
#ifdef _GLIBCXX_USE_DEV_RANDOM
std::random_device x1("/dev/urandom");
std::random_device x2("/dev/random");
+ VERIFY( x1() != x2() );
#endif
}
{
// At least one of these tokens should be valid.
const std::string tokens[] = {
- "rdseed", "rdrand", "rand_s", "/dev/urandom", "/dev/random", "mt19337"
+ "rdseed", "rdrand", "rand_s", "/dev/urandom", "/dev/random", "mt19937"
};
int count = 0;
for (const std::string& token : tokens)
test04()
{
bool can_use_mt19937 = true;
+ std::random_device::result_type xval;
try
{
std::random_device x("mt19937");
+ xval = x();
}
catch (const std::runtime_error&)
{
can_use_mt19937 = false;
}
- // If "mt19337" is a valid token then numeric seeds should be too.
+ // If "mt19937" is a valid token then numeric seeds should be too.
if (can_use_mt19937)
{
std::random_device x1("0");
std::random_device x2("1234");
std::random_device x3("0xc0fefe");
+ VERIFY( xval != x1() );
+ VERIFY( x2() != x3() );
}
}