158 lines · c
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-exception7//8//===----------------------------------------------------------------------===//9 10#ifndef _LIBCPP___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H11#define _LIBCPP___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H12 13#include <__config>14#include <__filesystem/directory_entry.h>15#include <__filesystem/directory_options.h>16#include <__filesystem/path.h>17#include <__iterator/default_sentinel.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 25#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)26# pragma GCC system_header27#endif28 29_LIBCPP_PUSH_MACROS30#include <__undef_macros>31 32#if _LIBCPP_STD_VER >= 17 && _LIBCPP_HAS_FILESYSTEM33 34_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM35 36class recursive_directory_iterator {37public: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 44public:45 // constructors and destructor46 _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator() noexcept : __rec_(false) {}47 48 _LIBCPP_HIDE_FROM_ABI explicit recursive_directory_iterator(49 const path& __p, directory_options __xoptions = directory_options::none)50 : recursive_directory_iterator(__p, __xoptions, nullptr) {}51 52 _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator(const path& __p, directory_options __xoptions, error_code& __ec)53 : recursive_directory_iterator(__p, __xoptions, &__ec) {}54 55 _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator(const path& __p, error_code& __ec)56 : recursive_directory_iterator(__p, directory_options::none, &__ec) {}57 58 _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator(const recursive_directory_iterator&) = default;59 _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator(recursive_directory_iterator&&) = default;60 61 _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator& operator=(const recursive_directory_iterator&) = default;62 63 _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator& operator=(recursive_directory_iterator&& __o) noexcept {64 // non-default implementation provided to support self-move assign.65 if (this != &__o) {66 __imp_ = std::move(__o.__imp_);67 __rec_ = __o.__rec_;68 }69 return *this;70 }71 72 _LIBCPP_HIDE_FROM_ABI ~recursive_directory_iterator() = default;73 74 _LIBCPP_HIDE_FROM_ABI const directory_entry& operator*() const { return __dereference(); }75 76 _LIBCPP_HIDE_FROM_ABI const directory_entry* operator->() const { return &__dereference(); }77 78 _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator& operator++() { return __increment(); }79 80 _LIBCPP_HIDE_FROM_ABI __dir_element_proxy operator++(int) {81 __dir_element_proxy __p(**this);82 __increment();83 return __p;84 }85 86 _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator& increment(error_code& __ec) { return __increment(&__ec); }87 88 _LIBCPP_EXPORTED_FROM_ABI directory_options options() const;89 _LIBCPP_EXPORTED_FROM_ABI int depth() const;90 91 _LIBCPP_HIDE_FROM_ABI void pop() { __pop(); }92 93 _LIBCPP_HIDE_FROM_ABI void pop(error_code& __ec) { __pop(&__ec); }94 95 _LIBCPP_HIDE_FROM_ABI bool recursion_pending() const { return __rec_; }96 97 _LIBCPP_HIDE_FROM_ABI void disable_recursion_pending() { __rec_ = false; }98 99# if _LIBCPP_STD_VER >= 20100 101 _LIBCPP_HIDE_FROM_ABI bool operator==(default_sentinel_t) const noexcept {102 return *this == recursive_directory_iterator();103 }104 105# endif106 107private:108 _LIBCPP_EXPORTED_FROM_ABI recursive_directory_iterator(const path& __p, directory_options __opt, error_code* __ec);109 _LIBCPP_EXPORTED_FROM_ABI const directory_entry& __dereference() const;110 _LIBCPP_EXPORTED_FROM_ABI bool __try_recursion(error_code* __ec);111 _LIBCPP_EXPORTED_FROM_ABI void __advance(error_code* __ec = nullptr);112 _LIBCPP_EXPORTED_FROM_ABI recursive_directory_iterator& __increment(error_code* __ec = nullptr);113 _LIBCPP_EXPORTED_FROM_ABI void __pop(error_code* __ec = nullptr);114 115 inline _LIBCPP_HIDE_FROM_ABI friend bool116 operator==(const recursive_directory_iterator&, const recursive_directory_iterator&) noexcept;117 118 struct _LIBCPP_HIDDEN __shared_imp;119 shared_ptr<__shared_imp> __imp_;120 bool __rec_;121}; // class recursive_directory_iterator122 123inline _LIBCPP_HIDE_FROM_ABI bool124operator==(const recursive_directory_iterator& __lhs, const recursive_directory_iterator& __rhs) noexcept {125 return __lhs.__imp_ == __rhs.__imp_;126}127 128_LIBCPP_HIDE_FROM_ABI inline bool129operator!=(const recursive_directory_iterator& __lhs, const recursive_directory_iterator& __rhs) noexcept {130 return !(__lhs == __rhs);131}132// enable recursive_directory_iterator range-based for statements133inline _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator begin(recursive_directory_iterator __iter) noexcept {134 return __iter;135}136 137inline _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator end(recursive_directory_iterator) noexcept {138 return recursive_directory_iterator();139}140 141_LIBCPP_END_NAMESPACE_FILESYSTEM142 143# if _LIBCPP_STD_VER >= 20144 145template <>146inline constexpr bool std::ranges::enable_borrowed_range<std::filesystem::recursive_directory_iterator> = true;147 148template <>149inline constexpr bool std::ranges::enable_view<std::filesystem::recursive_directory_iterator> = true;150 151# endif // _LIBCPP_STD_VER >= 20152 153#endif // _LIBCPP_STD_VER >= 17 && _LIBCPP_HAS_FILESYSTEM154 155_LIBCPP_POP_MACROS156 157#endif // _LIBCPP___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H158