[libcxx-commits] [libcxx] 6614d36 - [libc++][spaceship] Additional tests for `operator<=>` `map` and `multimap`
Hristo Hristov via libcxx-commits
libcxx-commits at lists.llvm.org
Wed May 31 00:37:03 PDT 2023
Author: Hristo Hristov
Date: 2023-05-31T10:36:57+03:00
New Revision: 6614d36d711495c57d8971f2330065c7cd21b9ef
URL: https://github.com/llvm/llvm-project/commit/6614d36d711495c57d8971f2330065c7cd21b9ef
DIFF: https://github.com/llvm/llvm-project/commit/6614d36d711495c57d8971f2330065c7cd21b9ef.diff
LOG: [libc++][spaceship] Additional tests for `operator<=>` `map` and `multimap`
- Added additional tests
- Improved existing tests
- Moved misplaced test files to the correct location
Reviewed By: #libc, philnik
Differential Revision: https://reviews.llvm.org/D151205
Added:
libcxx/test/std/containers/associative/map/map.nonmember/compare.three_way.pass.cpp
libcxx/test/std/containers/associative/map/map.nonmember/compare.three_way.verify.cpp
libcxx/test/std/containers/associative/multimap/multimap.nonmember/compare.three_way.pass.cpp
libcxx/test/std/containers/associative/multimap/multimap.nonmember/compare.three_way.verify.cpp
Modified:
libcxx/test/support/test_container_comparisons.h
Removed:
libcxx/test/std/containers/associative/map/compare.three_way.pass.cpp
libcxx/test/std/containers/associative/multimap/compare.three_way.pass.cpp
################################################################################
diff --git a/libcxx/test/std/containers/associative/map/compare.three_way.pass.cpp b/libcxx/test/std/containers/associative/map/map.nonmember/compare.three_way.pass.cpp
similarity index 100%
rename from libcxx/test/std/containers/associative/map/compare.three_way.pass.cpp
rename to libcxx/test/std/containers/associative/map/map.nonmember/compare.three_way.pass.cpp
diff --git a/libcxx/test/std/containers/associative/map/map.nonmember/compare.three_way.verify.cpp b/libcxx/test/std/containers/associative/map/map.nonmember/compare.three_way.verify.cpp
new file mode 100644
index 0000000000000..a1cd2ab29bd2a
--- /dev/null
+++ b/libcxx/test/std/containers/associative/map/map.nonmember/compare.three_way.verify.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <map>
+
+// class map
+
+// template<class Key, class T, class Compare, class Allocator>
+// synth-three-way-result<pair<const Key, T>>
+// operator<=>(const map<Key, T, Compare, Allocator>& x,
+// const map<Key, T, Compare, Allocator>& y);
+
+#include <map>
+
+#include "test_allocator.h"
+
+int main(int, char**) {
+ // Mismatching allocators
+ {
+ std::map<int, int, std::less<int>, std::allocator<int>> s1;
+ std::map<int, int, std::less<int>, test_allocator<int>> s2;
+ // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed due to requirement 'is_same<int, std::pair<const int, int>>::value'{{.*}}Allocator::value_type must be same type as value_type}}
+ s1 <=> s2;
+ // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed due to requirement 'is_same<int, std::pair<const int, int>>::value'{{.*}}Allocator::value_type must be same type as value_type}}
+ s2 <=> s1;
+ }
+ // Mismatching comparision functions
+ {
+ std::map<int, int, std::less<int>> s1;
+ std::map<int, int, std::greater<int>> s2;
+ // expected-error at +1 {{invalid operands to binary expression}}
+ s1 <=> s2;
+ // expected-error at +1 {{invalid operands to binary expression}}
+ s2 <=> s1;
+ }
+ {
+ std::map<int, int, std::less<int>> s1;
+ std::map<int, int, std::less<float>> s2;
+ // expected-error at +1 {{invalid operands to binary expression}}
+ s1 <=> s2;
+ // expected-error at +1 {{invalid operands to binary expression}}
+ s2 <=> s1;
+ }
+ // Mismatching types
+ {
+ std::map<int, int> s1;
+ std::map<int, float> s2;
+ // expected-error at +1 {{invalid operands to binary expression}}
+ s1 <=> s2;
+ // expected-error at +1 {{invalid operands to binary expression}}
+ s2 <=> s1;
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/containers/associative/multimap/compare.three_way.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.nonmember/compare.three_way.pass.cpp
similarity index 100%
rename from libcxx/test/std/containers/associative/multimap/compare.three_way.pass.cpp
rename to libcxx/test/std/containers/associative/multimap/multimap.nonmember/compare.three_way.pass.cpp
diff --git a/libcxx/test/std/containers/associative/multimap/multimap.nonmember/compare.three_way.verify.cpp b/libcxx/test/std/containers/associative/multimap/multimap.nonmember/compare.three_way.verify.cpp
new file mode 100644
index 0000000000000..a6b3a0c99cf08
--- /dev/null
+++ b/libcxx/test/std/containers/associative/multimap/multimap.nonmember/compare.three_way.verify.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <map>
+
+// class multimap
+
+// template<class Key, class T, class Compare, class Allocator>
+// synth-three-way-result<pair<const Key, T>>
+// operator<=>(const multimap<Key, T, Compare, Allocator>& x,
+// const multimap<Key, T, Compare, Allocator>& y);
+
+#include <map>
+
+#include "test_allocator.h"
+
+int main(int, char**) {
+ // Mismatching allocators
+ {
+ std::multimap<int, int, std::less<int>, std::allocator<int>> s1;
+ std::multimap<int, int, std::less<int>, test_allocator<int>> s2;
+ // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed due to requirement 'is_same<int, std::pair<const int, int>>::value'{{.*}}Allocator::value_type must be same type as value_type}}
+ s1 <=> s2;
+ // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed due to requirement 'is_same<int, std::pair<const int, int>>::value'{{.*}}Allocator::value_type must be same type as value_type}}
+ s2 <=> s1;
+ }
+ // Mismatching comparision functions
+ {
+ std::multimap<int, int, std::less<int>> s1;
+ std::multimap<int, int, std::greater<int>> s2;
+ // expected-error at +1 {{invalid operands to binary expression}}
+ s1 <=> s2;
+ // expected-error at +1 {{invalid operands to binary expression}}
+ s2 <=> s1;
+ }
+ {
+ std::multimap<int, int, std::less<int>> s1;
+ std::multimap<int, int, std::less<float>> s2;
+ // expected-error at +1 {{invalid operands to binary expression}}
+ s1 <=> s2;
+ // expected-error at +1 {{invalid operands to binary expression}}
+ s2 <=> s1;
+ }
+ // Mismatching types
+ {
+ std::multimap<int, int> s1;
+ std::multimap<int, float> s2;
+ // expected-error at +1 {{invalid operands to binary expression}}
+ s1 <=> s2;
+ // expected-error at +1 {{invalid operands to binary expression}}
+ s2 <=> s1;
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/support/test_container_comparisons.h b/libcxx/test/support/test_container_comparisons.h
index d3b4033039c37..8748f2d8efdd3 100644
--- a/libcxx/test/support/test_container_comparisons.h
+++ b/libcxx/test/support/test_container_comparisons.h
@@ -10,6 +10,7 @@
#ifndef TEST_CONTAINER_COMPARISONS
#define TEST_CONTAINER_COMPARISONS
+#include <functional>
#include <set>
#include "test_comparisons.h"
@@ -84,103 +85,109 @@ constexpr bool test_sequence_container_spaceship() {
}
// Implementation detail of `test_ordered_map_container_spaceship`
-template <template <typename...> typename Container, typename Key, typename Val, typename Order>
-constexpr void test_ordered_map_container_spaceship_with_type() {
+template <template <typename...> typename Container, typename Key, typename Val, typename Order, typename Compare>
+constexpr void test_ordered_map_container_spaceship_with_type(Compare comp) {
// Empty containers
{
- Container<Key, Val> l1;
- Container<Key, Val> l2;
+ Container<Key, Val, Compare> l1{{}, comp};
+ Container<Key, Val, Compare> l2{{}, comp};
assert(testOrder(l1, l2, Order::equivalent));
}
// Identical contents
{
- Container<Key, Val> l1{{1, 1}, {2, 1}};
- Container<Key, Val> l2{{1, 1}, {2, 1}};
+ Container<Key, Val, Compare> l1{{{1, 1}, {2, 1}}, comp};
+ Container<Key, Val, Compare> l2{{{1, 1}, {2, 1}}, comp};
assert(testOrder(l1, l2, Order::equivalent));
}
// Less, due to contained values
{
- Container<Key, Val> l1{{1, 1}, {2, 1}};
- Container<Key, Val> l2{{1, 1}, {2, 2}};
+ Container<Key, Val, Compare> l1{{{1, 1}, {2, 1}}, comp};
+ Container<Key, Val, Compare> l2{{{1, 1}, {2, 2}}, comp};
assert(testOrder(l1, l2, Order::less));
}
// Greater, due to contained values
{
- Container<Key, Val> l1{{1, 1}, {2, 3}};
- Container<Key, Val> l2{{1, 1}, {2, 2}};
+ Container<Key, Val, Compare> l1{{{1, 1}, {2, 3}}, comp};
+ Container<Key, Val, Compare> l2{{{1, 1}, {2, 2}}, comp};
assert(testOrder(l1, l2, Order::greater));
}
// Shorter list
{
- Container<Key, Val> l1{{1, 1}};
- Container<Key, Val> l2{{1, 1}, {2, 2}};
+ Container<Key, Val, Compare> l1{{{1, 1}}, comp};
+ Container<Key, Val, Compare> l2{{{1, 1}, {2, 2}}, comp};
assert(testOrder(l1, l2, Order::less));
}
// Longer list
{
- Container<Key, Val> l1{{1, 2}, {2, 2}};
- Container<Key, Val> l2{{1, 1}};
+ Container<Key, Val, Compare> l1{{{1, 2}, {2, 2}}, comp};
+ Container<Key, Val, Compare> l2{{{1, 1}}, comp};
assert(testOrder(l1, l2, Order::greater));
}
// Unordered
if constexpr (std::is_same_v<Val, PartialOrder>) {
- Container<Key, Val> l1{{1, 1}, {2, std::numeric_limits<int>::min()}};
- Container<Key, Val> l2{{1, 1}, {2, 2}};
+ Container<Key, Val, Compare> l1{{{1, 1}, {2, std::numeric_limits<int>::min()}}, comp};
+ Container<Key, Val, Compare> l2{{{1, 1}, {2, 2}}, comp};
assert(testOrder(l1, l2, Order::unordered));
}
// Identical contents
{
- Container<Key, Val> l1{{1, 1}, {2, 1}, {2, 2}};
- Container<Key, Val> l2{{1, 1}, {2, 1}, {2, 2}};
+ Container<Key, Val, Compare> l1{{{1, 1}, {2, 1}, {2, 2}}, comp};
+ Container<Key, Val, Compare> l2{{{1, 1}, {2, 1}, {2, 2}}, comp};
assert(testOrder(l1, l2, Order::equivalent));
- Container<Key, Val> l3{{1, 1}, {2, 1}, {2, 2}};
- Container<Key, Val> l4{{2, 1}, {2, 2}, {1, 1}};
+
+ Container<Key, Val, Compare> l3{{{1, 1}, {2, 1}, {2, 2}}, comp};
+ Container<Key, Val, Compare> l4{{{2, 1}, {2, 2}, {1, 1}}, comp};
assert(testOrder(l3, l4, Order::equivalent));
}
// Less, due to contained values
{
- Container<Key, Val> l1{{1, 1}, {2, 1}, {2, 1}};
- Container<Key, Val> l2{{1, 1}, {2, 2}, {2, 2}};
+ Container<Key, Val, Compare> l1{{{1, 1}, {2, 1}, {2, 1}}, comp};
+ Container<Key, Val, Compare> l2{{{1, 1}, {2, 2}, {2, 2}}, comp};
assert(testOrder(l1, l2, Order::less));
- Container<Key, Val> l3{{1, 1}, {2, 1}, {2, 1}};
- Container<Key, Val> l4{{2, 2}, {2, 2}, {1, 1}};
+
+ Container<Key, Val, Compare> l3{{{1, 1}, {2, 1}, {2, 1}}, comp};
+ Container<Key, Val, Compare> l4{{{2, 2}, {2, 2}, {1, 1}}, comp};
assert(testOrder(l3, l4, Order::less));
}
// Greater, due to contained values
{
- Container<Key, Val> l1{{1, 1}, {2, 3}, {2, 3}};
- Container<Key, Val> l2{{1, 1}, {2, 2}, {2, 2}};
+ Container<Key, Val, Compare> l1{{{1, 1}, {2, 3}, {2, 3}}, comp};
+ Container<Key, Val, Compare> l2{{{1, 1}, {2, 2}, {2, 2}}, comp};
assert(testOrder(l1, l2, Order::greater));
- Container<Key, Val> l3{{1, 1}, {2, 3}, {2, 3}};
- Container<Key, Val> l4{{2, 2}, {2, 2}, {1, 1}};
+
+ Container<Key, Val, Compare> l3{{{1, 1}, {2, 3}, {2, 3}}, comp};
+ Container<Key, Val, Compare> l4{{{2, 2}, {2, 2}, {1, 1}}, comp};
assert(testOrder(l3, l4, Order::greater));
}
// Shorter list
{
- Container<Key, Val> l1{{1, 1}, {2, 2}};
- Container<Key, Val> l2{{1, 1}, {2, 2}, {2, 2}, {3, 1}};
+ Container<Key, Val, Compare> l1{{{1, 1}, {2, 2}}, comp};
+ Container<Key, Val, Compare> l2{{{1, 1}, {2, 2}, {2, 2}, {3, 1}}, comp};
assert(testOrder(l1, l2, Order::less));
- Container<Key, Val> l3{{1, 1}, {2, 2}};
- Container<Key, Val> l4{{3, 1}, {2, 2}, {2, 2}, {1, 1}};
+
+ Container<Key, Val, Compare> l3{{{1, 1}, {2, 2}}, comp};
+ Container<Key, Val, Compare> l4{{{3, 1}, {2, 2}, {2, 2}, {1, 1}}, comp};
assert(testOrder(l3, l4, Order::less));
}
// Longer list
{
- Container<Key, Val> l1{{1, 2}, {2, 2}, {2, 2}, {3, 1}};
- Container<Key, Val> l2{{1, 1}, {2, 2}};
+ Container<Key, Val, Compare> l1{{{1, 2}, {2, 2}, {2, 2}, {3, 1}}, comp};
+ Container<Key, Val, Compare> l2{{{1, 1}, {2, 2}}, comp};
assert(testOrder(l1, l2, Order::greater));
- Container<Key, Val> l3{{1, 2}, {2, 2}, {2, 2}, {3, 1}};
- Container<Key, Val> l4{{2, 2}, {1, 1}};
+
+ Container<Key, Val, Compare> l3{{{1, 2}, {2, 2}, {2, 2}, {3, 1}}, comp};
+ Container<Key, Val, Compare> l4{{{2, 2}, {1, 1}}, comp};
assert(testOrder(l3, l4, Order::greater));
}
// Unordered
if constexpr (std::is_same_v<Val, PartialOrder>) {
- Container<Key, Val> l1{{1, 1}, {2, std::numeric_limits<int>::min()}, {2, 3}};
- Container<Key, Val> l2{{1, 1}, {2, 2}, {2, 3}};
+ Container<Key, Val, Compare> l1{{{1, 1}, {2, std::numeric_limits<int>::min()}, {2, 3}}, comp};
+ Container<Key, Val, Compare> l2{{{1, 1}, {2, 2}, {2, 3}}, comp};
assert(testOrder(l1, l2, Order::unordered));
- Container<Key, Val> l3{{1, 1}, {2, std::numeric_limits<int>::min()}, {2, 3}};
- Container<Key, Val> l4{{2, 3}, {2, 2}, {1, 1}};
+
+ Container<Key, Val, Compare> l3{{{1, 1}, {2, std::numeric_limits<int>::min()}, {2, 3}}, comp};
+ Container<Key, Val, Compare> l4{{{2, 3}, {2, 2}, {1, 1}}, comp};
assert(testOrder(l3, l4, Order::unordered));
}
}
@@ -188,21 +195,25 @@ constexpr void test_ordered_map_container_spaceship_with_type() {
// Tests the `operator<=>` on ordered map containers
template <template <typename...> typename Container>
constexpr bool test_ordered_map_container_spaceship() {
+ // Thanks to SFINAE, the following is not a compiler error but returns `false`
+ struct NonComparable {};
+ static_assert(!std::three_way_comparable<Container<int, NonComparable>>);
+
// The container should fulfill `std::three_way_comparable`
static_assert(std::three_way_comparable<Container<int, int>>);
// Test
diff erent comparison categories
- test_ordered_map_container_spaceship_with_type<Container, int, int, std::strong_ordering>();
- test_ordered_map_container_spaceship_with_type<Container, int, StrongOrder, std::strong_ordering>();
- test_ordered_map_container_spaceship_with_type<Container, int, WeakOrder, std::weak_ordering>();
- test_ordered_map_container_spaceship_with_type<Container, int, PartialOrder, std::partial_ordering>();
+ test_ordered_map_container_spaceship_with_type<Container, int, int, std::strong_ordering>(std::less{});
+ test_ordered_map_container_spaceship_with_type<Container, int, int, std::strong_ordering>(std::greater{});
+ test_ordered_map_container_spaceship_with_type<Container, int, StrongOrder, std::strong_ordering>(std::less{});
+ test_ordered_map_container_spaceship_with_type<Container, int, StrongOrder, std::strong_ordering>(std::greater{});
+ test_ordered_map_container_spaceship_with_type<Container, int, WeakOrder, std::weak_ordering>(std::less{});
+ test_ordered_map_container_spaceship_with_type<Container, int, WeakOrder, std::weak_ordering>(std::greater{});
+ test_ordered_map_container_spaceship_with_type<Container, int, PartialOrder, std::partial_ordering>(std ::less{});
+ test_ordered_map_container_spaceship_with_type<Container, int, PartialOrder, std::partial_ordering>(std ::greater{});
// `LessAndEqComp` does not have `operator<=>`. Ordering is synthesized based on `operator<`
- test_ordered_map_container_spaceship_with_type<Container, int, LessAndEqComp, std::weak_ordering>();
-
- // Thanks to SFINAE, the following is not a compiler error but returns `false`
- struct NonComparable {};
- static_assert(!std::three_way_comparable<Container<int, NonComparable>>);
+ test_ordered_map_container_spaceship_with_type<Container, int, LessAndEqComp, std::weak_ordering>(std::less{});
return true;
}
More information about the libcxx-commits
mailing list