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
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)
51       : recursive_directory_iterator(__p, __xoptions, nullptr) {}
52 
53   _LIBCPP_INLINE_VISIBILITY
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
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
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
105   void pop() { __pop(); }
106 
107   _LIBCPP_INLINE_VISIBILITY
108   void pop(error_code& __ec) { __pop(&__ec); }
109 
110   _LIBCPP_INLINE_VISIBILITY
111   bool recursion_pending() const { return __rec_; }
112 
113   _LIBCPP_INLINE_VISIBILITY
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
158 begin(recursive_directory_iterator __iter) noexcept {
159   return __iter;
160 }
161 
162 inline _LIBCPP_INLINE_VISIBILITY 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