mclow.lists created this revision. mclow.lists added a reviewer: EricWF. P0805R1 <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0805r1.html> is about comparing heterogenous containers.
This is the implementation for `array`, `vector`, `deque`, `list` and `forward_list`. The `tuple` bits will follow soon. I hope to land this immediately after it is adopted in Jacksonville. https://reviews.llvm.org/D43773 Files: include/array include/deque include/list 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
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" @@ -68,4 +83,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,57 @@ 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) +{ + const typename vector<_Tp1, _Allocator1>::size_type __sz = __x.size(); + return __sz == __y.size() && _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/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,56 @@ 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) +{ + return __x.size() == __y.size() && _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/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,57 @@ 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) +{ + const typename deque<_Tp1, _Allocator1>::size_type __sz = __x.size(); + return __sz == __y.size() && _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(), __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 !(__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 cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits