Home | History | Annotate | Download | only in alg.nth.element
      1 //===----------------------------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 // <algorithm>
     11 
     12 // template<RandomAccessIterator Iter, StrictWeakOrder<auto, Iter::value_type> Compare>
     13 //   requires ShuffleIterator<Iter>
     14 //         && CopyConstructible<Compare>
     15 //   void
     16 //   nth_element(Iter first, Iter nth, Iter last, Compare comp);
     17 
     18 #include <algorithm>
     19 #include <functional>
     20 #include <vector>
     21 #include <cassert>
     22 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     23 #include <memory>
     24 
     25 struct indirect_less
     26 {
     27     template <class P>
     28     bool operator()(const P& x, const P& y)
     29         {return *x < *y;}
     30 };
     31 
     32 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     33 
     34 void
     35 test_one(unsigned N, unsigned M)
     36 {
     37     assert(N != 0);
     38     assert(M < N);
     39     int* array = new int[N];
     40     for (int i = 0; i < N; ++i)
     41         array[i] = i;
     42     std::random_shuffle(array, array+N);
     43     std::nth_element(array, array+M, array+N, std::greater<int>());
     44     assert(array[M] == N-M-1);
     45     delete [] array;
     46 }
     47 
     48 void
     49 test(unsigned N)
     50 {
     51     test_one(N, 0);
     52     test_one(N, 1);
     53     test_one(N, 2);
     54     test_one(N, 3);
     55     test_one(N, N/2-1);
     56     test_one(N, N/2);
     57     test_one(N, N/2+1);
     58     test_one(N, N-3);
     59     test_one(N, N-2);
     60     test_one(N, N-1);
     61 }
     62 
     63 int main()
     64 {
     65     int d = 0;
     66     std::nth_element(&d, &d, &d);
     67     assert(d == 0);
     68     test(256);
     69     test(257);
     70     test(499);
     71     test(500);
     72     test(997);
     73     test(1000);
     74     test(1009);
     75 
     76 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     77     {
     78     std::vector<std::unique_ptr<int> > v(1000);
     79     for (int i = 0; i < v.size(); ++i)
     80         v[i].reset(new int(i));
     81     std::nth_element(v.begin(), v.begin() + v.size()/2, v.end(), indirect_less());
     82     assert(*v[v.size()/2] == v.size()/2);
     83     }
     84 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     85 }
     86