1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef _LIBCPP___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H
11 #define _LIBCPP___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H
12
13 #include <__availability>
14 #include <__config>
15 #include <__filesystem/directory_entry.h>
16 #include <__filesystem/directory_options.h>
17 #include <__filesystem/path.h>
18 #include <__iterator/iterator_traits.h>
19 #include <__memory/shared_ptr.h>
20 #include <__ranges/enable_borrowed_range.h>
21 #include <__ranges/enable_view.h>
22 #include <cstddef>
23 #include <system_error>
24
25 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
26 # pragma GCC system_header
27 #endif
28
29 #ifndef _LIBCPP_CXX03_LANG
30
31 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
32
33 _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
34
35 class recursive_directory_iterator {
36 public:
37 using value_type = directory_entry;
38 using difference_type = ptrdiff_t;
39 using pointer = directory_entry const*;
40 using reference = directory_entry const&;
41 using iterator_category = input_iterator_tag;
42
43 public:
44 // constructors and destructor
45 _LIBCPP_INLINE_VISIBILITY
recursive_directory_iterator()46 recursive_directory_iterator() noexcept : __rec_(false) {}
47
48 _LIBCPP_INLINE_VISIBILITY
49 explicit recursive_directory_iterator(
50 const path& __p, directory_options __xoptions = directory_options::none)
recursive_directory_iterator(__p,__xoptions,nullptr)51 : recursive_directory_iterator(__p, __xoptions, nullptr) {}
52
53 _LIBCPP_INLINE_VISIBILITY
recursive_directory_iterator(const path & __p,directory_options __xoptions,error_code & __ec)54 recursive_directory_iterator(const path& __p, directory_options __xoptions,
55 error_code& __ec)
56 : recursive_directory_iterator(__p, __xoptions, &__ec) {}
57
58 _LIBCPP_INLINE_VISIBILITY
recursive_directory_iterator(const path & __p,error_code & __ec)59 recursive_directory_iterator(const path& __p, error_code& __ec)
60 : recursive_directory_iterator(__p, directory_options::none, &__ec) {}
61
62 recursive_directory_iterator(const recursive_directory_iterator&) = default;
63 recursive_directory_iterator(recursive_directory_iterator&&) = default;
64
65 recursive_directory_iterator&
66 operator=(const recursive_directory_iterator&) = default;
67
68 _LIBCPP_INLINE_VISIBILITY
69 recursive_directory_iterator&
70 operator=(recursive_directory_iterator&& __o) noexcept {
71 // non-default implementation provided to support self-move assign.
72 if (this != &__o) {
73 __imp_ = _VSTD::move(__o.__imp_);
74 __rec_ = __o.__rec_;
75 }
76 return *this;
77 }
78
79 ~recursive_directory_iterator() = default;
80
81 _LIBCPP_INLINE_VISIBILITY
82 const directory_entry& operator*() const { return __dereference(); }
83
84 _LIBCPP_INLINE_VISIBILITY
85 const directory_entry* operator->() const { return &__dereference(); }
86
87 recursive_directory_iterator& operator++() { return __increment(); }
88
89 _LIBCPP_INLINE_VISIBILITY
90 __dir_element_proxy operator++(int) {
91 __dir_element_proxy __p(**this);
92 __increment();
93 return __p;
94 }
95
96 _LIBCPP_INLINE_VISIBILITY
increment(error_code & __ec)97 recursive_directory_iterator& increment(error_code& __ec) {
98 return __increment(&__ec);
99 }
100
101 _LIBCPP_FUNC_VIS directory_options options() const;
102 _LIBCPP_FUNC_VIS int depth() const;
103
104 _LIBCPP_INLINE_VISIBILITY
pop()105 void pop() { __pop(); }
106
107 _LIBCPP_INLINE_VISIBILITY
pop(error_code & __ec)108 void pop(error_code& __ec) { __pop(&__ec); }
109
110 _LIBCPP_INLINE_VISIBILITY
recursion_pending()111 bool recursion_pending() const { return __rec_; }
112
113 _LIBCPP_INLINE_VISIBILITY
disable_recursion_pending()114 void disable_recursion_pending() { __rec_ = false; }
115
116 private:
117 _LIBCPP_FUNC_VIS
118 recursive_directory_iterator(const path& __p, directory_options __opt,
119 error_code* __ec);
120
121 _LIBCPP_FUNC_VIS
122 const directory_entry& __dereference() const;
123
124 _LIBCPP_FUNC_VIS
125 bool __try_recursion(error_code* __ec);
126
127 _LIBCPP_FUNC_VIS
128 void __advance(error_code* __ec = nullptr);
129
130 _LIBCPP_FUNC_VIS
131 recursive_directory_iterator& __increment(error_code* __ec = nullptr);
132
133 _LIBCPP_FUNC_VIS
134 void __pop(error_code* __ec = nullptr);
135
136 inline _LIBCPP_INLINE_VISIBILITY friend bool
137 operator==(const recursive_directory_iterator&,
138 const recursive_directory_iterator&) noexcept;
139
140 struct _LIBCPP_HIDDEN __shared_imp;
141 shared_ptr<__shared_imp> __imp_;
142 bool __rec_;
143 }; // class recursive_directory_iterator
144
145 inline _LIBCPP_INLINE_VISIBILITY bool
146 operator==(const recursive_directory_iterator& __lhs,
147 const recursive_directory_iterator& __rhs) noexcept {
148 return __lhs.__imp_ == __rhs.__imp_;
149 }
150
151 _LIBCPP_INLINE_VISIBILITY
152 inline bool operator!=(const recursive_directory_iterator& __lhs,
153 const recursive_directory_iterator& __rhs) noexcept {
154 return !(__lhs == __rhs);
155 }
156 // enable recursive_directory_iterator range-based for statements
157 inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator
begin(recursive_directory_iterator __iter)158 begin(recursive_directory_iterator __iter) noexcept {
159 return __iter;
160 }
161
162 inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator
end(recursive_directory_iterator)163 end(recursive_directory_iterator) noexcept {
164 return recursive_directory_iterator();
165 }
166
167 _LIBCPP_AVAILABILITY_FILESYSTEM_POP
168
169 _LIBCPP_END_NAMESPACE_FILESYSTEM
170
171 #if _LIBCPP_STD_VER > 17
172
173 template <>
174 _LIBCPP_AVAILABILITY_FILESYSTEM
175 inline constexpr bool _VSTD::ranges::enable_borrowed_range<_VSTD_FS::recursive_directory_iterator> = true;
176
177 template <>
178 _LIBCPP_AVAILABILITY_FILESYSTEM
179 inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::recursive_directory_iterator> = true;
180
181 #endif // _LIBCPP_STD_VER > 17
182
183 #endif // _LIBCPP_CXX03_LANG
184
185 #endif // _LIBCPP___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H
186