[libcxx] r201697 - Implement LWG2350: min, max, and minmax should be constexpr.

Marshall Clow mclow.lists at gmail.com
Wed Feb 19 08:51:36 PST 2014


Author: marshall
Date: Wed Feb 19 10:51:35 2014
New Revision: 201697

URL: http://llvm.org/viewvc/llvm-project?rev=201697&view=rev
Log:
Implement LWG2350: min, max, and minmax should be constexpr.

Modified:
    libcxx/trunk/include/algorithm
    libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/max.pass.cpp
    libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/max_comp.pass.cpp
    libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/max_init_list.pass.cpp
    libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/max_init_list_comp.pass.cpp
    libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/min.pass.cpp
    libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/min_comp.pass.cpp
    libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/min_init_list.pass.cpp
    libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/min_init_list_comp.pass.cpp
    libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/minmax.pass.cpp
    libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/minmax_comp.pass.cpp
    libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/minmax_init_list.pass.cpp
    libcxx/trunk/test/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=201697&r1=201696&r2=201697&view=diff
==============================================================================
--- libcxx/trunk/include/algorithm (original)
+++ libcxx/trunk/include/algorithm Wed Feb 19 10:51:35 2014
@@ -528,19 +528,19 @@ template <class ForwardIterator, class C
 
 template <class T>
     const T&
-    min(const T& a, const T& b);
+    min(const T& a, const T& b);  // constexpr in C++14
 
 template <class T, class Compare>
     const T&
-    min(const T& a, const T& b, Compare comp);
+    min(const T& a, const T& b, Compare comp);  // constexpr in C++14
 
 template<class T>
     T
-    min(initializer_list<T> t);
+    min(initializer_list<T> t);  // constexpr in C++14
 
 template<class T, class Compare>
     T
-    min(initializer_list<T> t, Compare comp);
+    min(initializer_list<T> t, Compare comp);  // constexpr in C++14
 
 template <class ForwardIterator>
     ForwardIterator
@@ -552,19 +552,19 @@ template <class ForwardIterator, class C
 
 template <class T>
     const T&
-    max(const T& a, const T& b);
+    max(const T& a, const T& b); // constexpr in C++14
 
 template <class T, class Compare>
     const T&
-    max(const T& a, const T& b, Compare comp);
+    max(const T& a, const T& b, Compare comp);  // constexpr in C++14
 
 template<class T>
     T
-    max(initializer_list<T> t);
+    max(initializer_list<T> t);  // constexpr in C++14
 
 template<class T, class Compare>
     T
-    max(initializer_list<T> t, Compare comp);
+    max(initializer_list<T> t, Compare comp);  // constexpr in C++14
 
 template<class ForwardIterator>
     pair<ForwardIterator, ForwardIterator>
@@ -576,19 +576,19 @@ template<class ForwardIterator, class Co
 
 template<class T>
     pair<const T&, const T&>
-    minmax(const T& a, const T& b);
+    minmax(const T& a, const T& b);  // constexpr in C++14
 
 template<class T, class Compare>
     pair<const T&, const T&>
-    minmax(const T& a, const T& b, Compare comp);
+    minmax(const T& a, const T& b, Compare comp);  // constexpr in C++14
 
 template<class T>
     pair<T, T>
-    minmax(initializer_list<T> t);
+    minmax(initializer_list<T> t);  // constexpr in C++14
 
 template<class T, class Compare>
     pair<T, T>
-    minmax(initializer_list<T> t, Compare comp);
+    minmax(initializer_list<T> t, Compare comp);  // constexpr in C++14
 
 template <class InputIterator1, class InputIterator2>
     bool
@@ -643,6 +643,9 @@ template <class BidirectionalIterator, c
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+// I'd like to replace these with _VSTD::equal_to<void>, but can't because:
+//   * That only works with C++14 and later, and
+//   * We haven't included <functional> here.
 template <class _T1, class _T2 = _T1>
 struct __equal_to
 {
@@ -655,46 +658,59 @@ struct __equal_to
 template <class _T1>
 struct __equal_to<_T1, _T1>
 {
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
 };
 
 template <class _T1>
 struct __equal_to<const _T1, _T1>
 {
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
 };
 
 template <class _T1>
 struct __equal_to<_T1, const _T1>
 {
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
 };
 
 template <class _T1, class _T2 = _T1>
 struct __less
 {
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const _T1& __x, const _T2& __y) const {return __x < __y;}
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const _T2& __x, const _T1& __y) const {return __x < __y;}
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const _T2& __x, const _T2& __y) const {return __x < __y;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 
+    bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T1& __x, const _T2& __y) const {return __x < __y;}
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T2& __x, const _T1& __y) const {return __x < __y;}
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T2& __x, const _T2& __y) const {return __x < __y;}
 };
 
 template <class _T1>
 struct __less<_T1, _T1>
 {
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
 };
 
 template <class _T1>
 struct __less<const _T1, _T1>
 {
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
 };
 
 template <class _T1>
 struct __less<_T1, const _T1>
 {
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
 };
 
 template <class _Predicate>
