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