1 | //===----------------------------------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | // XFAIL: availability-filesystem-missing |
10 | |
11 | // Make sure the various containers' iterators are not broken by the use of `std::rel_ops`. |
12 | |
13 | #include <utility> // for std::rel_ops |
14 | |
15 | #include <array> |
16 | #include <deque> |
17 | #include <filesystem> |
18 | #include <forward_list> |
19 | #include <list> |
20 | #include <map> |
21 | #include <set> |
22 | #include <string> |
23 | #include <unordered_map> |
24 | #include <unordered_set> |
25 | #include <vector> |
26 | |
27 | #include "test_macros.h" |
28 | |
29 | #if TEST_STD_VER >= 17 |
30 | #include <string_view> |
31 | #endif |
32 | |
33 | #if TEST_STD_VER >= 20 |
34 | #include <span> |
35 | #endif |
36 | |
37 | using namespace std::rel_ops; |
38 | |
39 | template<class It, class ConstIt> |
40 | void test_eq(It it, ConstIt cit) { |
41 | (void)(it == it); |
42 | (void)(it != it); |
43 | (void)(it == cit); |
44 | (void)(it != cit); |
45 | (void)(cit == it); |
46 | (void)(cit != it); |
47 | (void)(cit == cit); |
48 | (void)(cit != cit); |
49 | } |
50 | |
51 | template<class It, class ConstIt> |
52 | void test_lt(It it, ConstIt cit) { |
53 | (void)(it < it); |
54 | (void)(it <= it); |
55 | (void)(it > it); |
56 | (void)(it >= it); |
57 | (void)(it < cit); |
58 | (void)(it <= cit); |
59 | (void)(it > cit); |
60 | (void)(it >= cit); |
61 | (void)(cit < it); |
62 | (void)(cit <= it); |
63 | (void)(cit > it); |
64 | (void)(cit >= it); |
65 | (void)(cit < cit); |
66 | (void)(cit <= cit); |
67 | (void)(cit > cit); |
68 | (void)(cit >= cit); |
69 | |
70 | // Test subtraction too, even though std::rel_ops shouldn't affect it. |
71 | |
72 | (void)(it - it); |
73 | (void)(it - cit); |
74 | (void)(cit - it); |
75 | (void)(cit - cit); |
76 | } |
77 | |
78 | template<class Container> |
79 | void test_forward() { |
80 | // There is no need to distinguish "forward" from "bidirectional." |
81 | // libc++ already can't handle `c.rbegin() >= c.rbegin()` in the |
82 | // presence of std::rel_ops, and neither can Microsoft nor libstdc++. |
83 | |
84 | Container c; |
85 | typename Container::iterator it = c.begin(); |
86 | typename Container::const_iterator cit = c.begin(); |
87 | test_eq(it, cit); |
88 | } |
89 | |
90 | template<class Container> |
91 | void test_random_access() { |
92 | Container c; |
93 | typename Container::iterator it = c.begin(); |
94 | typename Container::const_iterator cit = c.begin(); |
95 | test_eq(it, cit); |
96 | test_lt(it, cit); |
97 | } |
98 | |
99 | template void test_random_access<std::array<int, 10> >(); |
100 | template void test_random_access<std::deque<int> >(); |
101 | template void test_forward<std::forward_list<int> >(); |
102 | template void test_forward<std::list<int> >(); |
103 | template void test_forward<std::map<int, int> >(); |
104 | template void test_forward<std::multimap<int, int> >(); |
105 | template void test_forward<std::multiset<int> >(); |
106 | template void test_forward<std::set<int> >(); |
107 | template void test_random_access<std::string>(); |
108 | template void test_forward<std::unordered_map<int, int> >(); |
109 | template void test_forward<std::unordered_multimap<int, int> >(); |
110 | template void test_forward<std::unordered_multiset<int> >(); |
111 | template void test_forward<std::unordered_set<int> >(); |
112 | template void test_random_access<std::vector<int> >(); |
113 | |
114 | #if TEST_STD_VER >= 17 |
115 | void test_directory_iterators() { |
116 | #ifndef TEST_HAS_NO_FILESYSTEM |
117 | std::filesystem::directory_iterator it; |
118 | test_eq(it, it); |
119 | |
120 | std::filesystem::recursive_directory_iterator rdit; |
121 | test_eq(rdit, rdit); |
122 | #endif |
123 | } |
124 | |
125 | template void test_forward<std::filesystem::path>(); |
126 | #endif |
127 | |
128 | #if TEST_STD_VER >= 17 |
129 | template void test_random_access<std::string_view>(); |
130 | #endif |
131 | |
132 | #if TEST_STD_VER >= 20 |
133 | void test_span() { |
134 | std::span<int> c; |
135 | std::span<int>::iterator it = c.begin(); // span has no const_iterator |
136 | test_eq(it, it); |
137 | test_lt(it, it); |
138 | } |
139 | #endif |
140 | |