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