17056250fSNikolas Klauser // -*- C++ -*- 27056250fSNikolas Klauser //===----------------------------------------------------------------------===// 37056250fSNikolas Klauser // 47056250fSNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 57056250fSNikolas Klauser // See https://llvm.org/LICENSE.txt for license information. 67056250fSNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 77056250fSNikolas Klauser // 87056250fSNikolas Klauser //===----------------------------------------------------------------------===// 97056250fSNikolas Klauser 107056250fSNikolas Klauser #ifndef _LIBCPP___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H 117056250fSNikolas Klauser #define _LIBCPP___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H 127056250fSNikolas Klauser 137056250fSNikolas Klauser #include <__config> 147056250fSNikolas Klauser #include <__filesystem/directory_entry.h> 157056250fSNikolas Klauser #include <__filesystem/directory_options.h> 167056250fSNikolas Klauser #include <__filesystem/path.h> 175f8e4315SHristo Hristov #include <__iterator/default_sentinel.h> 187056250fSNikolas Klauser #include <__iterator/iterator_traits.h> 197056250fSNikolas Klauser #include <__memory/shared_ptr.h> 207056250fSNikolas Klauser #include <__ranges/enable_borrowed_range.h> 217056250fSNikolas Klauser #include <__ranges/enable_view.h> 22e8cfbfd0SMark de Wever #include <__system_error/error_code.h> 23e8cfbfd0SMark de Wever #include <__utility/move.h> 247056250fSNikolas Klauser 25fa6b9e40SArthur O'Dwyer #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 26fa6b9e40SArthur O'Dwyer # pragma GCC system_header 27fa6b9e40SArthur O'Dwyer #endif 28fa6b9e40SArthur O'Dwyer 297b462251SLouis Dionne _LIBCPP_PUSH_MACROS 307b462251SLouis Dionne #include <__undef_macros> 317b462251SLouis Dionne 32*c6f3b7bcSNikolas Klauser #if _LIBCPP_STD_VER >= 17 && _LIBCPP_HAS_FILESYSTEM 337056250fSNikolas Klauser 347056250fSNikolas Klauser _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM 357056250fSNikolas Klauser 36dd72b813SLouis Dionne _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH 377056250fSNikolas Klauser 387056250fSNikolas Klauser class recursive_directory_iterator { 397056250fSNikolas Klauser public: 407056250fSNikolas Klauser using value_type = directory_entry; 417056250fSNikolas Klauser using difference_type = ptrdiff_t; 427056250fSNikolas Klauser using pointer = directory_entry const*; 437056250fSNikolas Klauser using reference = directory_entry const&; 447056250fSNikolas Klauser using iterator_category = input_iterator_tag; 457056250fSNikolas Klauser 467056250fSNikolas Klauser public: 477056250fSNikolas Klauser // constructors and destructor 489783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator() noexcept : __rec_(false) {} 497056250fSNikolas Klauser 509783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit recursive_directory_iterator( 517056250fSNikolas Klauser const path& __p, directory_options __xoptions = directory_options::none) 527056250fSNikolas Klauser : recursive_directory_iterator(__p, __xoptions, nullptr) {} 537056250fSNikolas Klauser 549783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator(const path& __p, directory_options __xoptions, error_code& __ec) 557056250fSNikolas Klauser : recursive_directory_iterator(__p, __xoptions, &__ec) {} 567056250fSNikolas Klauser 579783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator(const path& __p, error_code& __ec) 587056250fSNikolas Klauser : recursive_directory_iterator(__p, directory_options::none, &__ec) {} 597056250fSNikolas Klauser 6083ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator(const recursive_directory_iterator&) = default; 6183ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator(recursive_directory_iterator&&) = default; 627056250fSNikolas Klauser 639783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator& operator=(const recursive_directory_iterator&) = default; 647056250fSNikolas Klauser 659783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator& operator=(recursive_directory_iterator&& __o) noexcept { 667056250fSNikolas Klauser // non-default implementation provided to support self-move assign. 677056250fSNikolas Klauser if (this != &__o) { 6877a00c0dSLouis Dionne __imp_ = std::move(__o.__imp_); 697056250fSNikolas Klauser __rec_ = __o.__rec_; 707056250fSNikolas Klauser } 717056250fSNikolas Klauser return *this; 727056250fSNikolas Klauser } 737056250fSNikolas Klauser 7483ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI ~recursive_directory_iterator() = default; 757056250fSNikolas Klauser 769783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI const directory_entry& operator*() const { return __dereference(); } 777056250fSNikolas Klauser 789783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI const directory_entry* operator->() const { return &__dereference(); } 797056250fSNikolas Klauser 8083ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator& operator++() { return __increment(); } 817056250fSNikolas Klauser 829783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI __dir_element_proxy operator++(int) { 837056250fSNikolas Klauser __dir_element_proxy __p(**this); 847056250fSNikolas Klauser __increment(); 857056250fSNikolas Klauser return __p; 867056250fSNikolas Klauser } 877056250fSNikolas Klauser 889783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator& increment(error_code& __ec) { return __increment(&__ec); } 897056250fSNikolas Klauser 90f1ea0b11SNikolas Klauser _LIBCPP_EXPORTED_FROM_ABI directory_options options() const; 91f1ea0b11SNikolas Klauser _LIBCPP_EXPORTED_FROM_ABI int depth() const; 927056250fSNikolas Klauser 939783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI void pop() { __pop(); } 947056250fSNikolas Klauser 959783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI void pop(error_code& __ec) { __pop(&__ec); } 967056250fSNikolas Klauser 979783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI bool recursion_pending() const { return __rec_; } 987056250fSNikolas Klauser 999783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI void disable_recursion_pending() { __rec_ = false; } 1007056250fSNikolas Klauser 1015f8e4315SHristo Hristov # if _LIBCPP_STD_VER >= 20 1025f8e4315SHristo Hristov 1035f8e4315SHristo Hristov _LIBCPP_HIDE_FROM_ABI bool operator==(default_sentinel_t) const noexcept { 1045f8e4315SHristo Hristov return *this == recursive_directory_iterator(); 1055f8e4315SHristo Hristov } 1065f8e4315SHristo Hristov 1075f8e4315SHristo Hristov # endif 1085f8e4315SHristo Hristov 1097056250fSNikolas Klauser private: 110f1ea0b11SNikolas Klauser _LIBCPP_EXPORTED_FROM_ABI recursive_directory_iterator(const path& __p, directory_options __opt, error_code* __ec); 111f1ea0b11SNikolas Klauser _LIBCPP_EXPORTED_FROM_ABI const directory_entry& __dereference() const; 112f1ea0b11SNikolas Klauser _LIBCPP_EXPORTED_FROM_ABI bool __try_recursion(error_code* __ec); 113f1ea0b11SNikolas Klauser _LIBCPP_EXPORTED_FROM_ABI void __advance(error_code* __ec = nullptr); 114f1ea0b11SNikolas Klauser _LIBCPP_EXPORTED_FROM_ABI recursive_directory_iterator& __increment(error_code* __ec = nullptr); 115f1ea0b11SNikolas Klauser _LIBCPP_EXPORTED_FROM_ABI void __pop(error_code* __ec = nullptr); 1167056250fSNikolas Klauser 1174c198542SLouis Dionne inline _LIBCPP_HIDE_FROM_ABI friend bool 1189783f28cSLouis Dionne operator==(const recursive_directory_iterator&, const recursive_directory_iterator&) noexcept; 1197056250fSNikolas Klauser 1207056250fSNikolas Klauser struct _LIBCPP_HIDDEN __shared_imp; 1217056250fSNikolas Klauser shared_ptr<__shared_imp> __imp_; 1227056250fSNikolas Klauser bool __rec_; 1237056250fSNikolas Klauser }; // class recursive_directory_iterator 1247056250fSNikolas Klauser 1254c198542SLouis Dionne inline _LIBCPP_HIDE_FROM_ABI bool 1269783f28cSLouis Dionne operator==(const recursive_directory_iterator& __lhs, const recursive_directory_iterator& __rhs) noexcept { 1277056250fSNikolas Klauser return __lhs.__imp_ == __rhs.__imp_; 1287056250fSNikolas Klauser } 1297056250fSNikolas Klauser 1309783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI inline bool 1319783f28cSLouis Dionne operator!=(const recursive_directory_iterator& __lhs, const recursive_directory_iterator& __rhs) noexcept { 1327056250fSNikolas Klauser return !(__lhs == __rhs); 1337056250fSNikolas Klauser } 1347056250fSNikolas Klauser // enable recursive_directory_iterator range-based for statements 1359783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator begin(recursive_directory_iterator __iter) noexcept { 1367056250fSNikolas Klauser return __iter; 1377056250fSNikolas Klauser } 1387056250fSNikolas Klauser 1399783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator end(recursive_directory_iterator) noexcept { 1407056250fSNikolas Klauser return recursive_directory_iterator(); 1417056250fSNikolas Klauser } 1427056250fSNikolas Klauser 143dd72b813SLouis Dionne _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP 1447056250fSNikolas Klauser 1457056250fSNikolas Klauser _LIBCPP_END_NAMESPACE_FILESYSTEM 1467056250fSNikolas Klauser 1474f15267dSNikolas Klauser # if _LIBCPP_STD_VER >= 20 1487056250fSNikolas Klauser 1497056250fSNikolas Klauser template <> 1509783f28cSLouis Dionne _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY inline constexpr bool 1519783f28cSLouis Dionne std::ranges::enable_borrowed_range<std::filesystem::recursive_directory_iterator> = true; 1527056250fSNikolas Klauser 1537056250fSNikolas Klauser template <> 1549783f28cSLouis Dionne _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY inline constexpr bool 1559783f28cSLouis Dionne std::ranges::enable_view<std::filesystem::recursive_directory_iterator> = true; 1567056250fSNikolas Klauser 1574f15267dSNikolas Klauser # endif // _LIBCPP_STD_VER >= 20 1587056250fSNikolas Klauser 159*c6f3b7bcSNikolas Klauser #endif // _LIBCPP_STD_VER >= 17 && _LIBCPP_HAS_FILESYSTEM 1607056250fSNikolas Klauser 1617b462251SLouis Dionne _LIBCPP_POP_MACROS 1627b462251SLouis Dionne 1637056250fSNikolas Klauser #endif // _LIBCPP___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H 164