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