Index: include/array =================================================================== --- include/array +++ include/array @@ -85,6 +85,20 @@ template bool operator>=(const array& x, const array& y); +// C++20 +template + bool operator==(const array& x, const array& y); +template + bool operator!=(const array& x, const array& y); +template + bool operator<(const array& x, const array& y); +template + bool operator>(const array& x, const array& y); +template + bool operator<=(const array& x, const array& y); +template + bool operator>=(const array& x, const array& y); + template void swap(array& x, array& y) noexcept(noexcept(x.swap(y))); @@ -403,6 +417,59 @@ return !(__x < __y); } +#if _LIBCPP_STD_VER > 17 +template +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(), __y.end()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const array<_Tp1, _Size1>& __x, const array<_Tp2, _Size2>& __y) +{ + return !(__x == __y); +} + +template +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 +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>(const array<_Tp1, _Size1>& __x, const array<_Tp2, _Size2>& __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(const array<_Tp1, _Size1>& __x, const array<_Tp2, _Size2>& __y) +{ + return !(__y < __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>=(const array<_Tp1, _Size1>& __x, const array<_Tp2, _Size2>& __y) +{ + return !(__x < __y); +} +#endif + template inline _LIBCPP_INLINE_VISIBILITY typename enable_if Index: include/deque =================================================================== --- include/deque +++ include/deque @@ -141,6 +141,20 @@ template bool operator<=(const deque& x, const deque& y); +// C++20 +template + bool operator==(const deque& x, const deque& y); +template + bool operator< (const deque& x, const deque& y); +template + bool operator!=(const deque& x, const deque& y); +template + bool operator> (const deque& x, const deque& y); +template + bool operator>=(const deque& x, const deque& y); +template + bool operator<=(const deque& x, const deque& y); + // specialized algorithms: template void swap(deque& x, deque& y) @@ -2894,6 +2908,57 @@ return !(__y < __x); } +#if _LIBCPP_STD_VER > 17 +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const deque<_Tp1, _Allocator1>& __x, const deque<_Tp2, _Allocator2>& __y) +{ + const typename deque<_Tp1, _Allocator1>::size_type __sz = __x.size(); + return __sz == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const deque<_Tp1, _Allocator1>& __x, const deque<_Tp2, _Allocator2>& __y) +{ + return !(__x == __y); +} + +template +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 +inline _LIBCPP_INLINE_VISIBILITY +bool +operator> (const deque<_Tp1, _Allocator1>& __x, const deque<_Tp2, _Allocator2>& __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>=(const deque<_Tp1, _Allocator1>& __x, const deque<_Tp2, _Allocator2>& __y) +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(const deque<_Tp1, _Allocator1>& __x, const deque<_Tp2, _Allocator2>& __y) +{ + return !(__y < __x); +} +#endif + template inline _LIBCPP_INLINE_VISIBILITY void Index: include/forward_list =================================================================== --- include/forward_list +++ include/forward_list @@ -158,6 +158,20 @@ bool operator<=(const forward_list& x, const forward_list& y); +// C++20 +template + bool operator==(const forward_list& x, const forward_list& y); +template + bool operator< (const forward_list& x, const forward_list& y); +template + bool operator!=(const forward_list& x, const forward_list& y); +template + bool operator> (const forward_list& x, const forward_list& y); +template + bool operator>=(const forward_list& x, const forward_list& y); +template + bool operator<=(const forward_list& x, const forward_list& y); + template void swap(forward_list& x, forward_list& y) noexcept(noexcept(x.swap(y))); @@ -1709,6 +1723,54 @@ return !(__y < __x); } +#if _LIBCPP_STD_VER > 17 +template +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 +bool operator!=(const forward_list<_Tp1, _Allocator1>& __x, + const forward_list<_Tp2, _Allocator2>& __y) +{ + return !(__x == __y); +} + +template +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 +inline _LIBCPP_INLINE_VISIBILITY +bool operator> (const forward_list<_Tp1, _Allocator1>& __x, + const forward_list<_Tp2, _Allocator2>& __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool operator>=(const forward_list<_Tp1, _Allocator1>& __x, + const forward_list<_Tp2, _Allocator2>& __y) +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool operator<=(const forward_list<_Tp1, _Allocator1>& __x, + const forward_list<_Tp2, _Allocator2>& __y) +{ + return !(__y < __x); +} +#endif + template inline _LIBCPP_INLINE_VISIBILITY void Index: include/list =================================================================== --- include/list +++ include/list @@ -160,6 +160,20 @@ template bool operator<=(const list& x, const list& y); +// C++20 +template + bool operator==(const list& x, const list& y); +template + bool operator< (const list& x, const list& y); +template + bool operator!=(const list& x, const list& y); +template + bool operator> (const list& x, const list& y); +template + bool operator>=(const list& x, const list& y); +template + bool operator<=(const list& x, const list& y); + template void swap(list& x, list& y) noexcept(noexcept(x.swap(y))); @@ -2405,6 +2419,56 @@ return !(__y < __x); } +#if _LIBCPP_STD_VER > 17 +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const list<_Tp1, _Allocator1>& __x, const list<_Tp2, _Allocator2>& __y) +{ + return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin()); +} + +template +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 +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const list<_Tp1, _Allocator1>& __x, const list<_Tp2, _Allocator2>& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator> (const list<_Tp1, _Allocator1>& __x, const list<_Tp2, _Allocator2>& __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>=(const list<_Tp1, _Allocator1>& __x, const list<_Tp2, _Allocator2>& __y) +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(const list<_Tp1, _Allocator1>& __x, const list<_Tp2, _Allocator2>& __y) +{ + return !(__y < __x); +} +#endif + template inline _LIBCPP_INLINE_VISIBILITY void Index: include/vector =================================================================== --- include/vector +++ include/vector @@ -253,6 +253,20 @@ template bool operator>=(const vector& x, const vector& y); template bool operator<=(const vector& x, const vector& y); +// C++20 +template + bool operator==(const vector& x, const vector& y); +template + bool operator< (const vector& x, const vector& y); +template + bool operator!=(const vector& x, const vector& y); +template + bool operator> (const vector& x, const vector& y); +template + bool operator>=(const vector& x, const vector& y); +template + bool operator<=(const vector& x, const vector& y); + template void swap(vector& x, vector& y) noexcept(noexcept(x.swap(y))); @@ -3352,6 +3366,57 @@ return !(__y < __x); } +#if _LIBCPP_STD_VER > 17 +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const vector<_Tp1, _Allocator1>& __x, const vector<_Tp2, _Allocator2>& __y) +{ + const typename vector<_Tp1, _Allocator1>::size_type __sz = __x.size(); + return __sz == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const vector<_Tp1, _Allocator1>& __x, const vector<_Tp2, _Allocator2>& __y) +{ + return !(__x == __y); +} + +template +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 +inline _LIBCPP_INLINE_VISIBILITY +bool +operator> (const vector<_Tp1, _Allocator1>& __x, const vector<_Tp2, _Allocator2>& __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>=(const vector<_Tp1, _Allocator1>& __x, const vector<_Tp2, _Allocator2>& __y) +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(const vector<_Tp1, _Allocator1>& __x, const vector<_Tp2, _Allocator2>& __y) +{ + return !(__y < __x); +} +#endif + template inline _LIBCPP_INLINE_VISIBILITY void 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 const&, array const&); // bool operator>=(array const&, array const&); +// C++20 +// template +// bool operator==(const array& x, const array& y); +// template +// bool operator!=(const array& x, const array& y); +// template +// bool operator<(const array& x, const array& y); +// template +// bool operator>(const array& x, const array& y); +// template +// bool operator<=(const array& x, const array& y); +// template +// bool operator>=(const array& x, const array& y); + #include #include +#include #include #include "test_macros.h" @@ -68,4 +83,13 @@ TEST_IGNORE_NODISCARD (c1 == c1); TEST_IGNORE_NODISCARD (c1 < c1); } +#if TEST_STD_VER > 17 + { + std::array c1 = {{}}; + std::array 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 const&, array const&); // bool operator>=(array const&, array const&); +// C++20 +// template +// bool operator==(const array& x, const array& y); +// template +// bool operator!=(const array& x, const array& y); +// template +// bool operator<(const array& x, const array& y); +// template +// bool operator>(const array& x, const array& y); +// template +// bool operator<=(const array& x, const array& y); +// template +// bool operator>=(const array& x, const array& y); + #include -#include #include #include "test_macros.h" @@ -28,18 +41,25 @@ #include "disable_missing_braces_warning.h" template -void test_compare(const Array& LHS, const Array& RHS) { - typedef std::vector 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 +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 C; C c1 = {}; C c2 = {}; - test_compare(c1, c2); + test_compare(c1, c2, false, true); } + +#if TEST_STD_VER > 17 + { + std::array c0 = {{}}; + std::array c1 = {{4}}; + std::array c2 = {{4L}}; + std::array 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/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. +// +//===----------------------------------------------------------------------===// + +// + +// template bool operator==(const deque& x, const deque& y); +// template bool operator< (const deque& x, const deque& y); +// template bool operator!=(const deque& x, const deque& y); +// template bool operator> (const deque& x, const deque& y); +// template bool operator>=(const deque& x, const deque& y); +// template bool operator<=(const deque& x, const deque& y); +// +// C++20 +// template +// bool operator==(const deque& x, const deque& y); +// template +// bool operator< (const deque& x, const deque& y); +// template +// bool operator!=(const deque& x, const deque& y); +// template +// bool operator> (const deque& x, const deque& y); +// template +// bool operator>=(const deque& x, const deque& y); +// template +// bool operator<=(const deque& x, const deque& y); + + +#include +#include +#include + +#include "test_macros.h" + +template struct NoCompare {}; + +int main() +{ + { + typedef NoCompare<0> T; + typedef std::deque 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 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 c1 = {}; + std::deque 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. +// +//===----------------------------------------------------------------------===// + +// + +// template bool operator==(const deque& x, const deque& y); +// template bool operator< (const deque& x, const deque& y); +// template bool operator!=(const deque& x, const deque& y); +// template bool operator> (const deque& x, const deque& y); +// template bool operator>=(const deque& x, const deque& y); +// template bool operator<=(const deque& x, const deque& y); +// +// C++20 +// template +// bool operator==(const deque& x, const deque& y); +// template +// bool operator< (const deque& x, const deque& y); +// template +// bool operator!=(const deque& x, const deque& y); +// template +// bool operator> (const deque& x, const deque& y); +// template +// bool operator>=(const deque& x, const deque& y); +// template +// bool operator<=(const deque& x, const deque& y); + + +#include +#include + +#include "min_allocator.h" +#include "test_macros.h" + +template +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 +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 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 c0 = {}; + std::deque c1 = {4}; + std::deque c2 = {4L}; + std::deque c3 = {2}; + std::deque> 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. +// +//===----------------------------------------------------------------------===// + +// + +// template bool operator==(const forward_list& x, const forward_list& y); +// template bool operator< (const forward_list& x, const forward_list& y); +// template bool operator!=(const forward_list& x, const forward_list& y); +// template bool operator> (const forward_list& x, const forward_list& y); +// template bool operator>=(const forward_list& x, const forward_list& y); +// template bool operator<=(const forward_list& x, const forward_list& y); +// +// C++20 +// template +// bool operator==(const forward_list& x, const forward_list& y); +// template +// bool operator< (const forward_list& x, const forward_list& y); +// template +// bool operator!=(const forward_list& x, const forward_list& y); +// template +// bool operator> (const forward_list& x, const forward_list& y); +// template +// bool operator>=(const forward_list& x, const forward_list& y); +// template +// bool operator<=(const forward_list& x, const forward_list& y); + + +#include +#include +#include + +#include "test_macros.h" + +template struct NoCompare {}; + +int main() +{ + { + typedef NoCompare<0> T; + typedef std::forward_list 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 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 c1 = {}; + std::forward_list 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. +// +//===----------------------------------------------------------------------===// + +// + +// template bool operator==(const forward_list& x, const forward_list& y); +// template bool operator< (const forward_list& x, const forward_list& y); +// template bool operator!=(const forward_list& x, const forward_list& y); +// template bool operator> (const forward_list& x, const forward_list& y); +// template bool operator>=(const forward_list& x, const forward_list& y); +// template bool operator<=(const forward_list& x, const forward_list& y); +// +// C++20 +// template +// bool operator==(const forward_list& x, const forward_list& y); +// template +// bool operator< (const forward_list& x, const forward_list& y); +// template +// bool operator!=(const forward_list& x, const forward_list& y); +// template +// bool operator> (const forward_list& x, const forward_list& y); +// template +// bool operator>=(const forward_list& x, const forward_list& y); +// template +// bool operator<=(const forward_list& x, const forward_list& y); + + +#include +#include + +#include "min_allocator.h" +#include "test_macros.h" + +template +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 +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 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 c0 = {}; + std::forward_list c1 = {4}; + std::forward_list c2 = {4L}; + std::forward_list c3 = {2}; + std::forward_list> 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. +// +//===----------------------------------------------------------------------===// + +// + +// template bool operator==(const list& x, const list& y); +// template bool operator< (const list& x, const list& y); +// template bool operator!=(const list& x, const list& y); +// template bool operator> (const list& x, const list& y); +// template bool operator>=(const list& x, const list& y); +// template bool operator<=(const list& x, const list& y); +// +// C++20 +// template +// bool operator==(const list& x, const list& y); +// template +// bool operator< (const list& x, const list& y); +// template +// bool operator!=(const list& x, const list& y); +// template +// bool operator> (const list& x, const list& y); +// template +// bool operator>=(const list& x, const list& y); +// template +// bool operator<=(const list& x, const list& y); + + +#include +#include +#include + +#include "test_macros.h" + +template struct NoCompare {}; + +int main() +{ + { + typedef NoCompare<0> T; + typedef std::list 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 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 c1 = {}; + std::list 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. +// +//===----------------------------------------------------------------------===// + +// + +// template bool operator==(const list& x, const list& y); +// template bool operator< (const list& x, const list& y); +// template bool operator!=(const list& x, const list& y); +// template bool operator> (const list& x, const list& y); +// template bool operator>=(const list& x, const list& y); +// template bool operator<=(const list& x, const list& y); +// +// C++20 +// template +// bool operator==(const list& x, const list& y); +// template +// bool operator< (const list& x, const list& y); +// template +// bool operator!=(const list& x, const list& y); +// template +// bool operator> (const list& x, const list& y); +// template +// bool operator>=(const list& x, const list& y); +// template +// bool operator<=(const list& x, const list& y); + + +#include +#include + +#include "min_allocator.h" +#include "test_macros.h" + +template +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 +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 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 c0 = {}; + std::list c1 = {4}; + std::list c2 = {4L}; + std::list c3 = {2}; + std::list> 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. +// +//===----------------------------------------------------------------------===// + +// + +// template bool operator==(const vector& x, const vector& y); +// template bool operator< (const vector& x, const vector& y); +// template bool operator!=(const vector& x, const vector& y); +// template bool operator> (const vector& x, const vector& y); +// template bool operator>=(const vector& x, const vector& y); +// template bool operator<=(const vector& x, const vector& y); +// +// C++20 +// template +// bool operator==(const vector& x, const vector& y); +// template +// bool operator< (const vector& x, const vector& y); +// template +// bool operator!=(const vector& x, const vector& y); +// template +// bool operator> (const vector& x, const vector& y); +// template +// bool operator>=(const vector& x, const vector& y); +// template +// bool operator<=(const vector& x, const vector& y); + + +#include +#include +#include + +#include "test_macros.h" + +template struct NoCompare {}; + +int main() +{ + { + typedef NoCompare<0> T; + typedef std::vector 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 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 c1 = {}; + std::vector 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/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. +// +//===----------------------------------------------------------------------===// + +// + +// template bool operator==(const vector& x, const vector& y); +// template bool operator< (const vector& x, const vector& y); +// template bool operator!=(const vector& x, const vector& y); +// template bool operator> (const vector& x, const vector& y); +// template bool operator>=(const vector& x, const vector& y); +// template bool operator<=(const vector& x, const vector& y); +// +// C++20 +// template +// bool operator==(const vector& x, const vector& y); +// template +// bool operator< (const vector& x, const vector& y); +// template +// bool operator!=(const vector& x, const vector& y); +// template +// bool operator> (const vector& x, const vector& y); +// template +// bool operator>=(const vector& x, const vector& y); +// template +// bool operator<=(const vector& x, const vector& y); + + +#include +#include + +#include "min_allocator.h" +#include "test_macros.h" + +template +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 +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 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 c0 = {}; + std::vector c1 = {4}; + std::vector c2 = {4L}; + std::vector c3 = {2}; + std::vector> 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 +}