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// <experimental/filesystem> 13 14// class recursive_directory_iterator 15 16// recursive_directory_iterator& operator=(recursive_directory_iterator const&); 17 18#include <experimental/filesystem> 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 33using namespace std::experimental::filesystem; 34 35TEST_SUITE(recursive_directory_iterator_move_assign_tests) 36 37recursive_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 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 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 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 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 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 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 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 169TEST_SUITE_END() 170