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: c++03 10 11 // <filesystem> 12 13 // class recursive_directory_iterator 14 15 // recursive_directory_iterator& operator=(recursive_directory_iterator const&); 16 17 #include "filesystem_include.h" 18 #include <type_traits> 19 #include <set> 20 #include <cassert> 21 22 #include "test_macros.h" 23 #include "rapid-cxx-test.h" 24 #include "filesystem_test_helper.h" 25 26 // The filesystem specification explicitly allows for self-move on 27 // the directory iterators. Turn off this warning so we can test it. 28 TEST_CLANG_DIAGNOSTIC_IGNORED("-Wself-move") 29 30 using namespace fs; 31 TEST_SUITE(recursive_directory_iterator_move_assign_tests)32TEST_SUITE(recursive_directory_iterator_move_assign_tests) 33 34 recursive_directory_iterator createInterestingIterator(const static_test_env &static_env) 35 // Create an "interesting" iterator where all fields are 36 // in a non-default state. The returned 'it' is in a 37 // state such that: 38 // it.options() == directory_options::skip_permission_denied 39 // it.depth() == 1 40 // it.recursion_pending() == true 41 { 42 const path testDir = static_env.Dir; 43 const recursive_directory_iterator endIt; 44 recursive_directory_iterator it(testDir, 45 directory_options::skip_permission_denied); 46 TEST_ASSERT(it != endIt); 47 while (it.depth() != 1) { 48 ++it; 49 TEST_ASSERT(it != endIt); 50 } 51 TEST_ASSERT(it.depth() == 1); 52 it.disable_recursion_pending(); 53 return it; 54 } 55 createDifferentInterestingIterator(const static_test_env & static_env)56recursive_directory_iterator createDifferentInterestingIterator(const static_test_env &static_env) 57 // Create an "interesting" iterator where all fields are 58 // in a non-default state. The returned 'it' is in a 59 // state such that: 60 // it.options() == directory_options::follow_directory_symlink 61 // it.depth() == 2 62 // it.recursion_pending() == false 63 { 64 const path testDir = static_env.Dir; 65 const recursive_directory_iterator endIt; 66 recursive_directory_iterator it(testDir, 67 directory_options::follow_directory_symlink); 68 TEST_ASSERT(it != endIt); 69 while (it.depth() != 2) { 70 ++it; 71 TEST_ASSERT(it != endIt); 72 } 73 TEST_ASSERT(it.depth() == 2); 74 return it; 75 } 76 77 TEST_CASE(test_assignment_signature)78TEST_CASE(test_assignment_signature) 79 { 80 using D = recursive_directory_iterator; 81 static_assert(std::is_nothrow_move_assignable<D>::value, ""); 82 } 83 84 TEST_CASE(test_move_to_end_iterator)85TEST_CASE(test_move_to_end_iterator) 86 { 87 static_test_env static_env; 88 const recursive_directory_iterator endIt; 89 90 recursive_directory_iterator from = createInterestingIterator(static_env); 91 const recursive_directory_iterator from_copy(from); 92 const path entry = *from; 93 94 recursive_directory_iterator to; 95 to = std::move(from); 96 TEST_REQUIRE(to != endIt); 97 TEST_CHECK(*to == entry); 98 TEST_CHECK(to.options() == from_copy.options()); 99 TEST_CHECK(to.depth() == from_copy.depth()); 100 TEST_CHECK(to.recursion_pending() == from_copy.recursion_pending()); 101 TEST_CHECK(from == endIt || from == to); 102 } 103 104 TEST_CASE(test_move_from_end_iterator)105TEST_CASE(test_move_from_end_iterator) 106 { 107 static_test_env static_env; 108 recursive_directory_iterator from; 109 recursive_directory_iterator to = createInterestingIterator(static_env); 110 111 to = std::move(from); 112 TEST_REQUIRE(to == from); 113 TEST_CHECK(to == recursive_directory_iterator{}); 114 } 115 TEST_CASE(test_move_valid_iterator)116TEST_CASE(test_move_valid_iterator) 117 { 118 static_test_env static_env; 119 const recursive_directory_iterator endIt; 120 121 recursive_directory_iterator it = createInterestingIterator(static_env); 122 const recursive_directory_iterator it_copy(it); 123 const path entry = *it; 124 125 recursive_directory_iterator it2 = createDifferentInterestingIterator(static_env); 126 const recursive_directory_iterator it2_copy(it2); 127 TEST_REQUIRE(it2 != it); 128 TEST_CHECK(it2.options() != it.options()); 129 TEST_CHECK(it2.depth() != it.depth()); 130 TEST_CHECK(it2.recursion_pending() != it.recursion_pending()); 131 TEST_CHECK(*it2 != entry); 132 133 it2 = std::move(it); 134 TEST_REQUIRE(it2 != it2_copy && it2 != endIt); 135 TEST_CHECK(it2.options() == it_copy.options()); 136 TEST_CHECK(it2.depth() == it_copy.depth()); 137 TEST_CHECK(it2.recursion_pending() == it_copy.recursion_pending()); 138 TEST_CHECK(*it2 == entry); 139 TEST_CHECK(it == endIt || it == it2); 140 } 141 TEST_CASE(test_returns_reference_to_self)142TEST_CASE(test_returns_reference_to_self) 143 { 144 recursive_directory_iterator it; 145 recursive_directory_iterator it2; 146 recursive_directory_iterator& ref = (it2 = std::move(it)); 147 TEST_CHECK(&ref == &it2); 148 } 149 TEST_CASE(test_self_move)150TEST_CASE(test_self_move) 151 { 152 static_test_env static_env; 153 // Create two non-equal iterators that have exactly the same state. 154 recursive_directory_iterator it = createInterestingIterator(static_env); 155 recursive_directory_iterator it2 = createInterestingIterator(static_env); 156 TEST_CHECK(it != it2); 157 TEST_CHECK(it2.options() == it.options()); 158 TEST_CHECK(it2.depth() == it.depth()); 159 TEST_CHECK(it2.recursion_pending() == it.recursion_pending()); 160 TEST_CHECK(*it2 == *it); 161 162 it = std::move(it); 163 TEST_CHECK(it2.options() == it.options()); 164 TEST_CHECK(it2.depth() == it.depth()); 165 TEST_CHECK(it2.recursion_pending() == it.recursion_pending()); 166 TEST_CHECK(*it2 == *it); 167 } 168 169 170 TEST_SUITE_END() 171