mclow.lists updated this revision to Diff 136582.
mclow.lists added a comment.
Add the `tuple` bits. Regularize the equality comparisons of the containers;
i.e, don't try to be clever - let the compiler be clever.
https://reviews.llvm.org/D43773
Files:
include/array
include/deque
include/forward_list
include/list
include/tuple
include/vector
test/std/containers/sequences/array/compare.fail.cpp
test/std/containers/sequences/array/compare.pass.cpp
test/std/containers/sequences/deque/compare.fail.cpp
test/std/containers/sequences/deque/compare.pass.cpp
test/std/containers/sequences/forwardlist/compare.fail.cpp
test/std/containers/sequences/forwardlist/compare.pass.cpp
test/std/containers/sequences/list/compare.fail.cpp
test/std/containers/sequences/list/compare.pass.cpp
test/std/containers/sequences/vector/compare.fail.cpp
test/std/containers/sequences/vector/compare.pass.cpp
test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp
test/std/utilities/tuple/tuple.tuple/tuple.rel/lt.pass.cpp
Index: test/std/utilities/tuple/tuple.tuple/tuple.rel/lt.pass.cpp
===================================================================
--- test/std/utilities/tuple/tuple.tuple/tuple.rel/lt.pass.cpp
+++ test/std/utilities/tuple/tuple.tuple/tuple.rel/lt.pass.cpp
@@ -35,6 +35,16 @@
#include "test_macros.h"
+
+template <bool isLess, bool isEqual, typename T1, typename T2>
+void compare (const T1 &t1, const T2 &t2)
+{
+ assert((t1 < t2) == ( isLess));
+ assert((t1 > t2) == (!isLess && !isEqual));
+ assert((t1 <= t2) == ( isLess || isEqual));
+ assert((t1 >= t2) == (!isLess || isEqual));
+}
+
int main()
{
{
@@ -208,5 +218,57 @@
static_assert(!(t1 > t2), "");
static_assert(!(t1 >= t2), "");
}
+ { // P0805
+ typedef std::tuple<> T0;
+ typedef std::tuple<long, int, double> T1;
+ typedef std::tuple<double, long> T2;
+ constexpr T0 t0;
+ constexpr T1 t1(1, 2, 3);
+ constexpr T2 t2(1, 2);
+ constexpr T1 t3(0, 1, 2); // common tail
+
+ // less, equal
+ compare<false, true >(t0, t0);
+ static_assert(!(t0 < t0), "");
+ static_assert(!(t0 > t0), "");
+ static_assert( (t0 <= t0), "");
+ static_assert( (t0 >= t0), "");
+
+ compare<true, false>(t0, t1);
+ static_assert( (t0 < t1), "");
+ static_assert(!(t0 > t1), "");
+ static_assert( (t0 <= t1), "");
+ static_assert(!(t0 >= t1), "");
+
+ compare<false, false>(t1, t0);
+ static_assert(!(t1 < t0), "");
+ static_assert( (t1 > t0), "");
+ static_assert(!(t1 <= t0), "");
+ static_assert( (t1 >= t0), "");
+
+ compare<false, false>(t1, t2);
+ static_assert(!(t1 < t2), "");
+ static_assert( (t1 > t2), "");
+ static_assert(!(t1 <= t2), "");
+ static_assert( (t1 >= t2), "");
+
+ compare<true, false>(t2, t1);
+ static_assert( (t2 < t1), "");
+ static_assert(!(t2 > t1), "");
+ static_assert( (t2 <= t1), "");
+ static_assert(!(t2 >= t1), "");
+
+ compare<false, false>(t2, t3);
+ static_assert(!(t2 < t3), "");
+ static_assert( (t2 > t3), "");
+ static_assert(!(t2 <= t3), "");
+ static_assert( (t2 >= t3), "");
+
+ compare<true, false>(t3, t2);
+ static_assert( (t3 < t2), "");
+ static_assert(!(t3 > t2), "");
+ static_assert( (t3 <= t2), "");
+ static_assert(!(t3 >= t2), "");
+ }
#endif
}
Index: test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp
===================================================================
--- test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp
+++ test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp
@@ -154,5 +154,20 @@
static_assert(!(t1 == t2), "");
static_assert(t1 != t2, "");
}
+ { // P0805
+ typedef std::tuple<long, int, double> T1;
+ typedef std::tuple<double, long> T2;
+ constexpr T1 t1(1, 2, 3);
+ constexpr T2 t2(1.1, 3);
+ constexpr T2 t3(1, 2);
+ static_assert(!(t1 == t2), "");
+ static_assert(!(t2 == t1), "");
+ static_assert(!(t1 == t3), "");
+ static_assert(!(t3 == t1), "");
+ static_assert( t1 != t2, "");
+ static_assert( t2 != t1, "");
+ static_assert( t1 != t3, "");
+ static_assert( t3 != t1, "");
+ }
#endif
}
Index: test/std/containers/sequences/vector/compare.pass.cpp
===================================================================
--- test/std/containers/sequences/vector/compare.pass.cpp
+++ test/std/containers/sequences/vector/compare.pass.cpp
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// template <class T, class Allocator> bool operator==(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
+// template <class T, class Allocator> bool operator< (const vector<T,Allocator>& x, const vector<T,Allocator>& y);
+// template <class T, class Allocator> bool operator!=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
+// template <class T, class Allocator> bool operator> (const vector<T,Allocator>& x, const vector<T,Allocator>& y);
+// template <class T, class Allocator> bool operator>=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
+// template <class T, class Allocator> bool operator<=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
+//
+// C++20
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator==(const vector<T1, Allocator1>& x, const vector<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator< (const vector<T1, Allocator1>& x, const vector<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator!=(const vector<T1, Allocator1>& x, const vector<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator> (const vector<T1, Allocator1>& x, const vector<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator>=(const vector<T1, Allocator1>& x, const vector<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator<=(const vector<T1, Allocator1>& x, const vector<T2, Allocator2>& y);
+
+
+#include <vector>
+#include <cassert>
+
+#include "min_allocator.h"
+#include "test_macros.h"
+
+template <class Vector>
+void test_compare(const Vector& LHS, const Vector& RHS, bool isLess, bool isEqual) {
+ assert((LHS == RHS) == isEqual);
+ assert((LHS != RHS) == !isEqual);
+ assert((LHS < RHS) == isLess);
+ assert((LHS <= RHS) == (isLess | isEqual));
+ assert((LHS > RHS) == !(isLess | isEqual));
+ assert((LHS >= RHS) == !isLess);
+}
+
+template <class Vector1, class Vector2>
+void test_compare(const Vector1& LHS, const Vector2& RHS, bool isLess, bool isEqual) {
+ assert((LHS == RHS) == isEqual);
+ assert((LHS != RHS) == !isEqual);
+ assert((LHS < RHS) == isLess);
+ assert((LHS <= RHS) == (isLess | isEqual));
+ assert((LHS > RHS) == !(isLess | isEqual));
+ assert((LHS >= RHS) == !isLess);
+}
+
+int main()
+{
+ {
+ typedef int T;
+ typedef std::vector<T> C;
+ C c0 = {};
+ C c1 = {1, 2, 3};
+ C c2 = {1, 2, 3};
+ C c3 = {3, 2, 1};
+ C c4 = {1, 2, 1};
+ test_compare(c0, c1, true, false);
+ test_compare(c1, c2, false, true);
+ test_compare(c1, c3, true, false);
+ test_compare(c1, c4, false, false);
+ }
+
+#if TEST_STD_VER > 17
+ {
+ std::vector<int> c0 = {};
+ std::vector<int> c1 = {4};
+ std::vector<long> c2 = {4L};
+ std::vector<short> c3 = {2};
+ std::vector<short, min_allocator<short>> c4 = {4};
+ test_compare(c0, c1, true, false); // same type, different lengths
+ test_compare(c0, c2, true, false); // different type, different lengths
+ test_compare(c1, c2, false, true); // different types, same length, same values
+ test_compare(c1, c3, false, false); // different types, same length, different values
+ test_compare(c1, c4, false, true); // different types, same length, same value, different allocator
+ }
+#endif
+}
Index: test/std/containers/sequences/vector/compare.fail.cpp
===================================================================
--- test/std/containers/sequences/vector/compare.fail.cpp
+++ test/std/containers/sequences/vector/compare.fail.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// template <class T, class Allocator> bool operator==(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
+// template <class T, class Allocator> bool operator< (const vector<T,Allocator>& x, const vector<T,Allocator>& y);
+// template <class T, class Allocator> bool operator!=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
+// template <class T, class Allocator> bool operator> (const vector<T,Allocator>& x, const vector<T,Allocator>& y);
+// template <class T, class Allocator> bool operator>=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
+// template <class T, class Allocator> bool operator<=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
+//
+// C++20
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator==(const vector<T1, Allocator1>& x, const vector<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator< (const vector<T1, Allocator1>& x, const vector<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator!=(const vector<T1, Allocator1>& x, const vector<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator> (const vector<T1, Allocator1>& x, const vector<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator>=(const vector<T1, Allocator1>& x, const vector<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator<=(const vector<T1, Allocator1>& x, const vector<T2, Allocator2>& y);
+
+
+#include <vector>
+#include <string>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <int Dummy> struct NoCompare {};
+
+int main()
+{
+ {
+ typedef NoCompare<0> T;
+ typedef std::vector<T> C;
+ C c1 = {};
+ // expected-error@algorithm:* 2 {{invalid operands to binary expression}}
+ TEST_IGNORE_NODISCARD (c1 == c1);
+ TEST_IGNORE_NODISCARD (c1 < c1);
+ }
+ {
+ typedef NoCompare<1> T;
+ typedef std::vector<T> C;
+ C c1 = {};
+ // expected-error@algorithm:* 2 {{invalid operands to binary expression}}
+ TEST_IGNORE_NODISCARD (c1 != c1);
+ TEST_IGNORE_NODISCARD (c1 > c1);
+ }
+
+#if TEST_STD_VER > 17
+ {
+ std::vector<int> c1 = {};
+ std::vector<std::string> c2 = {};
+ // expected-error@algorithm:* 3 {{invalid operands to binary expression}}
+ TEST_IGNORE_NODISCARD (c1 == c2);
+ TEST_IGNORE_NODISCARD (c1 < c2);
+ }
+#endif
+}
Index: test/std/containers/sequences/list/compare.pass.cpp
===================================================================
--- test/std/containers/sequences/list/compare.pass.cpp
+++ test/std/containers/sequences/list/compare.pass.cpp
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <list>
+
+// template <class T, class Allocator> bool operator==(const list<T,Allocator>& x, const list<T,Allocator>& y);
+// template <class T, class Allocator> bool operator< (const list<T,Allocator>& x, const list<T,Allocator>& y);
+// template <class T, class Allocator> bool operator!=(const list<T,Allocator>& x, const list<T,Allocator>& y);
+// template <class T, class Allocator> bool operator> (const list<T,Allocator>& x, const list<T,Allocator>& y);
+// template <class T, class Allocator> bool operator>=(const list<T,Allocator>& x, const list<T,Allocator>& y);
+// template <class T, class Allocator> bool operator<=(const list<T,Allocator>& x, const list<T,Allocator>& y);
+//
+// C++20
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator==(const list<T1, Allocator1>& x, const list<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator< (const list<T1, Allocator1>& x, const list<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator!=(const list<T1, Allocator1>& x, const list<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator> (const list<T1, Allocator1>& x, const list<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator>=(const list<T1, Allocator1>& x, const list<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator<=(const list<T1, Allocator1>& x, const list<T2, Allocator2>& y);
+
+
+#include <list>
+#include <cassert>
+
+#include "min_allocator.h"
+#include "test_macros.h"
+
+template <class List>
+void test_compare(const List& LHS, const List& RHS, bool isLess, bool isEqual) {
+ assert((LHS == RHS) == isEqual);
+ assert((LHS != RHS) == !isEqual);
+ assert((LHS < RHS) == isLess);
+ assert((LHS <= RHS) == (isLess | isEqual));
+ assert((LHS > RHS) == !(isLess | isEqual));
+ assert((LHS >= RHS) == !isLess);
+}
+
+template <class List1, class List2>
+void test_compare(const List1& LHS, const List2& RHS, bool isLess, bool isEqual) {
+ assert((LHS == RHS) == isEqual);
+ assert((LHS != RHS) == !isEqual);
+ assert((LHS < RHS) == isLess);
+ assert((LHS <= RHS) == (isLess | isEqual));
+ assert((LHS > RHS) == !(isLess | isEqual));
+ assert((LHS >= RHS) == !isLess);
+}
+
+int main()
+{
+ {
+ typedef int T;
+ typedef std::list<T> C;
+ C c0 = {};
+ C c1 = {1, 2, 3};
+ C c2 = {1, 2, 3};
+ C c3 = {3, 2, 1};
+ C c4 = {1, 2, 1};
+ test_compare(c0, c1, true, false);
+ test_compare(c1, c2, false, true);
+ test_compare(c1, c3, true, false);
+ test_compare(c1, c4, false, false);
+ }
+
+#if TEST_STD_VER > 17
+ {
+ std::list<int> c0 = {};
+ std::list<int> c1 = {4};
+ std::list<long> c2 = {4L};
+ std::list<short> c3 = {2};
+ std::list<short, min_allocator<short>> c4 = {4};
+ test_compare(c0, c1, true, false); // same type, different lengths
+ test_compare(c0, c2, true, false); // different type, different lengths
+ test_compare(c1, c2, false, true); // different types, same length, same values
+ test_compare(c1, c3, false, false); // different types, same length, different values
+ test_compare(c1, c4, false, true); // different types, same length, same value, different allocator
+ }
+#endif
+}
Index: test/std/containers/sequences/list/compare.fail.cpp
===================================================================
--- test/std/containers/sequences/list/compare.fail.cpp
+++ test/std/containers/sequences/list/compare.fail.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <list>
+
+// template <class T, class Allocator> bool operator==(const list<T,Allocator>& x, const list<T,Allocator>& y);
+// template <class T, class Allocator> bool operator< (const list<T,Allocator>& x, const list<T,Allocator>& y);
+// template <class T, class Allocator> bool operator!=(const list<T,Allocator>& x, const list<T,Allocator>& y);
+// template <class T, class Allocator> bool operator> (const list<T,Allocator>& x, const list<T,Allocator>& y);
+// template <class T, class Allocator> bool operator>=(const list<T,Allocator>& x, const list<T,Allocator>& y);
+// template <class T, class Allocator> bool operator<=(const list<T,Allocator>& x, const list<T,Allocator>& y);
+//
+// C++20
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator==(const list<T1, Allocator1>& x, const list<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator< (const list<T1, Allocator1>& x, const list<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator!=(const list<T1, Allocator1>& x, const list<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator> (const list<T1, Allocator1>& x, const list<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator>=(const list<T1, Allocator1>& x, const list<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator<=(const list<T1, Allocator1>& x, const list<T2, Allocator2>& y);
+
+
+#include <list>
+#include <string>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <int Dummy> struct NoCompare {};
+
+int main()
+{
+ {
+ typedef NoCompare<0> T;
+ typedef std::list<T> C;
+ C c1 = {};
+ // expected-error@algorithm:* 2 {{invalid operands to binary expression}}
+ TEST_IGNORE_NODISCARD (c1 == c1);
+ TEST_IGNORE_NODISCARD (c1 < c1);
+ }
+ {
+ typedef NoCompare<1> T;
+ typedef std::list<T> C;
+ C c1 = {};
+ // expected-error@algorithm:* 2 {{invalid operands to binary expression}}
+ TEST_IGNORE_NODISCARD (c1 != c1);
+ TEST_IGNORE_NODISCARD (c1 > c1);
+ }
+
+#if TEST_STD_VER > 17
+ {
+ std::list<int> c1 = {};
+ std::list<std::string> c2 = {};
+ // expected-error@algorithm:* 3 {{invalid operands to binary expression}}
+ TEST_IGNORE_NODISCARD (c1 == c2);
+ TEST_IGNORE_NODISCARD (c1 < c2);
+ }
+#endif
+}
Index: test/std/containers/sequences/forwardlist/compare.pass.cpp
===================================================================
--- test/std/containers/sequences/forwardlist/compare.pass.cpp
+++ test/std/containers/sequences/forwardlist/compare.pass.cpp
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <forward_list>
+
+// template <class T, class Allocator> bool operator==(const forward_list<T,Allocator>& x, const forward_list<T,Allocator>& y);
+// template <class T, class Allocator> bool operator< (const forward_list<T,Allocator>& x, const forward_list<T,Allocator>& y);
+// template <class T, class Allocator> bool operator!=(const forward_list<T,Allocator>& x, const forward_list<T,Allocator>& y);
+// template <class T, class Allocator> bool operator> (const forward_list<T,Allocator>& x, const forward_list<T,Allocator>& y);
+// template <class T, class Allocator> bool operator>=(const forward_list<T,Allocator>& x, const forward_list<T,Allocator>& y);
+// template <class T, class Allocator> bool operator<=(const forward_list<T,Allocator>& x, const forward_list<T,Allocator>& y);
+//
+// C++20
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator==(const forward_list<T1, Allocator1>& x, const forward_list<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator< (const forward_list<T1, Allocator1>& x, const forward_list<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator!=(const forward_list<T1, Allocator1>& x, const forward_list<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator> (const forward_list<T1, Allocator1>& x, const forward_list<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator>=(const forward_list<T1, Allocator1>& x, const forward_list<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator<=(const forward_list<T1, Allocator1>& x, const forward_list<T2, Allocator2>& y);
+
+
+#include <forward_list>
+#include <cassert>
+
+#include "min_allocator.h"
+#include "test_macros.h"
+
+template <class FList>
+void test_compare(const FList& LHS, const FList& RHS, bool isLess, bool isEqual) {
+ assert((LHS == RHS) == isEqual);
+ assert((LHS != RHS) == !isEqual);
+ assert((LHS < RHS) == isLess);
+ assert((LHS <= RHS) == (isLess | isEqual));
+ assert((LHS > RHS) == !(isLess | isEqual));
+ assert((LHS >= RHS) == !isLess);
+}
+
+template <class FList1, class FList2>
+void test_compare(const FList1& LHS, const FList2& RHS, bool isLess, bool isEqual) {
+ assert((LHS == RHS) == isEqual);
+ assert((LHS != RHS) == !isEqual);
+ assert((LHS < RHS) == isLess);
+ assert((LHS <= RHS) == (isLess | isEqual));
+ assert((LHS > RHS) == !(isLess | isEqual));
+ assert((LHS >= RHS) == !isLess);
+}
+
+int main()
+{
+ {
+ typedef int T;
+ typedef std::forward_list<T> C;
+ C c0 = {};
+ C c1 = {1, 2, 3};
+ C c2 = {1, 2, 3};
+ C c3 = {3, 2, 1};
+ C c4 = {1, 2, 1};
+ test_compare(c0, c1, true, false);
+ test_compare(c1, c2, false, true);
+ test_compare(c1, c3, true, false);
+ test_compare(c1, c4, false, false);
+ }
+
+#if TEST_STD_VER > 17
+ {
+ std::forward_list<int> c0 = {};
+ std::forward_list<int> c1 = {4};
+ std::forward_list<long> c2 = {4L};
+ std::forward_list<short> c3 = {2};
+ std::forward_list<short, min_allocator<short>> c4 = {4};
+ test_compare(c0, c1, true, false); // same type, different lengths
+ test_compare(c0, c2, true, false); // different type, different lengths
+ test_compare(c1, c2, false, true); // different types, same length, same values
+ test_compare(c1, c3, false, false); // different types, same length, different values
+ test_compare(c1, c4, false, true); // different types, same length, same value, different allocator
+ }
+#endif
+}
Index: test/std/containers/sequences/forwardlist/compare.fail.cpp
===================================================================
--- test/std/containers/sequences/forwardlist/compare.fail.cpp
+++ test/std/containers/sequences/forwardlist/compare.fail.cpp
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <forward_list>
+
+// template <class T, class Allocator> bool operator==(const forward_list<T,Allocator>& x, const forward_list<T,Allocator>& y);
+// template <class T, class Allocator> bool operator< (const forward_list<T,Allocator>& x, const forward_list<T,Allocator>& y);
+// template <class T, class Allocator> bool operator!=(const forward_list<T,Allocator>& x, const forward_list<T,Allocator>& y);
+// template <class T, class Allocator> bool operator> (const forward_list<T,Allocator>& x, const forward_list<T,Allocator>& y);
+// template <class T, class Allocator> bool operator>=(const forward_list<T,Allocator>& x, const forward_list<T,Allocator>& y);
+// template <class T, class Allocator> bool operator<=(const forward_list<T,Allocator>& x, const forward_list<T,Allocator>& y);
+//
+// C++20
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator==(const forward_list<T1, Allocator1>& x, const forward_list<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator< (const forward_list<T1, Allocator1>& x, const forward_list<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator!=(const forward_list<T1, Allocator1>& x, const forward_list<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator> (const forward_list<T1, Allocator1>& x, const forward_list<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator>=(const forward_list<T1, Allocator1>& x, const forward_list<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator<=(const forward_list<T1, Allocator1>& x, const forward_list<T2, Allocator2>& y);
+
+
+#include <forward_list>
+#include <string>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <int Dummy> struct NoCompare {};
+
+int main()
+{
+ {
+ typedef NoCompare<0> T;
+ typedef std::forward_list<T> C;
+ C c1 = {};
+ // expected-error@algorithm:* {{invalid operands to binary expression}}
+ // expected-error@forward_list:* {{invalid operands to binary expression}}
+ TEST_IGNORE_NODISCARD (c1 == c1);
+ TEST_IGNORE_NODISCARD (c1 < c1);
+ }
+ {
+ typedef NoCompare<1> T;
+ typedef std::forward_list<T> C;
+ C c1 = {};
+ // expected-error@algorithm:* {{invalid operands to binary expression}}
+ // expected-error@forward_list:* {{invalid operands to binary expression}}
+ TEST_IGNORE_NODISCARD (c1 != c1);
+ TEST_IGNORE_NODISCARD (c1 > c1);
+ }
+
+#if TEST_STD_VER > 17
+ {
+ std::forward_list<int> c1 = {};
+ std::forward_list<std::string> c2 = {};
+ // expected-error@algorithm:* 3 {{invalid operands to binary expression}}
+ TEST_IGNORE_NODISCARD (c1 == c2);
+ TEST_IGNORE_NODISCARD (c1 < c2);
+ }
+#endif
+}
Index: test/std/containers/sequences/deque/compare.pass.cpp
===================================================================
--- test/std/containers/sequences/deque/compare.pass.cpp
+++ test/std/containers/sequences/deque/compare.pass.cpp
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <deque>
+
+// template <class T, class Allocator> bool operator==(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
+// template <class T, class Allocator> bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
+// template <class T, class Allocator> bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
+// template <class T, class Allocator> bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
+// template <class T, class Allocator> bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
+// template <class T, class Allocator> bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
+//
+// C++20
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator==(const deque<T1, Allocator1>& x, const deque<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator< (const deque<T1, Allocator1>& x, const deque<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator!=(const deque<T1, Allocator1>& x, const deque<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator> (const deque<T1, Allocator1>& x, const deque<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator>=(const deque<T1, Allocator1>& x, const deque<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator<=(const deque<T1, Allocator1>& x, const deque<T2, Allocator2>& y);
+
+
+#include <deque>
+#include <cassert>
+
+#include "min_allocator.h"
+#include "test_macros.h"
+
+template <class Deque>
+void test_compare(const Deque& LHS, const Deque& RHS, bool isLess, bool isEqual) {
+ assert((LHS == RHS) == isEqual);
+ assert((LHS != RHS) == !isEqual);
+ assert((LHS < RHS) == isLess);
+ assert((LHS <= RHS) == (isLess | isEqual));
+ assert((LHS > RHS) == !(isLess | isEqual));
+ assert((LHS >= RHS) == !isLess);
+}
+
+template <class Deque1, class Deque2>
+void test_compare(const Deque1& LHS, const Deque2& RHS, bool isLess, bool isEqual) {
+ assert((LHS == RHS) == isEqual);
+ assert((LHS != RHS) == !isEqual);
+ assert((LHS < RHS) == isLess);
+ assert((LHS <= RHS) == (isLess | isEqual));
+ assert((LHS > RHS) == !(isLess | isEqual));
+ assert((LHS >= RHS) == !isLess);
+}
+
+int main()
+{
+ {
+ typedef int T;
+ typedef std::deque<T> C;
+ C c0 = {};
+ C c1 = {1, 2, 3};
+ C c2 = {1, 2, 3};
+ C c3 = {3, 2, 1};
+ C c4 = {1, 2, 1};
+ test_compare(c0, c1, true, false);
+ test_compare(c1, c2, false, true);
+ test_compare(c1, c3, true, false);
+ test_compare(c1, c4, false, false);
+ }
+
+#if TEST_STD_VER > 17
+ {
+ std::deque<int> c0 = {};
+ std::deque<int> c1 = {4};
+ std::deque<long> c2 = {4L};
+ std::deque<short> c3 = {2};
+ std::deque<short, min_allocator<short>> c4 = {4};
+ test_compare(c0, c1, true, false); // same type, different lengths
+ test_compare(c0, c2, true, false); // different type, different lengths
+ test_compare(c1, c2, false, true); // different types, same length, same values
+ test_compare(c1, c3, false, false); // different types, same length, different values
+ test_compare(c1, c4, false, true); // different types, same length, same value, different allocator
+ }
+#endif
+}
Index: test/std/containers/sequences/deque/compare.fail.cpp
===================================================================
--- test/std/containers/sequences/deque/compare.fail.cpp
+++ test/std/containers/sequences/deque/compare.fail.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <deque>
+
+// template <class T, class Allocator> bool operator==(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
+// template <class T, class Allocator> bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
+// template <class T, class Allocator> bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
+// template <class T, class Allocator> bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
+// template <class T, class Allocator> bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
+// template <class T, class Allocator> bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
+//
+// C++20
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator==(const deque<T1, Allocator1>& x, const deque<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator< (const deque<T1, Allocator1>& x, const deque<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator!=(const deque<T1, Allocator1>& x, const deque<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator> (const deque<T1, Allocator1>& x, const deque<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator>=(const deque<T1, Allocator1>& x, const deque<T2, Allocator2>& y);
+// template<class T1, class T2, class Allocator1, class Allocator2>
+// bool operator<=(const deque<T1, Allocator1>& x, const deque<T2, Allocator2>& y);
+
+
+#include <deque>
+#include <string>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <int Dummy> struct NoCompare {};
+
+int main()
+{
+ {
+ typedef NoCompare<0> T;
+ typedef std::deque<T> C;
+ C c1 = {};
+ // expected-error@algorithm:* 2 {{invalid operands to binary expression}}
+ TEST_IGNORE_NODISCARD (c1 == c1);
+ TEST_IGNORE_NODISCARD (c1 < c1);
+ }
+ {
+ typedef NoCompare<1> T;
+ typedef std::deque<T> C;
+ C c1 = {};
+ // expected-error@algorithm:* 2 {{invalid operands to binary expression}}
+ TEST_IGNORE_NODISCARD (c1 != c1);
+ TEST_IGNORE_NODISCARD (c1 > c1);
+ }
+
+#if TEST_STD_VER > 17
+ {
+ std::deque<int> c1 = {};
+ std::deque<std::string> c2 = {};
+ // expected-error@algorithm:* 3 {{invalid operands to binary expression}}
+ TEST_IGNORE_NODISCARD (c1 == c2);
+ TEST_IGNORE_NODISCARD (c1 < c2);
+ }
+#endif
+}
Index: test/std/containers/sequences/array/compare.pass.cpp
===================================================================
--- test/std/containers/sequences/array/compare.pass.cpp
+++ test/std/containers/sequences/array/compare.pass.cpp
@@ -16,9 +16,22 @@
// bool operator>(array<T, N> const&, array<T, N> const&);
// bool operator>=(array<T, N> const&, array<T, N> const&);
+// C++20
+// template <class T1, class T2, size_t N1, size_t N2>
+// bool operator==(const array<T1,N1>& x, const array<T2,N2>& y);
+// template <class T1, class T2, size_t N1, size_t N2>
+// bool operator!=(const array<T1,N1>& x, const array<T2,N2>& y);
+// template <class T1, class T2, size_t N1, size_t N2>
+// bool operator<(const array<T1,N1>& x, const array<T2,N2>& y);
+// template <class T1, class T2, size_t N1, size_t N2>
+// bool operator>(const array<T1,N1>& x, const array<T2,N2>& y);
+// template <class T1, class T2, size_t N1, size_t N2>
+// bool operator<=(const array<T1,N1>& x, const array<T2,N2>& y);
+// template <class T1, class T2, size_t N1, size_t N2>
+// bool operator>=(const array<T1,N1>& x, const array<T2,N2>& y);
+
#include <array>
-#include <vector>
#include <cassert>
#include "test_macros.h"
@@ -28,18 +41,25 @@
#include "disable_missing_braces_warning.h"
template <class Array>
-void test_compare(const Array& LHS, const Array& RHS) {
- typedef std::vector<typename Array::value_type> Vector;
- const Vector LHSV(LHS.begin(), LHS.end());
- const Vector RHSV(RHS.begin(), RHS.end());
- assert((LHS == RHS) == (LHSV == RHSV));
- assert((LHS != RHS) == (LHSV != RHSV));
- assert((LHS < RHS) == (LHSV < RHSV));
- assert((LHS <= RHS) == (LHSV <= RHSV));
- assert((LHS > RHS) == (LHSV > RHSV));
- assert((LHS >= RHS) == (LHSV >= RHSV));
+void test_compare(const Array& LHS, const Array& RHS, bool isLess, bool isEqual) {
+ assert((LHS == RHS) == isEqual);
+ assert((LHS != RHS) == !isEqual);
+ assert((LHS < RHS) == isLess);
+ assert((LHS <= RHS) == (isLess | isEqual));
+ assert((LHS > RHS) == !(isLess | isEqual));
+ assert((LHS >= RHS) == !isLess);
}
+template <class Array1, class Array2>
+void test_compare(const Array1& LHS, const Array2& RHS, bool isLess, bool isEqual) {
+ assert((LHS == RHS) == isEqual);
+ assert((LHS != RHS) == !isEqual);
+ assert((LHS < RHS) == isLess);
+ assert((LHS <= RHS) == (isLess | isEqual));
+ assert((LHS > RHS) == !(isLess | isEqual));
+ assert((LHS >= RHS) == !isLess);
+}
+
int main()
{
{
@@ -49,9 +69,9 @@
C c2 = {1, 2, 3};
C c3 = {3, 2, 1};
C c4 = {1, 2, 1};
- test_compare(c1, c2);
- test_compare(c1, c3);
- test_compare(c1, c4);
+ test_compare(c1, c2, false, true);
+ test_compare(c1, c3, true, false);
+ test_compare(c1, c4, false, false);
}
{
typedef int T;
@@ -58,6 +78,19 @@
typedef std::array<T, 0> C;
C c1 = {};
C c2 = {};
- test_compare(c1, c2);
+ test_compare(c1, c2, false, true);
}
+
+#if TEST_STD_VER > 17
+ {
+ std::array<int, 0> c0 = {{}};
+ std::array<int, 1> c1 = {{4}};
+ std::array<long, 1> c2 = {{4L}};
+ std::array<short, 1> c3 = {{2u}};
+ test_compare(c0, c1, true, false); // same type, different lengths
+ test_compare(c0, c2, true, false); // different type, different lengths
+ test_compare(c1, c2, false, true); // different types, same length, same values
+ test_compare(c1, c3, false, false); // different types, same length, different values
+ }
+#endif
}
Index: test/std/containers/sequences/array/compare.fail.cpp
===================================================================
--- test/std/containers/sequences/array/compare.fail.cpp
+++ test/std/containers/sequences/array/compare.fail.cpp
@@ -16,9 +16,24 @@
// bool operator>(array<T, N> const&, array<T, N> const&);
// bool operator>=(array<T, N> const&, array<T, N> const&);
+// C++20
+// template <class T1, class T2, size_t N1, size_t N2>
+// bool operator==(const array<T1,N1>& x, const array<T2,N2>& y);
+// template <class T1, class T2, size_t N1, size_t N2>
+// bool operator!=(const array<T1,N1>& x, const array<T2,N2>& y);
+// template <class T1, class T2, size_t N1, size_t N2>
+// bool operator<(const array<T1,N1>& x, const array<T2,N2>& y);
+// template <class T1, class T2, size_t N1, size_t N2>
+// bool operator>(const array<T1,N1>& x, const array<T2,N2>& y);
+// template <class T1, class T2, size_t N1, size_t N2>
+// bool operator<=(const array<T1,N1>& x, const array<T2,N2>& y);
+// template <class T1, class T2, size_t N1, size_t N2>
+// bool operator>=(const array<T1,N1>& x, const array<T2,N2>& y);
+
#include <array>
#include <vector>
+#include <string>
#include <cassert>
#include "test_macros.h"
@@ -27,19 +42,6 @@
// Disable the missing braces warning for this reason.
#include "disable_missing_braces_warning.h"
-template <class Array>
-void test_compare(const Array& LHS, const Array& RHS) {
- typedef std::vector<typename Array::value_type> Vector;
- const Vector LHSV(LHS.begin(), LHS.end());
- const Vector RHSV(RHS.begin(), RHS.end());
- assert((LHS == RHS) == (LHSV == RHSV));
- assert((LHS != RHS) == (LHSV != RHSV));
- assert((LHS < RHS) == (LHSV < RHSV));
- assert((LHS <= RHS) == (LHSV <= RHSV));
- assert((LHS > RHS) == (LHSV > RHSV));
- assert((LHS >= RHS) == (LHSV >= RHSV));
-}
-
template <int Dummy> struct NoCompare {};
int main()
@@ -68,4 +70,13 @@
TEST_IGNORE_NODISCARD (c1 == c1);
TEST_IGNORE_NODISCARD (c1 < c1);
}
+#if TEST_STD_VER > 17
+ {
+ std::array<int, 0> c1 = {{}};
+ std::array<std::string, 0> c2 = {{}};
+ // expected-error@algorithm:* 3 {{invalid operands to binary expression}}
+ TEST_IGNORE_NODISCARD (c1 == c2);
+ TEST_IGNORE_NODISCARD (c1 < c2);
+ }
+#endif
}
Index: include/vector
===================================================================
--- include/vector
+++ include/vector
@@ -253,6 +253,20 @@
template <class T, class Allocator> bool operator>=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
template <class T, class Allocator> bool operator<=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
+// C++20
+template<class T1, class T2, class Allocator1, class Allocator2>
+ bool operator==(const vector<T1, Allocator1>& x, const vector<T2, Allocator2>& y);
+template<class T1, class T2, class Allocator1, class Allocator2>
+ bool operator< (const vector<T1, Allocator1>& x, const vector<T2, Allocator2>& y);
+template<class T1, class T2, class Allocator1, class Allocator2>
+ bool operator!=(const vector<T1, Allocator1>& x, const vector<T2, Allocator2>& y);
+template<class T1, class T2, class Allocator1, class Allocator2>
+ bool operator> (const vector<T1, Allocator1>& x, const vector<T2, Allocator2>& y);
+template<class T1, class T2, class Allocator1, class Allocator2>
+ bool operator>=(const vector<T1, Allocator1>& x, const vector<T2, Allocator2>& y);
+template<class T1, class T2, class Allocator1, class Allocator2>
+ bool operator<=(const vector<T1, Allocator1>& x, const vector<T2, Allocator2>& y);
+
template <class T, class Allocator>
void swap(vector<T,Allocator>& x, vector<T,Allocator>& y)
noexcept(noexcept(x.swap(y)));
@@ -3352,6 +3366,58 @@
return !(__y < __x);
}
+#if _LIBCPP_STD_VER > 17
+template <class _Tp1, class _Tp2, class _Allocator1, class _Allocator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const vector<_Tp1, _Allocator1>& __x, const vector<_Tp2, _Allocator2>& __y)
+{
+ if (__x.size() != __y.size())
+ return false;
+ return _VSTD::equal(__x.begin(), __x.end(), __y.begin());
+}
+
+template <class _Tp1, class _Tp2, class _Allocator1, class _Allocator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const vector<_Tp1, _Allocator1>& __x, const vector<_Tp2, _Allocator2>& __y)
+{
+ return !(__x == __y);
+}
+
+template <class _Tp1, class _Tp2, class _Allocator1, class _Allocator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator< (const vector<_Tp1, _Allocator1>& __x, const vector<_Tp2, _Allocator2>& __y)
+{
+ return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
+}
+
+template <class _Tp1, class _Tp2, class _Allocator1, class _Allocator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator> (const vector<_Tp1, _Allocator1>& __x, const vector<_Tp2, _Allocator2>& __y)
+{
+ return __y < __x;
+}
+
+template <class _Tp1, class _Tp2, class _Allocator1, class _Allocator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const vector<_Tp1, _Allocator1>& __x, const vector<_Tp2, _Allocator2>& __y)
+{
+ return !(__x < __y);
+}
+
+template <class _Tp1, class _Tp2, class _Allocator1, class _Allocator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const vector<_Tp1, _Allocator1>& __x, const vector<_Tp2, _Allocator2>& __y)
+{
+ return !(__y < __x);
+}
+#endif
+
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
void
Index: include/tuple
===================================================================
--- include/tuple
+++ include/tuple
@@ -1111,6 +1111,10 @@
return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
}
+template <typename T>
+_LIBCPP_CONSTEXPR _LIBCPP_ALWAYS_INLINE
+const T& __min(const T& __x, const T& __y) { return __y < __x ? __y : __x; }
+
template <size_t _Ip>
struct __tuple_equal
{
@@ -1129,7 +1133,7 @@
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
bool operator()(const _Tp&, const _Up&)
{
- return true;
+ return tuple_size<_Tp>::value == tuple_size<_Up>::value;
}
};
@@ -1138,7 +1142,9 @@
bool
operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
{
- return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
+ if (sizeof...(_Tp) != sizeof...(_Up))
+ return false;
+ return __tuple_equal<__min(sizeof...(_Tp), sizeof...(_Up))>()(__x, __y);
}
template <class ..._Tp, class ..._Up>
@@ -1156,7 +1162,7 @@
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
bool operator()(const _Tp& __x, const _Up& __y)
{
- const size_t __idx = tuple_size<_Tp>::value - _Ip;
+ const size_t __idx = __min(tuple_size<_Tp>::value, tuple_size<_Up>::value) - _Ip;
if (_VSTD::get<__idx>(__x) < _VSTD::get<__idx>(__y))
return true;
if (_VSTD::get<__idx>(__y) < _VSTD::get<__idx>(__x))
@@ -1172,7 +1178,7 @@
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
bool operator()(const _Tp&, const _Up&)
{
- return false;
+ return tuple_size<_Tp>::value < tuple_size<_Up>::value;
}
};
@@ -1181,7 +1187,7 @@
bool
operator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
{
- return __tuple_less<sizeof...(_Tp)>()(__x, __y);
+ return __tuple_less<__min(sizeof...(_Tp), sizeof...(_Up))>()(__x, __y);
}
template <class ..._Tp, class ..._Up>
Index: include/list
===================================================================
--- include/list
+++ include/list
@@ -160,6 +160,20 @@
template <class T, class Alloc>
bool operator<=(const list<T,Alloc>& x, const list<T,Alloc>& y);
+// C++20
+template<class T1, class T2, class Allocator1, class Allocator2>
+ bool operator==(const list<T1, Allocator1>& x, const list<T2, Allocator2>& y);
+template<class T1, class T2, class Allocator1, class Allocator2>
+ bool operator< (const list<T1, Allocator1>& x, const list<T2, Allocator2>& y);
+template<class T1, class T2, class Allocator1, class Allocator2>
+ bool operator!=(const list<T1, Allocator1>& x, const list<T2, Allocator2>& y);
+template<class T1, class T2, class Allocator1, class Allocator2>
+ bool operator> (const list<T1, Allocator1>& x, const list<T2, Allocator2>& y);
+template<class T1, class T2, class Allocator1, class Allocator2>
+ bool operator>=(const list<T1, Allocator1>& x, const list<T2, Allocator2>& y);
+template<class T1, class T2, class Allocator1, class Allocator2>
+ bool operator<=(const list<T1, Allocator1>& x, const list<T2, Allocator2>& y);
+
template <class T, class Alloc>
void swap(list<T,Alloc>& x, list<T,Alloc>& y)
noexcept(noexcept(x.swap(y)));
@@ -2405,6 +2419,58 @@
return !(__y < __x);
}
+#if _LIBCPP_STD_VER > 17
+template <class _Tp1, class _Tp2, class _Allocator1, class _Allocator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const list<_Tp1, _Allocator1>& __x, const list<_Tp2, _Allocator2>& __y)
+{
+ if (__x.size() != __y.size())
+ return false;
+ return _VSTD::equal(__x.begin(), __x.end(), __y.begin());
+}
+
+template <class _Tp1, class _Tp2, class _Allocator1, class _Allocator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator< (const list<_Tp1, _Allocator1>& __x, const list<_Tp2, _Allocator2>& __y)
+{
+ return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
+}
+
+template <class _Tp1, class _Tp2, class _Allocator1, class _Allocator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const list<_Tp1, _Allocator1>& __x, const list<_Tp2, _Allocator2>& __y)
+{
+ return !(__x == __y);
+}
+
+template <class _Tp1, class _Tp2, class _Allocator1, class _Allocator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator> (const list<_Tp1, _Allocator1>& __x, const list<_Tp2, _Allocator2>& __y)
+{
+ return __y < __x;
+}
+
+template <class _Tp1, class _Tp2, class _Allocator1, class _Allocator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const list<_Tp1, _Allocator1>& __x, const list<_Tp2, _Allocator2>& __y)
+{
+ return !(__x < __y);
+}
+
+template <class _Tp1, class _Tp2, class _Allocator1, class _Allocator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const list<_Tp1, _Allocator1>& __x, const list<_Tp2, _Allocator2>& __y)
+{
+ return !(__y < __x);
+}
+#endif
+
template <class _Tp, class _Alloc>
inline _LIBCPP_INLINE_VISIBILITY
void
Index: include/forward_list
===================================================================
--- include/forward_list
+++ include/forward_list
@@ -158,6 +158,20 @@
bool operator<=(const forward_list<T, Allocator>& x,
const forward_list<T, Allocator>& y);
+// C++20
+template<class T1, class T2, class Allocator1, class Allocator2>
+ bool operator==(const forward_list<T1, Allocator1>& x, const forward_list<T2, Allocator2>& y);
+template<class T1, class T2, class Allocator1, class Allocator2>
+ bool operator< (const forward_list<T1, Allocator1>& x, const forward_list<T2, Allocator2>& y);
+template<class T1, class T2, class Allocator1, class Allocator2>
+ bool operator!=(const forward_list<T1, Allocator1>& x, const forward_list<T2, Allocator2>& y);
+template<class T1, class T2, class Allocator1, class Allocator2>
+ bool operator> (const forward_list<T1, Allocator1>& x, const forward_list<T2, Allocator2>& y);
+template<class T1, class T2, class Allocator1, class Allocator2>
+ bool operator>=(const forward_list<T1, Allocator1>& x, const forward_list<T2, Allocator2>& y);
+template<class T1, class T2, class Allocator1, class Allocator2>
+ bool operator<=(const forward_list<T1, Allocator1>& x, const forward_list<T2, Allocator2>& y);
+
template <class T, class Allocator>
void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
noexcept(noexcept(x.swap(y)));
@@ -1709,6 +1723,54 @@
return !(__y < __x);
}
+#if _LIBCPP_STD_VER > 17
+template <class _Tp1, class _Tp2, class _Allocator1, class _Allocator2>
+bool operator==(const forward_list<_Tp1, _Allocator1>& __x,
+ const forward_list<_Tp2, _Allocator2>& __y)
+{
+ return std::equal(__x.begin(), __x.end(), __y.begin(), __y.end());
+}
+
+template <class _Tp1, class _Tp2, class _Allocator1, class _Allocator2>
+bool operator!=(const forward_list<_Tp1, _Allocator1>& __x,
+ const forward_list<_Tp2, _Allocator2>& __y)
+{
+ return !(__x == __y);
+}
+
+template <class _Tp1, class _Tp2, class _Allocator1, class _Allocator2>
+bool operator< (const forward_list<_Tp1, _Allocator1>& __x,
+ const forward_list<_Tp2, _Allocator2>& __y)
+{
+ return _VSTD::lexicographical_compare(__x.begin(), __x.end(),
+ __y.begin(), __y.end());
+}
+
+template <class _Tp1, class _Tp2, class _Allocator1, class _Allocator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator> (const forward_list<_Tp1, _Allocator1>& __x,
+ const forward_list<_Tp2, _Allocator2>& __y)
+{
+ return __y < __x;
+}
+
+template <class _Tp1, class _Tp2, class _Allocator1, class _Allocator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator>=(const forward_list<_Tp1, _Allocator1>& __x,
+ const forward_list<_Tp2, _Allocator2>& __y)
+{
+ return !(__x < __y);
+}
+
+template <class _Tp1, class _Tp2, class _Allocator1, class _Allocator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator<=(const forward_list<_Tp1, _Allocator1>& __x,
+ const forward_list<_Tp2, _Allocator2>& __y)
+{
+ return !(__y < __x);
+}
+#endif
+
template <class _Tp, class _Alloc>
inline _LIBCPP_INLINE_VISIBILITY
void
Index: include/deque
===================================================================
--- include/deque
+++ include/deque
@@ -141,6 +141,20 @@
template <class T, class Allocator>
bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
+// C++20
+template<class T1, class T2, class Allocator1, class Allocator2>
+ bool operator==(const deque<T1, Allocator1>& x, const deque<T2, Allocator2>& y);
+template<class T1, class T2, class Allocator1, class Allocator2>
+ bool operator< (const deque<T1, Allocator1>& x, const deque<T2, Allocator2>& y);
+template<class T1, class T2, class Allocator1, class Allocator2>
+ bool operator!=(const deque<T1, Allocator1>& x, const deque<T2, Allocator2>& y);
+template<class T1, class T2, class Allocator1, class Allocator2>
+ bool operator> (const deque<T1, Allocator1>& x, const deque<T2, Allocator2>& y);
+template<class T1, class T2, class Allocator1, class Allocator2>
+ bool operator>=(const deque<T1, Allocator1>& x, const deque<T2, Allocator2>& y);
+template<class T1, class T2, class Allocator1, class Allocator2>
+ bool operator<=(const deque<T1, Allocator1>& x, const deque<T2, Allocator2>& y);
+
// specialized algorithms:
template <class T, class Allocator>
void swap(deque<T,Allocator>& x, deque<T,Allocator>& y)
@@ -2894,6 +2908,58 @@
return !(__y < __x);
}
+#if _LIBCPP_STD_VER > 17
+template <class _Tp1, class _Tp2, class _Allocator1, class _Allocator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const deque<_Tp1, _Allocator1>& __x, const deque<_Tp2, _Allocator2>& __y)
+{
+ if (__x.size() != __y.size())
+ return false;
+ return _VSTD::equal(__x.begin(), __x.end(), __y.begin());
+}
+
+template <class _Tp1, class _Tp2, class _Allocator1, class _Allocator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const deque<_Tp1, _Allocator1>& __x, const deque<_Tp2, _Allocator2>& __y)
+{
+ return !(__x == __y);
+}
+
+template <class _Tp1, class _Tp2, class _Allocator1, class _Allocator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator< (const deque<_Tp1, _Allocator1>& __x, const deque<_Tp2, _Allocator2>& __y)
+{
+ return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
+}
+
+template <class _Tp1, class _Tp2, class _Allocator1, class _Allocator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator> (const deque<_Tp1, _Allocator1>& __x, const deque<_Tp2, _Allocator2>& __y)
+{
+ return __y < __x;
+}
+
+template <class _Tp1, class _Tp2, class _Allocator1, class _Allocator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const deque<_Tp1, _Allocator1>& __x, const deque<_Tp2, _Allocator2>& __y)
+{
+ return !(__x < __y);
+}
+
+template <class _Tp1, class _Tp2, class _Allocator1, class _Allocator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const deque<_Tp1, _Allocator1>& __x, const deque<_Tp2, _Allocator2>& __y)
+{
+ return !(__y < __x);
+}
+#endif
+
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
void
Index: include/array
===================================================================
--- include/array
+++ include/array
@@ -85,6 +85,20 @@
template <class T, size_t N>
bool operator>=(const array<T,N>& x, const array<T,N>& y);
+// C++20
+template <class T1, class T2, size_t N1, size_t N2>
+ bool operator==(const array<T1,N1>& x, const array<T2,N2>& y);
+template <class T1, class T2, size_t N1, size_t N2>
+ bool operator!=(const array<T1,N1>& x, const array<T2,N2>& y);
+template <class T1, class T2, size_t N1, size_t N2>
+ bool operator<(const array<T1,N1>& x, const array<T2,N2>& y);
+template <class T1, class T2, size_t N1, size_t N2>
+ bool operator>(const array<T1,N1>& x, const array<T2,N2>& y);
+template <class T1, class T2, size_t N1, size_t N2>
+ bool operator<=(const array<T1,N1>& x, const array<T2,N2>& y);
+template <class T1, class T2, size_t N1, size_t N2>
+ bool operator>=(const array<T1,N1>& x, const array<T2,N2>& y);
+
template <class T, size_t N >
void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y)));
@@ -403,6 +417,59 @@
return !(__x < __y);
}
+#if _LIBCPP_STD_VER > 17
+template <class _Tp1, class _Tp2, size_t _Size1, size_t _Size2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const array<_Tp1, _Size1>& __x, const array<_Tp2, _Size2>& __y)
+{
+ if (_Size1 != _Size2)
+ return false;
+ return _VSTD::equal(__x.begin(), __x.end(), __y.begin());
+}
+
+template <class _Tp1, class _Tp2, size_t _Size1, size_t _Size2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const array<_Tp1, _Size1>& __x, const array<_Tp2, _Size2>& __y)
+{
+ return !(__x == __y);
+}
+
+template <class _Tp1, class _Tp2, size_t _Size1, size_t _Size2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(const array<_Tp1, _Size1>& __x, const array<_Tp2, _Size2>& __y)
+{
+ return _VSTD::lexicographical_compare(__x.begin(), __x.end(),
+ __y.begin(), __y.end());
+}
+
+template <class _Tp1, class _Tp2, size_t _Size1, size_t _Size2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(const array<_Tp1, _Size1>& __x, const array<_Tp2, _Size2>& __y)
+{
+ return __y < __x;
+}
+
+template <class _Tp1, class _Tp2, size_t _Size1, size_t _Size2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const array<_Tp1, _Size1>& __x, const array<_Tp2, _Size2>& __y)
+{
+ return !(__y < __x);
+}
+
+template <class _Tp1, class _Tp2, size_t _Size1, size_t _Size2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const array<_Tp1, _Size1>& __x, const array<_Tp2, _Size2>& __y)
+{
+ return !(__x < __y);
+}
+#endif
+
template <class _Tp, size_t _Size>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits