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// recursive_directory_iterator& operator=(recursive_directory_iterator 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"
27namespace fs = std::filesystem;
28using namespace fs;
29
30recursive_directory_iterator createInterestingIterator(const static_test_env &static_env)
31 // Create an "interesting" iterator where all fields are
32 // in a non-default state. The returned 'it' is in a
33 // state such that:
34 // it.options() == directory_options::skip_permission_denied
35 // it.depth() == 1
36 // it.recursion_pending() == true
37{
38 const path testDir = static_env.Dir;
39 const recursive_directory_iterator endIt;
40 recursive_directory_iterator it(testDir,
41 directory_options::skip_permission_denied);
42 assert(it != endIt);
43 while (it.depth() != 1) {
44 ++it;
45 assert(it != endIt);
46 }
47 assert(it.depth() == 1);
48 it.disable_recursion_pending();
49 return it;
50}
51
52
53recursive_directory_iterator createDifferentInterestingIterator(const static_test_env &static_env)
54 // Create an "interesting" iterator where all fields are
55 // in a non-default state. The returned 'it' is in a
56 // state such that:
57 // it.options() == directory_options::follow_directory_symlink
58 // it.depth() == 2
59 // it.recursion_pending() == false
60{
61 const path testDir = static_env.Dir;
62 const recursive_directory_iterator endIt;
63 recursive_directory_iterator it(testDir,
64 directory_options::follow_directory_symlink);
65 assert(it != endIt);
66 while (it.depth() != 2) {
67 ++it;
68 assert(it != endIt);
69 }
70 assert(it.depth() == 2);
71 return it;
72}
73
74static void test_assignment_signature() {
75 using D = recursive_directory_iterator;
76 static_assert(std::is_copy_assignable<D>::value, "");
77}
78
79static void test_copy_to_end_iterator()
80{
81 static_test_env static_env;
82 const recursive_directory_iterator endIt;
83
84 const recursive_directory_iterator from = createInterestingIterator(static_env);
85 const path entry = *from;
86
87 recursive_directory_iterator to;
88 to = from;
89 assert(to == from);
90 assert(*to == entry);
91 assert(to.options() == from.options());
92 assert(to.depth() == from.depth());
93 assert(to.recursion_pending() == from.recursion_pending());
94}
95
96
97static void test_copy_from_end_iterator()
98{
99 static_test_env static_env;
100 const recursive_directory_iterator from;
101 recursive_directory_iterator to = createInterestingIterator(static_env);
102
103 to = from;
104 assert(to == from);
105 assert(to == recursive_directory_iterator{});
106}
107
108static void test_copy_valid_iterator()
109{
110 static_test_env static_env;
111 const recursive_directory_iterator endIt;
112
113 const recursive_directory_iterator it = createInterestingIterator(static_env);
114 const path entry = *it;
115
116 recursive_directory_iterator it2 = createDifferentInterestingIterator(static_env);
117 assert(it2 != it);
118 assert(it2.options() != it.options());
119 assert(it2.depth() != it.depth());
120 assert(it2.recursion_pending() != it.recursion_pending());
121 assert(*it2 != entry);
122
123 it2 = it;
124 assert(it2 == it);
125 assert(it2.options() == it.options());
126 assert(it2.depth() == it.depth());
127 assert(it2.recursion_pending() == it.recursion_pending());
128 assert(*it2 == entry);
129}
130
131static void test_returns_reference_to_self()
132{
133 const recursive_directory_iterator it;
134 recursive_directory_iterator it2;
135 recursive_directory_iterator& ref = (it2 = it);
136 assert(&ref == &it2);
137}
138
139static void test_self_copy()
140{
141 static_test_env static_env;
142 // Create two non-equal iterators that have exactly the same state.
143 recursive_directory_iterator it = createInterestingIterator(static_env);
144 recursive_directory_iterator it2 = createInterestingIterator(static_env);
145 assert(it != it2);
146 assert(it2.options() == it.options());
147 assert(it2.depth() == it.depth());
148 assert(it2.recursion_pending() == it.recursion_pending());
149 assert(*it2 == *it);
150
151 // perform a self-copy and check that the state still matches the
152 // other unmodified iterator.
153 recursive_directory_iterator const& cit = it;
154 it = cit;
155 assert(it2.options() == it.options());
156 assert(it2.depth() == it.depth());
157 assert(it2.recursion_pending() == it.recursion_pending());
158 assert(*it2 == *it);
159}
160
161int main(int, char**) {
162 test_assignment_signature();
163 test_copy_to_end_iterator();
164 test_copy_from_end_iterator();
165 test_copy_valid_iterator();
166 test_returns_reference_to_self();
167 test_self_copy();
168
169 return 0;
170}
171

source code of libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/copy_assign.pass.cpp