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_DIRECTORY_ITERATOR_H 11 #define _LIBCPP___FILESYSTEM_DIRECTORY_ITERATOR_H 12 13 #include <__availability> 14 #include <__config> 15 #include <__debug> 16 #include <__filesystem/directory_entry.h> 17 #include <__filesystem/directory_options.h> 18 #include <__filesystem/path.h> 19 #include <__iterator/iterator_traits.h> 20 #include <__memory/shared_ptr.h> 21 #include <__ranges/enable_borrowed_range.h> 22 #include <__ranges/enable_view.h> 23 #include <cstddef> 24 #include <system_error> 25 26 #ifndef _LIBCPP_CXX03_LANG 27 28 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM 29 30 _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH 31 32 class _LIBCPP_HIDDEN __dir_stream; 33 class directory_iterator { 34 public: 35 typedef directory_entry value_type; 36 typedef ptrdiff_t difference_type; 37 typedef value_type const* pointer; 38 typedef value_type const& reference; 39 typedef input_iterator_tag iterator_category; 40 41 public: 42 //ctor & dtor 43 directory_iterator() noexcept {} 44 45 explicit directory_iterator(const path& __p) 46 : directory_iterator(__p, nullptr) {} 47 48 directory_iterator(const path& __p, directory_options __opts) 49 : directory_iterator(__p, nullptr, __opts) {} 50 51 directory_iterator(const path& __p, error_code& __ec) 52 : directory_iterator(__p, &__ec) {} 53 54 directory_iterator(const path& __p, directory_options __opts, 55 error_code& __ec) 56 : directory_iterator(__p, &__ec, __opts) {} 57 58 directory_iterator(const directory_iterator&) = default; 59 directory_iterator(directory_iterator&&) = default; 60 directory_iterator& operator=(const directory_iterator&) = default; 61 62 directory_iterator& operator=(directory_iterator&& __o) noexcept { 63 // non-default implementation provided to support self-move assign. 64 if (this != &__o) { 65 __imp_ = _VSTD::move(__o.__imp_); 66 } 67 return *this; 68 } 69 70 ~directory_iterator() = default; 71 72 const directory_entry& operator*() const { 73 _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced"); 74 return __dereference(); 75 } 76 77 const directory_entry* operator->() const { return &**this; } 78 79 directory_iterator& operator++() { return __increment(); } 80 81 __dir_element_proxy operator++(int) { 82 __dir_element_proxy __p(**this); 83 __increment(); 84 return __p; 85 } 86 87 directory_iterator& increment(error_code& __ec) { return __increment(&__ec); } 88 89 private: 90 inline _LIBCPP_INLINE_VISIBILITY friend bool 91 operator==(const directory_iterator& __lhs, 92 const directory_iterator& __rhs) noexcept; 93 94 // construct the dir_stream 95 _LIBCPP_FUNC_VIS 96 directory_iterator(const path&, error_code*, 97 directory_options = directory_options::none); 98 99 _LIBCPP_FUNC_VIS 100 directory_iterator& __increment(error_code* __ec = nullptr); 101 102 _LIBCPP_FUNC_VIS 103 const directory_entry& __dereference() const; 104 105 private: 106 shared_ptr<__dir_stream> __imp_; 107 }; 108 109 inline _LIBCPP_INLINE_VISIBILITY bool 110 operator==(const directory_iterator& __lhs, 111 const directory_iterator& __rhs) noexcept { 112 return __lhs.__imp_ == __rhs.__imp_; 113 } 114 115 inline _LIBCPP_INLINE_VISIBILITY bool 116 operator!=(const directory_iterator& __lhs, 117 const directory_iterator& __rhs) noexcept { 118 return !(__lhs == __rhs); 119 } 120 121 // enable directory_iterator range-based for statements 122 inline _LIBCPP_INLINE_VISIBILITY directory_iterator 123 begin(directory_iterator __iter) noexcept { 124 return __iter; 125 } 126 127 inline _LIBCPP_INLINE_VISIBILITY directory_iterator 128 end(directory_iterator) noexcept { 129 return directory_iterator(); 130 } 131 132 _LIBCPP_AVAILABILITY_FILESYSTEM_POP 133 134 _LIBCPP_END_NAMESPACE_FILESYSTEM 135 136 #if !defined(_LIBCPP_HAS_NO_CONCEPTS) 137 138 template <> 139 _LIBCPP_AVAILABILITY_FILESYSTEM 140 inline constexpr bool _VSTD::ranges::enable_borrowed_range<_VSTD_FS::directory_iterator> = true; 141 142 template <> 143 _LIBCPP_AVAILABILITY_FILESYSTEM 144 inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::directory_iterator> = true; 145 146 #endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) 147 148 #endif // _LIBCPP_CXX03_LANG 149 150 #endif // _LIBCPP___FILESYSTEM_DIRECTORY_ITERATOR_H 151