@@ -2505,9 +2521,9 @@ rotate_copy(_ForwardIterator __first, _F
 // min_element
 
 template <class _ForwardIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 _ForwardIterator
-min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
+__min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
 {
     if (__first != __last)
     {
@@ -2519,19 +2535,27 @@ min_element(_ForwardIterator __first, _F
     return __first;
 }
 
+template <class _ForwardIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator
+min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
+{
+    return __min_element(__first, __last, __comp);
+}
+
 template <class _ForwardIterator>
 inline _LIBCPP_INLINE_VISIBILITY
 _ForwardIterator
 min_element(_ForwardIterator __first, _ForwardIterator __last)
 {
-    return _VSTD::min_element(__first, __last,
+    return __min_element(__first, __last,
               __less<typename iterator_traits<_ForwardIterator>::value_type>());
 }
 
 // min
 
 template <class _Tp, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 const _Tp&
 min(const _Tp& __a, const _Tp& __b, _Compare __comp)
 {
@@ -2539,7 +2563,7 @@ min(const _Tp& __a, const _Tp& __b, _Com
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 const _Tp&
 min(const _Tp& __a, const _Tp& __b)
 {
@@ -2549,19 +2573,19 @@ min(const _Tp& __a, const _Tp& __b)
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 
 template<class _Tp, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 _Tp
 min(initializer_list<_Tp> __t, _Compare __comp)
 {
-    return *_VSTD::min_element(__t.begin(), __t.end(), __comp);
+    return *__min_element(__t.begin(), __t.end(), __comp);
 }
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 _Tp
 min(initializer_list<_Tp> __t)
 {
-    return *_VSTD::min_element(__t.begin(), __t.end());
+    return *__min_element(__t.begin(), __t.end(), __less<_Tp>());
 }
 
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
@@ -2569,9 +2593,9 @@ min(initializer_list<_Tp> __t)
 // max_element
 
 template <class _ForwardIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 _ForwardIterator
-max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
+__max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
 {
     if (__first != __last)
     {
@@ -2583,19 +2607,28 @@ max_element(_ForwardIterator __first, _F
     return __first;
 }
 
+
+template <class _ForwardIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator
+max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
+{
+    return __max_element(__first, __last, __comp);
+}
+
 template <class _ForwardIterator>
 inline _LIBCPP_INLINE_VISIBILITY
 _ForwardIterator
 max_element(_ForwardIterator __first, _ForwardIterator __last)
 {
-    return _VSTD::max_element(__first, __last,
+    return __max_element(__first, __last,
               __less<typename iterator_traits<_ForwardIterator>::value_type>());
 }
 
 // max
 
 template <class _Tp, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 const _Tp&
 max(const _Tp& __a, const _Tp& __b, _Compare __comp)
 {
@@ -2603,7 +2636,7 @@ max(const _Tp& __a, const _Tp& __b, _Com
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 const _Tp&
 max(const _Tp& __a, const _Tp& __b)
 {
@@ -2613,19 +2646,19 @@ max(const _Tp& __a, const _Tp& __b)
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 
 template<class _Tp, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 _Tp
 max(initializer_list<_Tp> __t, _Compare __comp)
 {
-    return *_VSTD::max_element(__t.begin(), __t.end(), __comp);
+    return *__max_element(__t.begin(), __t.end(), __comp);
 }
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 _Tp
 max(initializer_list<_Tp> __t)
 {
-    return *_VSTD::max_element(__t.begin(), __t.end());
+    return *__max_element(__t.begin(), __t.end(), __less<_Tp>());
 }
 
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
@@ -2684,13 +2717,14 @@ inline _LIBCPP_INLINE_VISIBILITY
 std::pair<_ForwardIterator, _ForwardIterator>
 minmax_element(_ForwardIterator __first, _ForwardIterator __last)
 {
-    return _VSTD::minmax_element(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());
+    return _VSTD::minmax_element(__first, __last,
+              __less<typename iterator_traits<_ForwardIterator>::value_type>());
 }
 
 // minmax
 
 template<class _Tp, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 pair<const _Tp&, const _Tp&>
 minmax(const _Tp& __a, const _Tp& __b, _Compare __comp)
 {
@@ -2699,7 +2733,7 @@ minmax(const _Tp& __a, const _Tp& __b, _
 }
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 pair<const _Tp&, const _Tp&>
 minmax(const _Tp& __a, const _Tp& __b)
 {
@@ -2708,24 +2742,49 @@ minmax(const _Tp& __a, const _Tp& __b)
 
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 
-template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+template<class _Tp, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 pair<_Tp, _Tp>
-minmax(initializer_list<_Tp> __t)
+minmax(initializer_list<_Tp> __t, _Compare __comp)
 {
-    pair<const _Tp*, const _Tp*> __p =
-                                   _VSTD::minmax_element(__t.begin(), __t.end());
-    return pair<_Tp, _Tp>(*__p.first, *__p.second);
+    typedef typename initializer_list<_Tp>::const_iterator _Iter;
+    _Iter __first = __t.begin();
+    _Iter __last  = __t.end();
+    std::pair<_Tp, _Tp> __result ( *__first, *__first );
+
+    ++__first;
+    if (__t.size() % 2 == 0)
+    {
+        if (__comp(*__first,  __result.first))
+            __result.first  = *__first;
+        else
+            __result.second = *__first;
+        ++__first;
+    }
+    
+    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;
+            }
+        else {
+            if (__comp(*__first, __result.first)) __result.first  = *__first;
+            if (__comp(__result.second, __prev))  __result.second = __prev;
+            }
+                
+        __first++;
+    }
+    return __result;
 }
 
-template<class _Tp, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 pair<_Tp, _Tp>
-minmax(initializer_list<_Tp> __t, _Compare __comp)
+minmax(initializer_list<_Tp> __t)
 {
-    pair<const _Tp*, const _Tp*> __p =
-                           _VSTD::minmax_element(__t.begin(), __t.end(), __comp);
-    return pair<_Tp, _Tp>(*__p.first, *__p.second);
+    return _VSTD::minmax(__t, __less<_Tp>());
 }
 
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS

Modified: libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/max.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/max.pass.cpp?rev=201697&r1=201696&r2=201697&view=diff
==============================================================================
--- libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/max.pass.cpp (original)
+++ libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/max.pass.cpp Wed Feb 19 10:51:35 2014
@@ -43,4 +43,12 @@ int main()
     test(x, y, x);
     test(y, x, x);
     }
+#if _LIBCPP_STD_VER > 11
+    {
+    constexpr int x = 1;
+    constexpr int y = 0;
+    static_assert(std::max(x, y) == x, "" );
+    static_assert(std::max(y, x) == x, "" );
+    }
+#endif
 }

Modified: libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/max_comp.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/max_comp.pass.cpp?rev=201697&r1=201696&r2=201697&view=diff
==============================================================================
--- libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/max_comp.pass.cpp (original)
+++ libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/max_comp.pass.cpp Wed Feb 19 10:51:35 2014
@@ -45,4 +45,12 @@ int main()
     test(x, y, std::greater<int>(), y);
     test(y, x, std::greater<int>(), y);
     }
+#if _LIBCPP_STD_VER > 11
+    {
+    constexpr int x = 1;
+    constexpr int y = 0;
+    static_assert(std::max(x, y, std::greater<int>()) == y, "" );
+    static_assert(std::max(y, x, std::greater<int>()) == y, "" );
+    }
+#endif
 }

Modified: libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/max_init_list.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/max_init_list.pass.cpp?rev=201697&r1=201696&r2=201697&view=diff
==============================================================================
--- libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/max_init_list.pass.cpp (original)
+++ libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/max_init_list.pass.cpp Wed Feb 19 10:51:35 2014
@@ -31,5 +31,12 @@ int main()
     assert(i == 3);
     i = std::max({1, 3, 2});
     assert(i == 3);
+#if _LIBCPP_STD_VER > 11
+    {
+    static_assert(std::max({1, 3, 2}) == 3, "");
+    static_assert(std::max({2, 1, 3}) == 3, "");
+    static_assert(std::max({3, 2, 1}) == 3, "");
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }

Modified: libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/max_init_list_comp.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/max_init_list_comp.pass.cpp?rev=201697&r1=201696&r2=201697&view=diff
==============================================================================
--- libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/max_init_list_comp.pass.cpp (original)
+++ libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/max_init_list_comp.pass.cpp Wed Feb 19 10:51:35 2014
@@ -32,5 +32,12 @@ int main()
     assert(i == 1);
     i = std::max({1, 3, 2}, std::greater<int>());
     assert(i == 1);
+#if _LIBCPP_STD_VER > 11
+    {
+    static_assert(std::max({1, 3, 2}, std::greater<int>()) == 1, "");
+    static_assert(std::max({2, 1, 3}, std::greater<int>()) == 1, "");
+    static_assert(std::max({3, 2, 1}, std::greater<int>()) == 1, "");
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }

Modified: libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/min.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/min.pass.cpp?rev=201697&r1=201696&r2=201697&view=diff
==============================================================================
--- libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/min.pass.cpp (original)
+++ libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/min.pass.cpp Wed Feb 19 10:51:35 2014
@@ -43,4 +43,12 @@ int main()
     test(x, y, y);
     test(y, x, y);
     }
+#if _LIBCPP_STD_VER > 11
+    {
+    constexpr int x = 1;
+    constexpr int y = 0;
+    static_assert(std::min(x, y) == y, "" );
+    static_assert(std::min(y, x) == y, "" );
+    }
+#endif
 }

Modified: libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/min_comp.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/min_comp.pass.cpp?rev=201697&r1=201696&r2=201697&view=diff
==============================================================================
--- libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/min_comp.pass.cpp (original)
+++ libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/min_comp.pass.cpp Wed Feb 19 10:51:35 2014
@@ -45,4 +45,12 @@ int main()
     test(x, y, std::greater<int>(), x);
     test(y, x, std::greater<int>(), x);
     }
+#if _LIBCPP_STD_VER > 11
+    {
+    constexpr int x = 1;
+    constexpr int y = 0;
+    static_assert(std::min(x, y, std::greater<int>()) == x, "" );
+    static_assert(std::min(y, x, std::greater<int>()) == x, "" );
+    }
+#endif
 }

Modified: libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/min_init_list.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/min_init_list.pass.cpp?rev=201697&r1=201696&r2=201697&view=diff
==============================================================================
--- libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/min_init_list.pass.cpp (original)
+++ libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/min_init_list.pass.cpp Wed Feb 19 10:51:35 2014
@@ -31,5 +31,12 @@ int main()
     assert(i == 1);
     i = std::min({1, 3, 2});
     assert(i == 1);
+#if _LIBCPP_STD_VER > 11
+    {
+    static_assert(std::min({1, 3, 2}) == 1, "");
+    static_assert(std::min({2, 1, 3}) == 1, "");
+    static_assert(std::min({3, 2, 1}) == 1, "");
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }

Modified: libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/min_init_list_comp.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/min_init_list_comp.pass.cpp?rev=201697&r1=201696&r2=201697&view=diff
==============================================================================
--- libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/min_init_list_comp.pass.cpp (original)
+++ libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/min_init_list_comp.pass.cpp Wed Feb 19 10:51:35 2014
@@ -32,5 +32,12 @@ int main()
     assert(i == 3);
     i = std::min({1, 3, 2}, std::greater<int>());
     assert(i == 3);
+#if _LIBCPP_STD_VER > 11
+    {
+    static_assert(std::min({1, 3, 2}, std::greater<int>()) == 3, "");
+    static_assert(std::min({2, 1, 3}, std::greater<int>()) == 3, "");
+    static_assert(std::min({3, 2, 1}, std::greater<int>()) == 3, "");
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }

Modified: libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/minmax.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/minmax.pass.cpp?rev=201697&r1=201696&r2=201697&view=diff
==============================================================================
--- libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/minmax.pass.cpp (original)
+++ libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/minmax.pass.cpp Wed Feb 19 10:51:35 2014
@@ -45,4 +45,18 @@ int main()
     test(x, y, y, x);
     test(y, x, y, x);
     }
+#if _LIBCPP_STD_VER > 11
+    {
+//  Note that you can't take a reference to a local var, since 
+//  it's address is not a compile-time constant.
+    constexpr static int x = 1;
+    constexpr static int y = 0;
+    constexpr auto p1 = std::minmax (x, y);
+    static_assert(p1.first  == y, "");
+    static_assert(p1.second == x, "");
+    constexpr auto p2 = std::minmax (y, x);
+    static_assert(p2.first  == y, "");
+    static_assert(p2.second == x, "");
+    }
+#endif
 }

Modified: libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/minmax_comp.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/minmax_comp.pass.cpp?rev=201697&r1=201696&r2=201697&view=diff
==============================================================================
--- libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/minmax_comp.pass.cpp (original)
+++ libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/minmax_comp.pass.cpp Wed Feb 19 10:51:35 2014
@@ -27,6 +27,7 @@ test(const T& a, const T& b, C c, const
     assert(&p.second == &y);
 }
 
+
 int main()
 {
     {
@@ -47,4 +48,18 @@ int main()
     test(x, y, std::greater<int>(), x, y);
     test(y, x, std::greater<int>(), x, y);
     }
+#if _LIBCPP_STD_VER > 11
+    {
+//  Note that you can't take a reference to a local var, since 
+//  it's address is not a compile-time constant.
+    constexpr static int x = 1;
+    constexpr static int y = 0;
+    constexpr auto p1 = std::minmax(x, y, std::greater<>());
+    static_assert(p1.first  == x, "");
+    static_assert(p1.second == y, "");
+    constexpr auto p2 = std::minmax(y, x, std::greater<>());
+    static_assert(p2.first  == x, "");
+    static_assert(p2.second == y, "");
+    }
+#endif
 }

Modified: libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/minmax_init_list.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/minmax_init_list.pass.cpp?rev=201697&r1=201696&r2=201697&view=diff
==============================================================================
--- libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/minmax_init_list.pass.cpp (original)
+++ libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/minmax_init_list.pass.cpp Wed Feb 19 10:51:35 2014
@@ -25,5 +25,15 @@ int main()
     assert((std::minmax({2, 3, 1}) == std::pair<int, int>(1, 3)));
     assert((std::minmax({3, 1, 2}) == std::pair<int, int>(1, 3)));
     assert((std::minmax({3, 2, 1}) == std::pair<int, int>(1, 3)));
+#if _LIBCPP_STD_VER > 11
+    {
+    static_assert((std::minmax({1, 2, 3}) == std::pair<int, int>(1, 3)), "");
+    static_assert((std::minmax({1, 3, 2}) == std::pair<int, int>(1, 3)), "");
+    static_assert((std::minmax({2, 1, 3}) == std::pair<int, int>(1, 3)), "");
+    static_assert((std::minmax({2, 3, 1}) == std::pair<int, int>(1, 3)), "");
+    static_assert((std::minmax({3, 1, 2}) == std::pair<int, int>(1, 3)), "");
+    static_assert((std::minmax({3, 2, 1}) == std::pair<int, int>(1, 3)), "");
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }

Modified: libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/minmax_init_list_comp.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/minmax_init_list_comp.pass.cpp?rev=201697&r1=201696&r2=201697&view=diff
==============================================================================
--- libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/minmax_init_list_comp.pass.cpp (original)
+++ libcxx/trunk/test/algorithms/alg.sorting/alg.min.max/minmax_init_list_comp.pass.cpp Wed Feb 19 10:51:35 2014
@@ -26,5 +26,15 @@ 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)));
+#if _LIBCPP_STD_VER > 11
+    {
+    static_assert((std::minmax({1, 2, 3}, std::greater<int>()) == std::pair<int, int>(3, 1)), "");
+    static_assert((std::minmax({1, 3, 2}, std::greater<int>()) == std::pair<int, int>(3, 1)), "");
+    static_assert((std::minmax({2, 1, 3}, std::greater<int>()) == std::pair<int, int>(3, 1)), "");
+    static_assert((std::minmax({2, 3, 1}, std::greater<int>()) == std::pair<int, int>(3, 1)), "");
+    static_assert((std::minmax({3, 1, 2}, std::greater<int>()) == std::pair<int, int>(3, 1)), "");
+    static_assert((std::minmax({3, 2, 1}, std::greater<int>()) == std::pair<int, int>(3, 1)), "");
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }





More information about the cfe-commits mailing list