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