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// REQUIRES: can-create-symlinks
10// UNSUPPORTED: c++03, c++11, c++14
11// UNSUPPORTED: no-filesystem
12// UNSUPPORTED: availability-filesystem-missing
13
14// <filesystem>
15
16// class recursive_directory_iterator
17
18// bool recursion_pending() const;
19
20#include <filesystem>
21#include <type_traits>
22#include <set>
23#include <cassert>
24
25#include "test_macros.h"
26#include "filesystem_test_helper.h"
27namespace fs = std::filesystem;
28using namespace fs;
29
30static void initial_value_test()
31{
32 static_test_env static_env;
33 recursive_directory_iterator it(static_env.Dir);
34 assert(it.recursion_pending() == true);
35}
36
37static void value_after_copy_construction_and_assignment_test()
38{
39 static_test_env static_env;
40 recursive_directory_iterator rec_pending_it(static_env.Dir);
41 recursive_directory_iterator no_rec_pending_it(static_env.Dir);
42 no_rec_pending_it.disable_recursion_pending();
43
44 { // copy construction
45 recursive_directory_iterator it(rec_pending_it);
46 assert(it.recursion_pending() == true);
47 it.disable_recursion_pending();
48 assert(rec_pending_it.recursion_pending() == true);
49
50 recursive_directory_iterator it2(no_rec_pending_it);
51 assert(it2.recursion_pending() == false);
52 }
53 { // copy assignment
54 recursive_directory_iterator it(static_env.Dir);
55 it.disable_recursion_pending();
56 it = rec_pending_it;
57 assert(it.recursion_pending() == true);
58 it.disable_recursion_pending();
59 assert(rec_pending_it.recursion_pending() == true);
60
61 recursive_directory_iterator it2(static_env.Dir);
62 it2 = no_rec_pending_it;
63 assert(it2.recursion_pending() == false);
64 }
65 assert(rec_pending_it.recursion_pending() == true);
66 assert(no_rec_pending_it.recursion_pending() == false);
67}
68
69
70static void value_after_move_construction_and_assignment_test()
71{
72 static_test_env static_env;
73 recursive_directory_iterator rec_pending_it(static_env.Dir);
74 recursive_directory_iterator no_rec_pending_it(static_env.Dir);
75 no_rec_pending_it.disable_recursion_pending();
76
77 { // move construction
78 recursive_directory_iterator it_cp(rec_pending_it);
79 recursive_directory_iterator it(std::move(it_cp));
80 assert(it.recursion_pending() == true);
81
82 recursive_directory_iterator it_cp2(no_rec_pending_it);
83 recursive_directory_iterator it2(std::move(it_cp2));
84 assert(it2.recursion_pending() == false);
85 }
86 { // copy assignment
87 recursive_directory_iterator it(static_env.Dir);
88 it.disable_recursion_pending();
89 recursive_directory_iterator it_cp(rec_pending_it);
90 it = std::move(it_cp);
91 assert(it.recursion_pending() == true);
92
93 recursive_directory_iterator it2(static_env.Dir);
94 recursive_directory_iterator it_cp2(no_rec_pending_it);
95 it2 = std::move(it_cp2);
96 assert(it2.recursion_pending() == false);
97 }
98 assert(rec_pending_it.recursion_pending() == true);
99 assert(no_rec_pending_it.recursion_pending() == false);
100}
101
102static void increment_resets_value()
103{
104 static_test_env static_env;
105 const recursive_directory_iterator endIt;
106 {
107 recursive_directory_iterator it(static_env.Dir);
108 it.disable_recursion_pending();
109 assert(it.recursion_pending() == false);
110 ++it;
111 assert(it.recursion_pending() == true);
112 assert(it.depth() == 0);
113 }
114 {
115 recursive_directory_iterator it(static_env.Dir);
116 it.disable_recursion_pending();
117 assert(it.recursion_pending() == false);
118 it++;
119 assert(it.recursion_pending() == true);
120 assert(it.depth() == 0);
121 }
122 {
123 recursive_directory_iterator it(static_env.Dir);
124 it.disable_recursion_pending();
125 assert(it.recursion_pending() == false);
126 std::error_code ec;
127 it.increment(ec&: ec);
128 assert(it.recursion_pending() == true);
129 assert(it.depth() == 0);
130 }
131}
132
133static void pop_does_not_reset_value()
134{
135 static_test_env static_env;
136 const recursive_directory_iterator endIt;
137
138 auto& DE0 = static_env.DirIterationList;
139 std::set<path> notSeenDepth0(DE0.begin(), DE0.end());
140
141 recursive_directory_iterator it(static_env.Dir);
142 assert(it != endIt);
143
144 while (it.depth() == 0) {
145 notSeenDepth0.erase(x: it->path());
146 ++it;
147 assert(it != endIt);
148 }
149 assert(it.depth() == 1);
150 it.disable_recursion_pending();
151 it.pop();
152 // Since the order of iteration is unspecified the pop() could result
153 // in the end iterator. When this is the case it is undefined behavior
154 // to call recursion_pending().
155 if (it == endIt) {
156 assert(notSeenDepth0.empty());
157#if defined(_LIBCPP_VERSION)
158 assert(it.recursion_pending() == false);
159#endif
160 } else {
161 assert(! notSeenDepth0.empty());
162 assert(it.recursion_pending() == false);
163 }
164}
165
166int main(int, char**) {
167 initial_value_test();
168 value_after_copy_construction_and_assignment_test();
169 value_after_move_construction_and_assignment_test();
170 increment_resets_value();
171 pop_does_not_reset_value();
172
173 return 0;
174}
175

source code of libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/recursion_pending.pass.cpp