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" 27 namespace fs = std::filesystem; 28 using namespace fs; 29 initial_value_test()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 value_after_copy_construction_and_assignment_test()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 value_after_move_construction_and_assignment_test()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 increment_resets_value()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); 128 assert(it.recursion_pending() == true); 129 assert(it.depth() == 0); 130 } 131 } 132 pop_does_not_reset_value()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(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 main(int,char **)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