From: Jonathan Wakely Date: Mon, 17 Oct 2016 14:39:23 +0000 (+0100) Subject: PR77994 Convert std::sample size argument to suitable type X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=12d3f34b33bc41f5f3d010435fa7eb03fb344c5f;p=gcc.git PR77994 Convert std::sample size argument to suitable type PR libstdc++/77994 * include/bits/stl_algo.h (sample): Convert size argument to iterator difference type. * include/experimental/algorithm (experimental::sample): Likewise. * testsuite/25_algorithms/sample/2.cc: New test. From-SVN: r241245 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 98872fd6b4c..37ecc9c6392 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,11 @@ +2016-10-17 Jonathan Wakely + + PR libstdc++/77994 + * include/bits/stl_algo.h (sample): Convert size argument to iterator + difference type. + * include/experimental/algorithm (experimental::sample): Likewise. + * testsuite/25_algorithms/sample/2.cc: New test. + 2016-10-17 Paolo Carlini * testsuite/unordered_map/insert/57619.C: Rename to 57619.cc. diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h index db99cb8a0a6..6c771bb323a 100644 --- a/libstdc++-v3/include/bits/stl_algo.h +++ b/libstdc++-v3/include/bits/stl_algo.h @@ -5730,8 +5730,9 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO static_assert(is_integral<_Distance>::value, "sample size must be an integer type"); + typename iterator_traits<_PopulationIterator>::difference_type __d = __n; return std::__sample(__first, __last, __pop_cat{}, __out, __samp_cat{}, - __n, std::forward<_UniformRandomBitGenerator>(__g)); + __d, std::forward<_UniformRandomBitGenerator>(__g)); } #endif // C++17 #endif // C++14 diff --git a/libstdc++-v3/include/experimental/algorithm b/libstdc++-v3/include/experimental/algorithm index eb18dde198e..ff66b434bca 100644 --- a/libstdc++-v3/include/experimental/algorithm +++ b/libstdc++-v3/include/experimental/algorithm @@ -76,8 +76,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static_assert(is_integral<_Distance>::value, "sample size must be an integer type"); + typename iterator_traits<_PopulationIterator>::difference_type __d = __n; return std::__sample(__first, __last, __pop_cat{}, __out, __samp_cat{}, - __n, + __d, std::forward<_UniformRandomNumberGenerator>(__g)); } diff --git a/libstdc++-v3/testsuite/25_algorithms/sample/2.cc b/libstdc++-v3/testsuite/25_algorithms/sample/2.cc new file mode 100644 index 00000000000..8865e18f728 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/sample/2.cc @@ -0,0 +1,65 @@ +// Copyright (C) 2016 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 +// . + +// { dg-options "-std=gnu++17" } +// { dg-do run { target c++1z } } + +#ifndef _GLIBCXX_ASSERTIONS +// Make std::uniform_int_distribution check its parameters +# define _GLIBCXX_ASSERTIONS +#endif + +#include +#include +#include +#include +#include + +std::mt19937 rng; + +using std::sample; +using __gnu_test::test_container; +using __gnu_test::output_iterator_wrapper; + +void +test01() +{ + int pop[UCHAR_MAX] = { }; + for (int i = SCHAR_MAX; i < UCHAR_MAX; ++i) + pop[i] = 1; + const signed char sample_size = SCHAR_MAX; // PR libstdc++/77994 + int out[sample_size] = { }; + + // random access iterators for both population and result + // (uses reservoir sampling) + auto it = sample(std::begin(pop), std::end(pop), out, sample_size, rng); + auto sum = std::accumulate(out, it, 0); + VERIFY( sum != 0 ); // exceedingly unlikely! + + // random access iterator for population and output iterator for result + // (uses selection sampling) + test_container samp2(out); + sample(std::begin(pop), std::end(pop), samp2.begin(), sample_size, rng); + sum = std::accumulate(std::begin(out), std::end(out), 0); + VERIFY( sum != 0 ); +} + +int +main() +{ + test01(); +}