[libcxx] r228839 - Fix PR 22541: When values are equal, minmax should return the rightmost one in the initializer_list

Marshall Clow mclow.lists at gmail.com
Wed Feb 11 07:41:34 PST 2015


Author: marshall
Date: Wed Feb 11 09:41:34 2015
New Revision: 228839

URL: http://llvm.org/viewvc/llvm-project?rev=228839&view=rev
Log:
Fix PR 22541: When values are equal, minmax should return the rightmost one in the initializer_list

Modified:
    libcxx/trunk/include/algorithm
    libcxx/trunk/test/std/algorithms/alg.sorting/alg.min.max/minmax_init_list_comp.pass.cpp

Modified: libcxx/trunk/include/algorithm
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/algorithm?rev=228839&r1=228838&r2=228839&view=diff
==============================================================================
--- libcxx/trunk/include/algorithm (original)
+++ libcxx/trunk/include/algorithm Wed Feb 11 09:41:34 2015
@@ -2771,7 +2771,7 @@ minmax(initializer_list<_Tp> __t, _Compa
     typedef typename initializer_list<_Tp>::const_iterator _Iter;
     _Iter __first = __t.begin();
     _Iter __last  = __t.end();
-    std::pair<_Tp, _Tp> __result ( *__first, *__first );
+    std::pair<_Tp, _Tp> __result(*__first, *__first);
 
     ++__first;
     if (__t.size() % 2 == 0)
@@ -2786,13 +2786,13 @@ minmax(initializer_list<_Tp> __t, _Compa
     while (__first != __last)
     {
         _Tp __prev = *__first++;
-        if (__comp(__prev, *__first)) {
-            if (__comp(__prev, __result.first))    __result.first  = __prev;
-            if (__comp(__result.second, *__first)) __result.second = *__first;
+        if (__comp(*__first, __prev)) {
+            if ( __comp(*__first, __result.first)) __result.first  = *__first;
+            if (!__comp(__prev, __result.second))  __result.second = __prev;
             }
         else {
-            if (__comp(*__first, __result.first)) __result.first  = *__first;
-            if (__comp(__result.second, __prev))  __result.second = __prev;
+            if ( __comp(__prev, __result.first))    __result.first  = __prev;
+            if (!__comp(*__first, __result.second)) __result.second = *__first;
             }
                 
         __first++;

Modified: libcxx/trunk/test/std/algorithms/alg.sorting/alg.min.max/minmax_init_list_comp.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/algorithms/alg.sorting/alg.min.max/minmax_init_list_comp.pass.cpp?rev=228839&r1=228838&r2=228839&view=diff
==============================================================================
--- libcxx/trunk/test/std/algorithms/alg.sorting/alg.min.max/minmax_init_list_comp.pass.cpp (original)
+++ libcxx/trunk/test/std/algorithms/alg.sorting/alg.min.max/minmax_init_list_comp.pass.cpp Wed Feb 11 09:41:34 2015
@@ -12,11 +12,27 @@
 // template<class T, class Compare>
 //   pair<T, T>
 //   minmax(initializer_list<T> t, Compare comp);
+//
+//  Complexity: At most (3/2) * t.size() applications of the corresponding predicate.
 
 #include <algorithm>
 #include <functional>
 #include <cassert>
 
+#include "counting_predicates.hpp"
+
+bool all_equal(int a, int b) { return false; } // everything is equal
+
+void test_all_equal(std::initializer_list<int> il)
+{
+    binary_counting_predicate<bool(*)(int, int), int, int> pred (all_equal);
+    std::pair<int, int> p = std::minmax(il, std::ref(pred));
+    const int *ptr = il.end();
+    assert(p.first == *il.begin());
+    assert(p.second == *--ptr);
+    assert(pred.count() <= ((3 * il.size()) / 2));
+}
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
@@ -26,6 +42,25 @@ int main()
     assert((std::minmax({2, 3, 1}, std::greater<int>()) == std::pair<int, int>(3, 1)));
     assert((std::minmax({3, 1, 2}, std::greater<int>()) == std::pair<int, int>(3, 1)));
     assert((std::minmax({3, 2, 1}, std::greater<int>()) == std::pair<int, int>(3, 1)));
+    assert((std::minmax({1, 2, 3}, all_equal          ) == std::pair<int, int>(1, 3)));
+
+    binary_counting_predicate<std::greater<int>, int, int> pred ((std::greater<int>()));
+    assert((std::minmax({1, 2, 2, 3, 3, 3, 5, 5, 5, 5, 5, 3}, std::ref(pred)) == std::pair<int, int>(5, 1)));
+    assert(pred.count() <= 18); // size == 12
+
+    test_all_equal({0});
+    test_all_equal({0,1});
+    test_all_equal({0,1,2});
+    test_all_equal({0,1,2,3});
+    test_all_equal({0,1,2,3,4});
+    test_all_equal({0,1,2,3,4,5});
+    test_all_equal({0,1,2,3,4,5,6});
+    test_all_equal({0,1,2,3,4,5,6,7});
+    test_all_equal({0,1,2,3,4,5,6,7,8});
+    test_all_equal({0,1,2,3,4,5,6,7,8,9});
+    test_all_equal({0,1,2,3,4,5,6,7,8,9,10});
+    test_all_equal({0,1,2,3,4,5,6,7,8,9,10,11});
+
 #if _LIBCPP_STD_VER > 11
     {
     static_assert((std::minmax({1, 2, 3}, std::greater<int>()) == std::pair<int, int>(3, 1)), "");





More information about the cfe-commits mailing list