1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // UNSUPPORTED: c++98, c++03 11 12 // <filesystem> 13 14 // class recursive_directory_iterator 15 16 // recursive_directory_iterator& operator=(recursive_directory_iterator const&); 17 18 #include "filesystem_include.hpp" 19 #include <type_traits> 20 #include <set> 21 #include <cassert> 22 23 #include "test_macros.h" 24 #include "rapid-cxx-test.hpp" 25 #include "filesystem_test_helper.hpp" 26 27 // The filesystem specification explicitly allows for self-move on 28 // the directory iterators. Turn off this warning so we can test it. 29 #if defined(__clang__) 30 #pragma clang diagnostic ignored "-Wself-move" 31 #endif 32 33 using namespace fs; 34 TEST_SUITE(recursive_directory_iterator_move_assign_tests)35TEST_SUITE(recursive_directory_iterator_move_assign_tests) 36 37 recursive_directory_iterator createInterestingIterator() 38 // Create an "interesting" iterator where all fields are 39 // in a non-default state. The returned 'it' is in a 40 // state such that: 41 // it.options() == directory_options::skip_permission_denied 42 // it.depth() == 1 43 // it.recursion_pending() == true 44 { 45 const path testDir = StaticEnv::Dir; 46 const recursive_directory_iterator endIt; 47 recursive_directory_iterator it(testDir, 48 directory_options::skip_permission_denied); 49 TEST_ASSERT(it != endIt); 50 while (it.depth() != 1) { 51 ++it; 52 TEST_ASSERT(it != endIt); 53 } 54 TEST_ASSERT(it.depth() == 1); 55 it.disable_recursion_pending(); 56 return it; 57 } 58 createDifferentInterestingIterator()59recursive_directory_iterator createDifferentInterestingIterator() 60 // Create an "interesting" iterator where all fields are 61 // in a non-default state. The returned 'it' is in a 62 // state such that: 63 // it.options() == directory_options::follow_directory_symlink 64 // it.depth() == 2 65 // it.recursion_pending() == false 66 { 67 const path testDir = StaticEnv::Dir; 68 const recursive_directory_iterator endIt; 69 recursive_directory_iterator it(testDir, 70 directory_options::follow_directory_symlink); 71 TEST_ASSERT(it != endIt); 72 while (it.depth() != 2) { 73 ++it; 74 TEST_ASSERT(it != endIt); 75 } 76 TEST_ASSERT(it.depth() == 2); 77 return it; 78 } 79 80 TEST_CASE(test_assignment_signature)81TEST_CASE(test_assignment_signature) 82 { 83 using D = recursive_directory_iterator; 84 static_assert(std::is_nothrow_move_assignable<D>::value, ""); 85 } 86 87 TEST_CASE(test_move_to_end_iterator)88TEST_CASE(test_move_to_end_iterator) 89 { 90 const recursive_directory_iterator endIt; 91 92 recursive_directory_iterator from = createInterestingIterator(); 93 const recursive_directory_iterator from_copy(from); 94 const path entry = *from; 95 96 recursive_directory_iterator to; 97 to = std::move(from); 98 TEST_REQUIRE(to != endIt); 99 TEST_CHECK(*to == entry); 100 TEST_CHECK(to.options() == from_copy.options()); 101 TEST_CHECK(to.depth() == from_copy.depth()); 102 TEST_CHECK(to.recursion_pending() == from_copy.recursion_pending()); 103 TEST_CHECK(from == endIt || from == to); 104 } 105 106 TEST_CASE(test_move_from_end_iterator)107TEST_CASE(test_move_from_end_iterator) 108 { 109 recursive_directory_iterator from; 110 recursive_directory_iterator to = createInterestingIterator(); 111 112 to = std::move(from); 113 TEST_REQUIRE(to == from); 114 TEST_CHECK(to == recursive_directory_iterator{}); 115 } 116 TEST_CASE(test_move_valid_iterator)117TEST_CASE(test_move_valid_iterator) 118 { 119 const recursive_directory_iterator endIt; 120 121 recursive_directory_iterator it = createInterestingIterator(); 122 const recursive_directory_iterator it_copy(it); 123 const path entry = *it; 124 125 recursive_directory_iterator it2 = createDifferentInterestingIterator(); 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 // Create two non-equal iterators that have exactly the same state. 153 recursive_directory_iterator it = createInterestingIterator(); 154 recursive_directory_iterator it2 = createInterestingIterator(); 155 TEST_CHECK(it != it2); 156 TEST_CHECK(it2.options() == it.options()); 157 TEST_CHECK(it2.depth() == it.depth()); 158 TEST_CHECK(it2.recursion_pending() == it.recursion_pending()); 159 TEST_CHECK(*it2 == *it); 160 161 it = std::move(it); 162 TEST_CHECK(it2.options() == it.options()); 163 TEST_CHECK(it2.depth() == it.depth()); 164 TEST_CHECK(it2.recursion_pending() == it.recursion_pending()); 165 TEST_CHECK(*it2 == *it); 166 } 167 168 169 TEST_SUITE_END() 170