Fix for LWG Issue 2369: constexpr max(initializer_list) vs max_element
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@236952 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/algorithm b/include/algorithm
index 415059d..76f59f2 100644
--- a/include/algorithm
+++ b/include/algorithm
@@ -521,11 +521,11 @@
template <class ForwardIterator>
ForwardIterator
- min_element(ForwardIterator first, ForwardIterator last);
+ min_element(ForwardIterator first, ForwardIterator last); // constexpr in C++14
template <class ForwardIterator, class Compare>
ForwardIterator
- min_element(ForwardIterator first, ForwardIterator last, Compare comp);
+ min_element(ForwardIterator first, ForwardIterator last, Compare comp); // constexpr in C++14
template <class T>
const T&
@@ -545,11 +545,11 @@
template <class ForwardIterator>
ForwardIterator
- max_element(ForwardIterator first, ForwardIterator last);
+ max_element(ForwardIterator first, ForwardIterator last); // constexpr in C++14
template <class ForwardIterator, class Compare>
ForwardIterator
- max_element(ForwardIterator first, ForwardIterator last, Compare comp);
+ max_element(ForwardIterator first, ForwardIterator last, Compare comp); // constexpr in C++14
template <class T>
const T&
@@ -569,11 +569,11 @@
template<class ForwardIterator>
pair<ForwardIterator, ForwardIterator>
- minmax_element(ForwardIterator first, ForwardIterator last);
+ minmax_element(ForwardIterator first, ForwardIterator last); // constexpr in C++14
template<class ForwardIterator, class Compare>
pair<ForwardIterator, ForwardIterator>
- minmax_element(ForwardIterator first, ForwardIterator last, Compare comp);
+ minmax_element(ForwardIterator first, ForwardIterator last, Compare comp); // constexpr in C++14
template<class T>
pair<const T&, const T&>
@@ -2544,7 +2544,7 @@
template <class _ForwardIterator, class _Compare>
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)
{
@@ -2556,20 +2556,12 @@
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
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
_ForwardIterator
min_element(_ForwardIterator __first, _ForwardIterator __last)
{
- return __min_element(__first, __last,
+ return _VSTD::min_element(__first, __last,
__less<typename iterator_traits<_ForwardIterator>::value_type>());
}
@@ -2598,7 +2590,7 @@
_Tp
min(initializer_list<_Tp> __t, _Compare __comp)
{
- return *__min_element(__t.begin(), __t.end(), __comp);
+ return *_VSTD::min_element(__t.begin(), __t.end(), __comp);
}
template<class _Tp>
@@ -2606,7 +2598,7 @@
_Tp
min(initializer_list<_Tp> __t)
{
- return *__min_element(__t.begin(), __t.end(), __less<_Tp>());
+ return *_VSTD::min_element(__t.begin(), __t.end(), __less<_Tp>());
}
#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
@@ -2616,7 +2608,7 @@
template <class _ForwardIterator, class _Compare>
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)
{
@@ -2629,20 +2621,12 @@
}
-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
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
_ForwardIterator
max_element(_ForwardIterator __first, _ForwardIterator __last)
{
- return __max_element(__first, __last,
+ return _VSTD::max_element(__first, __last,
__less<typename iterator_traits<_ForwardIterator>::value_type>());
}
@@ -2671,7 +2655,7 @@
_Tp
max(initializer_list<_Tp> __t, _Compare __comp)
{
- return *__max_element(__t.begin(), __t.end(), __comp);
+ return *_VSTD::max_element(__t.begin(), __t.end(), __comp);
}
template<class _Tp>
@@ -2679,7 +2663,7 @@
_Tp
max(initializer_list<_Tp> __t)
{
- return *__max_element(__t.begin(), __t.end(), __less<_Tp>());
+ return *_VSTD::max_element(__t.begin(), __t.end(), __less<_Tp>());
}
#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
@@ -2687,6 +2671,7 @@
// minmax_element
template <class _ForwardIterator, class _Compare>
+_LIBCPP_CONSTEXPR_AFTER_CXX11
std::pair<_ForwardIterator, _ForwardIterator>
minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
{
@@ -2734,7 +2719,7 @@
}
template <class _ForwardIterator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
std::pair<_ForwardIterator, _ForwardIterator>
minmax_element(_ForwardIterator __first, _ForwardIterator __last)
{
diff --git a/test/std/algorithms/alg.sorting/alg.min.max/max_element.pass.cpp b/test/std/algorithms/alg.sorting/alg.min.max/max_element.pass.cpp
index 2788b19..2197b97 100644
--- a/test/std/algorithms/alg.sorting/alg.min.max/max_element.pass.cpp
+++ b/test/std/algorithms/alg.sorting/alg.min.max/max_element.pass.cpp
@@ -57,10 +57,24 @@
test<Iter>(1000);
}
+#if __cplusplus >= 201402L
+constexpr int il[] = { 2, 4, 6, 8, 7, 5, 3, 1 };
+#endif
+
+void constexpr_test()
+{
+#if __cplusplus >= 201402L
+ constexpr auto p = std::max_element(il,il+8);
+ static_assert ( *p == 8, "" );
+#endif
+}
+
int main()
{
test<forward_iterator<const int*> >();
test<bidirectional_iterator<const int*> >();
test<random_access_iterator<const int*> >();
test<const int*>();
+
+ constexpr_test ();
}
diff --git a/test/std/algorithms/alg.sorting/alg.min.max/max_element_comp.pass.cpp b/test/std/algorithms/alg.sorting/alg.min.max/max_element_comp.pass.cpp
index 74e9fe6..37c1813 100644
--- a/test/std/algorithms/alg.sorting/alg.min.max/max_element_comp.pass.cpp
+++ b/test/std/algorithms/alg.sorting/alg.min.max/max_element_comp.pass.cpp
@@ -75,6 +75,19 @@
delete [] a;
}
+#if __cplusplus >= 201402L
+constexpr int il[] = { 2, 4, 6, 8, 7, 5, 3, 1 };
+struct less { constexpr bool operator ()( const int &x, const int &y) const { return x < y; }};
+#endif
+
+void constexpr_test()
+{
+#if __cplusplus >= 201402L
+ constexpr auto p = std::max_element(il, il+8, less());
+ static_assert ( *p == 8, "" );
+#endif
+}
+
int main()
{
test<forward_iterator<const int*> >();
@@ -82,4 +95,6 @@
test<random_access_iterator<const int*> >();
test<const int*>();
test_eq();
+
+ constexpr_test();
}
diff --git a/test/std/algorithms/alg.sorting/alg.min.max/min_element.pass.cpp b/test/std/algorithms/alg.sorting/alg.min.max/min_element.pass.cpp
index fd41f7a..a9a9d61 100644
--- a/test/std/algorithms/alg.sorting/alg.min.max/min_element.pass.cpp
+++ b/test/std/algorithms/alg.sorting/alg.min.max/min_element.pass.cpp
@@ -57,10 +57,24 @@
test<Iter>(1000);
}
+#if __cplusplus >= 201402L
+constexpr int il[] = { 2, 4, 6, 8, 7, 5, 3, 1 };
+#endif
+
+void constexpr_test()
+{
+#if __cplusplus >= 201402L
+ constexpr auto p = std::min_element(il, il+8);
+ static_assert ( *p == 1, "" );
+#endif
+}
+
int main()
{
test<forward_iterator<const int*> >();
test<bidirectional_iterator<const int*> >();
test<random_access_iterator<const int*> >();
test<const int*>();
+
+ constexpr_test();
}
diff --git a/test/std/algorithms/alg.sorting/alg.min.max/min_element_comp.pass.cpp b/test/std/algorithms/alg.sorting/alg.min.max/min_element_comp.pass.cpp
index 2b5fdb1..9517f7e 100644
--- a/test/std/algorithms/alg.sorting/alg.min.max/min_element_comp.pass.cpp
+++ b/test/std/algorithms/alg.sorting/alg.min.max/min_element_comp.pass.cpp
@@ -75,6 +75,19 @@
delete [] a;
}
+#if __cplusplus >= 201402L
+constexpr int il[] = { 2, 4, 6, 8, 7, 5, 3, 1 };
+struct less { constexpr bool operator ()( const int &x, const int &y) const { return x < y; }};
+#endif
+
+void constexpr_test()
+{
+#if __cplusplus >= 201402L
+ constexpr auto p = std::min_element(il, il+8, less());
+ static_assert(*p == 1, "");
+#endif
+}
+
int main()
{
test<forward_iterator<const int*> >();
@@ -82,4 +95,6 @@
test<random_access_iterator<const int*> >();
test<const int*>();
test_eq();
+
+ constexpr_test();
}
diff --git a/test/std/algorithms/alg.sorting/alg.min.max/minmax_element.pass.cpp b/test/std/algorithms/alg.sorting/alg.min.max/minmax_element.pass.cpp
index 6cdb87d..915b1d1 100644
--- a/test/std/algorithms/alg.sorting/alg.min.max/minmax_element.pass.cpp
+++ b/test/std/algorithms/alg.sorting/alg.min.max/minmax_element.pass.cpp
@@ -74,10 +74,25 @@
}
}
+#if __cplusplus >= 201402L
+constexpr int il[] = { 2, 4, 6, 8, 7, 5, 3, 1 };
+#endif
+
+void constexpr_test()
+{
+#if __cplusplus >= 201402L
+ constexpr auto p = std::minmax_element(il, il+8);
+ static_assert ( *(p.first) == 1, "" );
+ static_assert ( *(p.second) == 8, "" );
+#endif
+}
+
int main()
{
test<forward_iterator<const int*> >();
test<bidirectional_iterator<const int*> >();
test<random_access_iterator<const int*> >();
test<const int*>();
+
+ constexpr_test();
}
diff --git a/test/std/algorithms/alg.sorting/alg.min.max/minmax_element_comp.pass.cpp b/test/std/algorithms/alg.sorting/alg.min.max/minmax_element_comp.pass.cpp
index cc0e66e..d3a067f 100644
--- a/test/std/algorithms/alg.sorting/alg.min.max/minmax_element_comp.pass.cpp
+++ b/test/std/algorithms/alg.sorting/alg.min.max/minmax_element_comp.pass.cpp
@@ -79,10 +79,26 @@
}
}
+#if __cplusplus >= 201402L
+constexpr int il[] = { 2, 4, 6, 8, 7, 5, 3, 1 };
+struct less { constexpr bool operator ()( const int &x, const int &y) const { return x < y; }};
+#endif
+
+void constexpr_test()
+{
+#if __cplusplus >= 201402L
+ constexpr auto p = std::minmax_element(il, il+8, less());
+ static_assert ( *(p.first) == 1, "" );
+ static_assert ( *(p.second) == 8, "" );
+#endif
+}
+
int main()
{
test<forward_iterator<const int*> >();
test<bidirectional_iterator<const int*> >();
test<random_access_iterator<const int*> >();
test<const int*>();
+
+ constexpr_test();
}