-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[libc++] NFCI: Restore code duplication in wrap_iter, with test.
It turns out that D105040 broke `std::rel_ops`; we actually do need both a one-template-parameter and a two-template-parameter version of all the comparison operators, because if we have only the heterogeneous two-parameter version, then `x > x` is ambiguous: template<class T, class U> int f(S<T>, S<U>) { return 1; } template<class T> int f(T, T) { return 2; } // rel_ops S<int> s; f(s,s); // ambiguous between #1 and #2 Adding the one-template-parameter version fixes the ambiguity: template<class T, class U> int f(S<T>, S<U>) { return 1; } template<class T> int f(T, T) { return 2; } // rel_ops template<class T> int f(S<T>, S<T>) { return 3; } S<int> s; f(s,s); // #3 beats both #1 and #2 We have the same problem with `reverse_iterator` as with `__wrap_iter`. But so do libstdc++ and Microsoft, so we're not going to worry about it. Differential Revision: https://reviews.llvm.org/D105894
- Loading branch information
1 parent
f352994
commit 0ddc58a
Showing
2 changed files
with
186 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
140 changes: 140 additions & 0 deletions
140
libcxx/test/std/containers/iterator.rel_ops.compile.pass.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// 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: libcpp-has-no-filesystem-library | ||
|
||
// Make sure the various containers' iterators are not broken by the use of `std::rel_ops`. | ||
|
||
#include <utility> // for std::rel_ops | ||
|
||
#include <array> | ||
#include <deque> | ||
#include <forward_list> | ||
#include <list> | ||
#include <map> | ||
#include <set> | ||
#include <string> | ||
#include <unordered_map> | ||
#include <unordered_set> | ||
#include <vector> | ||
|
||
#include "test_macros.h" | ||
|
||
#if TEST_STD_VER >= 11 | ||
#include "filesystem_include.h" | ||
#endif | ||
|
||
#if TEST_STD_VER >= 17 | ||
#include <string_view> | ||
#endif | ||
|
||
#if TEST_STD_VER >= 20 | ||
#include <span> | ||
#endif | ||
|
||
using namespace std::rel_ops; | ||
|
||
template<class It, class ConstIt> | ||
void test_eq(It it, ConstIt cit) { | ||
(void)(it == it); | ||
(void)(it != it); | ||
(void)(it == cit); | ||
(void)(it != cit); | ||
(void)(cit == it); | ||
(void)(cit != it); | ||
(void)(cit == cit); | ||
(void)(cit != cit); | ||
} | ||
|
||
template<class It, class ConstIt> | ||
void test_lt(It it, ConstIt cit) { | ||
(void)(it < it); | ||
(void)(it <= it); | ||
(void)(it > it); | ||
(void)(it >= it); | ||
(void)(it < cit); | ||
(void)(it <= cit); | ||
(void)(it > cit); | ||
(void)(it >= cit); | ||
(void)(cit < it); | ||
(void)(cit <= it); | ||
(void)(cit > it); | ||
(void)(cit >= it); | ||
(void)(cit < cit); | ||
(void)(cit <= cit); | ||
(void)(cit > cit); | ||
(void)(cit >= cit); | ||
|
||
// Test subtraction too, even though std::rel_ops shouldn't affect it. | ||
|
||
(void)(it - it); | ||
(void)(it - cit); | ||
(void)(cit - it); | ||
(void)(cit - cit); | ||
} | ||
|
||
template<class Container> | ||
void test_forward() { | ||
// There is no need to distinguish "forward" from "bidirectional." | ||
// libc++ already can't handle `c.rbegin() >= c.rbegin()` in the | ||
// presence of std::rel_ops, and neither can Microsoft nor libstdc++. | ||
|
||
Container c; | ||
typename Container::iterator it = c.begin(); | ||
typename Container::const_iterator cit = c.begin(); | ||
test_eq(it, cit); | ||
} | ||
|
||
template<class Container> | ||
void test_random_access() { | ||
Container c; | ||
typename Container::iterator it = c.begin(); | ||
typename Container::const_iterator cit = c.begin(); | ||
test_eq(it, cit); | ||
test_lt(it, cit); | ||
} | ||
|
||
template void test_random_access<std::array<int, 10> >(); | ||
template void test_random_access<std::deque<int> >(); | ||
template void test_forward<std::forward_list<int> >(); | ||
template void test_forward<std::list<int> >(); | ||
template void test_forward<std::map<int, int> >(); | ||
template void test_forward<std::multimap<int, int> >(); | ||
template void test_forward<std::multiset<int> >(); | ||
template void test_forward<std::set<int> >(); | ||
template void test_random_access<std::string>(); | ||
template void test_forward<std::unordered_map<int, int> >(); | ||
template void test_forward<std::unordered_multimap<int, int> >(); | ||
template void test_forward<std::unordered_multiset<int> >(); | ||
template void test_forward<std::unordered_set<int> >(); | ||
template void test_random_access<std::vector<int> >(); | ||
|
||
#if TEST_STD_VER >= 11 | ||
void test_directory_iterators() { | ||
fs::directory_iterator it; | ||
test_eq(it, it); | ||
|
||
fs::recursive_directory_iterator rdit; | ||
test_eq(rdit, rdit); | ||
} | ||
|
||
template void test_forward<fs::path>(); | ||
#endif | ||
|
||
#if TEST_STD_VER >= 17 | ||
template void test_random_access<std::string_view>(); | ||
#endif | ||
|
||
#if TEST_STD_VER >= 20 | ||
void test_span() { | ||
std::span<int> c; | ||
std::span<int>::iterator it = c.begin(); // span has no const_iterator | ||
test_eq(it, it); | ||
test_lt(it, it); | ||
} | ||
#endif |