+2006-06-09 Paolo Carlini <pcarlini@suse.de>
+
+ * acinclude.m4 ([GLIBCXX_CHECK_RANDOM_TR1]): New, check for
+ the availability of "/dev/random" and "/dev/urandom".
+ * configure.ac: Use it.
+ * include/tr1/random (random_device): Implement, a fall-back for
+ systems not providing "/dev/random" and "/dev/urandom" included.
+ * testsuite/tr1/5_numerical_facilities/random/random_device/
+ cons/default.cc: New.
+ * testsuite/tr1/5_numerical_facilities/random/random_device/
+ cons/token.cc: Likewise.
+ * testsuite/tr1/5_numerical_facilities/random/random_device/
+ requirements/typedefs.cc: Likewise.
+ * config.h.in: Regenerate.
+ * configure: Likewise.
+
+ * testsuite/tr1/5_numerical_facilities/random/mersenne_twister/
+ cons/gen1.cc: Minor tweak, add bool test.
+
2006-06-06 Benjamin Kosnik <bkoz@redhat.com>
* testsuite/util: New directory.
AC_LANG_RESTORE
])
+dnl
+dnl Check whether "dev/random" and "dev/urandom" are available for the
+dnl random_device of "TR1" (Chapter 5.1, "Random number generation").
+dnl
+AC_DEFUN([GLIBCXX_CHECK_RANDOM_TR1], [
+
+ AC_MSG_CHECKING([for "dev/random" and "dev/urandom" for TR1 random_device])
+ AC_CACHE_VAL(ac_random_tr1, [
+ AC_TRY_RUN([#include <stdio.h>
+ int main()
+ {
+ return !(fopen("/dev/random", "r")
+ && fopen("/dev/urandom", "r"));
+ }
+ ],
+ [ac_random_tr1=yes], [ac_random_tr1=no],
+ [ac_random_tr1=no])
+ ])
+ AC_MSG_RESULT($ac_random_tr1)
+ if test x"$ac_random_tr1" = x"yes"; then
+ AC_DEFINE(_GLIBCXX_USE_RANDOM_TR1, 1,
+ [Define if dev/random and dev/urandom are available for
+ the random_device of TR1 (Chapter 5.1).])
+ fi
+
+])
dnl
dnl Check for what type of C headers to use.
/* Define if NLS translations are to be used. */
#undef _GLIBCXX_USE_NLS
+/* Define if dev/random and dev/urandom are available for the random_device of
+ TR1 (Chapter 5.1). */
+#undef _GLIBCXX_USE_RANDOM_TR1
+
/* Define if code specialized for wchar_t should be used. */
#undef _GLIBCXX_USE_WCHAR_T
+ # For dev/random and dev/urandom for TR1.
+
+
+ echo "$as_me:$LINENO: checking for \"dev/random\" and \"dev/urandom\" for TR1 random_device" >&5
+echo $ECHO_N "checking for \"dev/random\" and \"dev/urandom\" for TR1 random_device... $ECHO_C" >&6
+ if test "${ac_random_tr1+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ if test "$cross_compiling" = yes; then
+ ac_random_tr1=no
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdio.h>
+ int main()
+ {
+ return !(fopen("/dev/random", "r")
+ && fopen("/dev/urandom", "r"));
+ }
+
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_random_tr1=yes
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_random_tr1=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+fi
+
+ echo "$as_me:$LINENO: result: $ac_random_tr1" >&5
+echo "${ECHO_T}$ac_random_tr1" >&6
+ if test x"$ac_random_tr1" = x"yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _GLIBCXX_USE_RANDOM_TR1 1
+_ACEOF
+
+ fi
+
+
+
# For TLS support.
# Check whether --enable-tls or --disable-tls was given.
# For C99 support to TR1.
GLIBCXX_CHECK_C99_TR1
+ # For dev/random and dev/urandom for TR1.
+ GLIBCXX_CHECK_RANDOM_TR1
+
# For TLS support.
GCC_CHECK_TLS
#include <iosfwd>
#include <limits>
#include <tr1/type_traits>
+#include <sstream>
+#include <fstream>
namespace std
{
/**
* A standard interface to a platform-specific non-deterministic random number
* generator (if any are available).
- *
- * @todo The underlying interface is system-specific and needs to be factored
- * into the generated configury mechs. For example, the use of "/dev/random"
- * under a Linux OS would be appropriate.
*/
class random_device
{
typedef unsigned int result_type;
// constructors, destructors and member functions
- explicit random_device(const std::string& __token = "unimplemented");
- result_type min() const;
- result_type max() const;
- double entropy() const;
- result_type operator()();
+
+#ifdef _GLIBCXX_USE_RANDOM_TR1
+ explicit
+ random_device(const std::string& __token = "/dev/urandom")
+ {
+ if ((__token != "/dev/urandom" && __token != "/dev/random")
+ || !_M_filebuf.open(__token.c_str(), std::ios_base::in))
+ std::__throw_runtime_error(__N("random_device::"
+ "random_device(const std::string&)"));
+ }
+
+ ~random_device()
+ { _M_filebuf.close(); }
+
+#else
+ explicit
+ random_device(const std::string& __token = "rand")
+ {
+ if (__token != "rand")
+ {
+ std::stringstream __ss(__token);
+ unsigned int __seed;
+ __ss >> __seed;
+ if (__ss.fail())
+ std::__throw_runtime_error(__N("random_device::random_device"
+ "(const std::string&)"));
+ else
+ std::srand(__seed);
+ }
+ }
+#endif
+
+ result_type
+ min() const
+ { return std::numeric_limits<result_type>::min(); }
+
+ result_type
+ max() const
+ { return std::numeric_limits<result_type>::max(); }
+
+ double
+ entropy() const
+ { return 0.0; }
+
+ result_type
+ operator()()
+ {
+#ifdef _GLIBCXX_USE_RANDOM_TR1
+ result_type __ret;
+ _M_filebuf.sgetn(reinterpret_cast<char*>(&__ret), sizeof(result_type));
+ return __ret;
+#else
+ return max() * (std::rand() / double(RAND_MAX));
+#endif
+ }
private:
random_device(const random_device&);
void operator=(const random_device&);
+
+#ifdef _GLIBCXX_USE_RANDOM_TR1
+ std::filebuf _M_filebuf;
+#endif
};
/* @} */ // group tr1_random_generators
void
test01()
-{
+{
+ bool test __attribute__((unused)) = true;
using namespace std::tr1;
mersenne_twister<
--- /dev/null
+// 2006-06-09 Paolo Carlini <pcarlini@suse.de>
+//
+// Copyright (C) 2006 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 5.1.6 class random_device [tr.rand.device]
+// 5.1.1 Table 15 default ctor
+
+#include <tr1/random>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ using namespace std::tr1;
+ random_device x;
+
+ VERIFY( x.min() == std::numeric_limits<random_device::result_type>::min() );
+ VERIFY( x.max() == std::numeric_limits<random_device::result_type>::max() );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// 2006-06-09 Paolo Carlini <pcarlini@suse.de>
+//
+// Copyright (C) 2006 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 5.1.6 class random_device [tr.rand.device]
+// 5.1.6, p3
+
+#include <tr1/random>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+ using namespace std::tr1;
+
+#ifdef _GLIBCXX_USE_RANDOM_TR1
+ random_device x("/dev/random");
+#else
+ random_device x("0");
+#endif
+
+ VERIFY( x.min() == std::numeric_limits<random_device::result_type>::min() );
+ VERIFY( x.max() == std::numeric_limits<random_device::result_type>::max() );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-do compile }
+//
+// 2006-06-09 Paolo Carlini <pcarlini@suse.de>
+//
+// Copyright (C) 2006 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 5.1.6 class random_device [tr.rand.device]
+
+#include <tr1/random>
+
+void
+test01()
+{
+ typedef std::tr1::random_device test_type;
+ typedef test_type::result_type result_type;
+}