From 5ae465c5301c279b4811925aaf0fd212e195f2ff Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 13 Nov 2015 16:49:40 +0000 Subject: [PATCH] Define std::experimental::randint etc. * 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 | 7 ++ libstdc++-v3/include/Makefile.am | 1 + libstdc++-v3/include/Makefile.in | 1 + libstdc++-v3/include/experimental/random | 77 +++++++++++++++++ .../testsuite/experimental/random/randint.cc | 84 +++++++++++++++++++ 5 files changed, 170 insertions(+) create mode 100644 libstdc++-v3/include/experimental/random create mode 100644 libstdc++-v3/testsuite/experimental/random/randint.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 4daa0c308a7c..2a4cc86fae3d 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,10 @@ +2015-11-13 Jonathan Wakely + + * 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 * testsuite/22_locale/codecvt/always_noconv/char/wrapped_env.cc: diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 4e2ae1815387..5560b9e834e8 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -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 \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 89dfdbe52787..077446b49b86 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -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 index 000000000000..9be1d31647d3 --- /dev/null +++ b/libstdc++-v3/include/experimental/random @@ -0,0 +1,77 @@ +// -*- 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 +// . + +/** @file experimental/random + * This is a TS C++ Library header. + */ + +#ifndef _GLIBCXX_EXPERIMENTAL_RANDOM +#define _GLIBCXX_EXPERIMENTAL_RANDOM 1 + +#include + +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 + 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 index 000000000000..d5238361f7fd --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/random/randint.cc @@ -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 +// . + +#include +#include + +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::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(); +} -- 2.39.2