1*e7154709SEric Fiselier //===----------------------------------------------------------------------===//
2*e7154709SEric Fiselier //
3*e7154709SEric Fiselier //                     The LLVM Compiler Infrastructure
4*e7154709SEric Fiselier //
5*e7154709SEric Fiselier // This file is dual licensed under the MIT and the University of Illinois Open
6*e7154709SEric Fiselier // Source Licenses. See LICENSE.TXT for details.
7*e7154709SEric Fiselier //
8*e7154709SEric Fiselier //===----------------------------------------------------------------------===//
9*e7154709SEric Fiselier 
10*e7154709SEric Fiselier // UNSUPPORTED: c++98, c++03, c++11, c++14
11*e7154709SEric Fiselier 
12*e7154709SEric Fiselier // <algorithm>
13*e7154709SEric Fiselier 
14*e7154709SEric Fiselier // template <class PopulationIterator, class SampleIterator, class Distance,
15*e7154709SEric Fiselier //           class UniformRandomNumberGenerator>
16*e7154709SEric Fiselier // SampleIterator sample(PopulationIterator first, PopulationIterator last,
17*e7154709SEric Fiselier //                       SampleIterator out, Distance n,
18*e7154709SEric Fiselier //                       UniformRandomNumberGenerator &&g);
19*e7154709SEric Fiselier 
20*e7154709SEric Fiselier #include <algorithm>
21*e7154709SEric Fiselier #include <random>
22*e7154709SEric Fiselier #include <cassert>
23*e7154709SEric Fiselier 
24*e7154709SEric Fiselier #include "test_iterators.h"
25*e7154709SEric Fiselier 
26*e7154709SEric Fiselier // Stable if and only if PopulationIterator meets the requirements of a
27*e7154709SEric Fiselier // ForwardIterator type.
28*e7154709SEric Fiselier template <class PopulationIterator, class SampleIterator>
29*e7154709SEric Fiselier void test_stability(bool expect_stable) {
30*e7154709SEric Fiselier   const unsigned kPopulationSize = 100;
31*e7154709SEric Fiselier   int ia[kPopulationSize];
32*e7154709SEric Fiselier   for (unsigned i = 0; i < kPopulationSize; ++i)
33*e7154709SEric Fiselier     ia[i] = i;
34*e7154709SEric Fiselier   PopulationIterator first(ia);
35*e7154709SEric Fiselier   PopulationIterator last(ia + kPopulationSize);
36*e7154709SEric Fiselier 
37*e7154709SEric Fiselier   const unsigned kSampleSize = 20;
38*e7154709SEric Fiselier   int oa[kPopulationSize];
39*e7154709SEric Fiselier   SampleIterator out(oa);
40*e7154709SEric Fiselier 
41*e7154709SEric Fiselier   std::minstd_rand g;
42*e7154709SEric Fiselier 
43*e7154709SEric Fiselier   const int kIterations = 1000;
44*e7154709SEric Fiselier   bool unstable = false;
45*e7154709SEric Fiselier   for (int i = 0; i < kIterations; ++i) {
46*e7154709SEric Fiselier     std::sample(first, last, out, kSampleSize, g);
47*e7154709SEric Fiselier     unstable |= !std::is_sorted(oa, oa + kSampleSize);
48*e7154709SEric Fiselier   }
49*e7154709SEric Fiselier   assert(expect_stable == !unstable);
50*e7154709SEric Fiselier }
51*e7154709SEric Fiselier 
52*e7154709SEric Fiselier int main() {
53*e7154709SEric Fiselier   test_stability<forward_iterator<int *>, output_iterator<int *> >(true);
54*e7154709SEric Fiselier   test_stability<input_iterator<int *>, random_access_iterator<int *> >(false);
55*e7154709SEric Fiselier }
56