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