Define std::experimental::randint etc.
authorJonathan Wakely <jwakely@redhat.com>
Fri, 13 Nov 2015 16:49:40 +0000 (16:49 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Fri, 13 Nov 2015 16:49:40 +0000 (16:49 +0000)
* include/Makefile.am: Add new header.
* include/Makefile.in: Regenerate.
* include/experimental/random: New.
* testsuite/experimental/random/randint.cc: New.

From-SVN: r230332

libstdc++-v3/ChangeLog
libstdc++-v3/include/Makefile.am
libstdc++-v3/include/Makefile.in
libstdc++-v3/include/experimental/random [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/random/randint.cc [new file with mode: 0644]

index 4daa0c308a7c7ad4b7b2913237ad5332440dd1c5..2a4cc86fae3d4b220eee6d7eda8b34edd66cc2ca 100644 (file)
@@ -1,3 +1,10 @@
+2015-11-13  Jonathan Wakely  <jwakely@redhat.com>
+
+       * include/Makefile.am: Add new header.
+       * include/Makefile.in: Regenerate.
+       * include/experimental/random: New.
+       * testsuite/experimental/random/randint.cc: New.
+
 2015-11-13  John Marino  <gnugcc@marino.st>
 
        * testsuite/22_locale/codecvt/always_noconv/char/wrapped_env.cc:
index 4e2ae18153878a0d7cfd8866ac5b87b430c0f30f..5560b9e834e8c899340be507ea8cb67b94a1cdc6 100644 (file)
@@ -660,6 +660,7 @@ experimental_headers = \
        ${experimental_srcdir}/numeric \
        ${experimental_srcdir}/optional \
        ${experimental_srcdir}/propagate_const \
+       ${experimental_srcdir}/random \
        ${experimental_srcdir}/ratio \
        ${experimental_srcdir}/regex \
        ${experimental_srcdir}/set \
index 89dfdbe5278754a5e6d33c994a3f9e224d4a4775..077446b49b86aeb05767cf37dc39bad1ae57a0d4 100644 (file)
@@ -949,6 +949,7 @@ experimental_headers = \
        ${experimental_srcdir}/numeric \
        ${experimental_srcdir}/optional \
        ${experimental_srcdir}/propagate_const \
+       ${experimental_srcdir}/random \
        ${experimental_srcdir}/ratio \
        ${experimental_srcdir}/regex \
        ${experimental_srcdir}/set \
diff --git a/libstdc++-v3/include/experimental/random b/libstdc++-v3/include/experimental/random
new file mode 100644 (file)
index 0000000..9be1d31
--- /dev/null
@@ -0,0 +1,77 @@
+// <experimental/random> -*- C++ -*-
+
+// Copyright (C) 2015 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file experimental/random
+ *  This is a TS C++ Library header.
+ */
+
+#ifndef _GLIBCXX_EXPERIMENTAL_RANDOM
+#define _GLIBCXX_EXPERIMENTAL_RANDOM 1
+
+#include <random>
+
+namespace std {
+namespace experimental {
+inline namespace fundamentals_v2 {
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+#define __cpp_lib_experimental_randint 201511
+
+  inline std::default_random_engine&
+  _S_randint_engine()
+  {
+    static thread_local default_random_engine __eng{random_device{}()};
+    return __eng;
+  }
+
+  // 13.2.2.1, Function template randint
+  template<typename _IntType>
+    inline _IntType
+    randint(_IntType __a, _IntType __b)
+    {
+      static_assert(is_integral<_IntType>::value && sizeof(_IntType) > 1,
+                   "argument must be an integer type");
+      using _Dist = std::uniform_int_distribution<_IntType>;
+      static thread_local _Dist __dist;
+      return __dist(_S_randint_engine(), typename _Dist::param_type{__a, __b});
+    }
+
+  inline void
+  reseed()
+  {
+    _S_randint_engine().seed(random_device{}());
+  }
+
+  inline void
+  reseed(default_random_engine::result_type __value)
+  {
+    _S_randint_engine().seed(__value);
+  }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace fundamentals_v2
+} // namespace experimental
+} // namespace std
+
+#endif
diff --git a/libstdc++-v3/testsuite/experimental/random/randint.cc b/libstdc++-v3/testsuite/experimental/random/randint.cc
new file mode 100644 (file)
index 0000000..d523836
--- /dev/null
@@ -0,0 +1,84 @@
+// { dg-options "-std=gnu++14" }
+// { dg-require-effective-target tls_runtime }
+
+// Copyright (C) 2015 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 moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/random>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  for (int i = 0; i < 100; ++i)
+  {
+    const int n = std::experimental::randint(-10, i);
+    VERIFY( -10 <= n && n <= i );
+  }
+
+  std::experimental::reseed(99u);
+  const long n1[] = {
+    std::experimental::randint(0, 100),
+    std::experimental::randint(0, 100),
+    std::experimental::randint(0, 100),
+    std::experimental::randint(0, 100),
+    std::experimental::randint(0, 100)
+  };
+  std::experimental::reseed(99u);
+  const long n2[] = {
+    std::experimental::randint(0, 100),
+    std::experimental::randint(0, 100),
+    std::experimental::randint(0, 100),
+    std::experimental::randint(0, 100),
+    std::experimental::randint(0, 100)
+  };
+  for (int i = 0; i < 5; ++i)
+    VERIFY( n1[i] == n2[i] );
+
+  std::experimental::reseed();
+  const long n3[] = {
+    std::experimental::randint(0, 100),
+    std::experimental::randint(0, 100),
+    std::experimental::randint(0, 100)
+  };
+  VERIFY( !(n3[0] == n1[0] && n3[1] == n1[1] && n3[2] == n1[2]) );
+}
+
+void
+test02()
+{
+  auto check = [](auto v) {
+    auto n = std::experimental::randint(decltype(v)(0), v);
+    static_assert(std::is_same<decltype(n), decltype(v)>::value,
+        "return type is correct");
+    VERIFY(0 <= n && n <= v);
+  };
+  check( (short)10 );
+  check( 100 );
+  check( 1000L );
+  check( 10000LL );
+  check( (unsigned short)10 );
+  check( 100U );
+  check( 1000UL );
+  check( 10000ULL );
+}
+
+int main()
+{
+  test01();
+  test02();
+}