xref: /freebsd-src/contrib/llvm-project/libcxx/include/__filesystem/directory_iterator.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10eae32dcSDimitry Andric // -*- C++ -*-
20eae32dcSDimitry Andric //===----------------------------------------------------------------------===//
30eae32dcSDimitry Andric //
40eae32dcSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50eae32dcSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
60eae32dcSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70eae32dcSDimitry Andric //
80eae32dcSDimitry Andric //===----------------------------------------------------------------------===//
90eae32dcSDimitry Andric 
100eae32dcSDimitry Andric #ifndef _LIBCPP___FILESYSTEM_DIRECTORY_ITERATOR_H
110eae32dcSDimitry Andric #define _LIBCPP___FILESYSTEM_DIRECTORY_ITERATOR_H
120eae32dcSDimitry Andric 
1381ad6265SDimitry Andric #include <__assert>
140eae32dcSDimitry Andric #include <__config>
150eae32dcSDimitry Andric #include <__filesystem/directory_entry.h>
160eae32dcSDimitry Andric #include <__filesystem/directory_options.h>
170eae32dcSDimitry Andric #include <__filesystem/path.h>
1806c3fb27SDimitry Andric #include <__iterator/default_sentinel.h>
190eae32dcSDimitry Andric #include <__iterator/iterator_traits.h>
200eae32dcSDimitry Andric #include <__memory/shared_ptr.h>
210eae32dcSDimitry Andric #include <__ranges/enable_borrowed_range.h>
220eae32dcSDimitry Andric #include <__ranges/enable_view.h>
2306c3fb27SDimitry Andric #include <__system_error/error_code.h>
2406c3fb27SDimitry Andric #include <__utility/move.h>
250eae32dcSDimitry Andric #include <cstddef>
260eae32dcSDimitry Andric 
2781ad6265SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2881ad6265SDimitry Andric #  pragma GCC system_header
2981ad6265SDimitry Andric #endif
3081ad6265SDimitry Andric 
31*b3edf446SDimitry Andric _LIBCPP_PUSH_MACROS
32*b3edf446SDimitry Andric #include <__undef_macros>
33*b3edf446SDimitry Andric 
345f757f3fSDimitry Andric #if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
350eae32dcSDimitry Andric 
360eae32dcSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
370eae32dcSDimitry Andric 
3806c3fb27SDimitry Andric _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
390eae32dcSDimitry Andric 
400eae32dcSDimitry Andric class _LIBCPP_HIDDEN __dir_stream;
410eae32dcSDimitry Andric class directory_iterator {
420eae32dcSDimitry Andric public:
430eae32dcSDimitry Andric   typedef directory_entry value_type;
440eae32dcSDimitry Andric   typedef ptrdiff_t difference_type;
450eae32dcSDimitry Andric   typedef value_type const* pointer;
460eae32dcSDimitry Andric   typedef value_type const& reference;
470eae32dcSDimitry Andric   typedef input_iterator_tag iterator_category;
480eae32dcSDimitry Andric 
490eae32dcSDimitry Andric public:
500eae32dcSDimitry Andric   // ctor & dtor
51cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI directory_iterator() noexcept {}
520eae32dcSDimitry Andric 
53cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit directory_iterator(const path& __p) : directory_iterator(__p, nullptr) {}
540eae32dcSDimitry Andric 
55cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI directory_iterator(const path& __p, directory_options __opts)
560eae32dcSDimitry Andric       : directory_iterator(__p, nullptr, __opts) {}
570eae32dcSDimitry Andric 
58cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI directory_iterator(const path& __p, error_code& __ec) : directory_iterator(__p, &__ec) {}
590eae32dcSDimitry Andric 
60cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI directory_iterator(const path& __p, directory_options __opts, error_code& __ec)
610eae32dcSDimitry Andric       : directory_iterator(__p, &__ec, __opts) {}
620eae32dcSDimitry Andric 
6381ad6265SDimitry Andric   _LIBCPP_HIDE_FROM_ABI directory_iterator(const directory_iterator&)            = default;
6481ad6265SDimitry Andric   _LIBCPP_HIDE_FROM_ABI directory_iterator(directory_iterator&&)                 = default;
6581ad6265SDimitry Andric   _LIBCPP_HIDE_FROM_ABI directory_iterator& operator=(const directory_iterator&) = default;
660eae32dcSDimitry Andric 
67cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI directory_iterator& operator=(directory_iterator&& __o) noexcept {
680eae32dcSDimitry Andric     // non-default implementation provided to support self-move assign.
690eae32dcSDimitry Andric     if (this != &__o) {
705f757f3fSDimitry Andric       __imp_ = std::move(__o.__imp_);
710eae32dcSDimitry Andric     }
720eae32dcSDimitry Andric     return *this;
730eae32dcSDimitry Andric   }
740eae32dcSDimitry Andric 
7581ad6265SDimitry Andric   _LIBCPP_HIDE_FROM_ABI ~directory_iterator() = default;
760eae32dcSDimitry Andric 
77cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI const directory_entry& operator*() const {
781db9f3b2SDimitry Andric     // Note: this check duplicates a check in `__dereference()`.
791db9f3b2SDimitry Andric     _LIBCPP_ASSERT_NON_NULL(__imp_, "The end iterator cannot be dereferenced");
800eae32dcSDimitry Andric     return __dereference();
810eae32dcSDimitry Andric   }
820eae32dcSDimitry Andric 
83cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI const directory_entry* operator->() const { return &**this; }
840eae32dcSDimitry Andric 
85cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI directory_iterator& operator++() { return __increment(); }
860eae32dcSDimitry Andric 
87cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __dir_element_proxy operator++(int) {
880eae32dcSDimitry Andric     __dir_element_proxy __p(**this);
890eae32dcSDimitry Andric     __increment();
900eae32dcSDimitry Andric     return __p;
910eae32dcSDimitry Andric   }
920eae32dcSDimitry Andric 
93cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI directory_iterator& increment(error_code& __ec) { return __increment(&__ec); }
940eae32dcSDimitry Andric 
9506c3fb27SDimitry Andric #  if _LIBCPP_STD_VER >= 20
9606c3fb27SDimitry Andric 
9706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool operator==(default_sentinel_t) const noexcept { return *this == directory_iterator(); }
9806c3fb27SDimitry Andric 
9906c3fb27SDimitry Andric #  endif
10006c3fb27SDimitry Andric 
1010eae32dcSDimitry Andric private:
10281ad6265SDimitry Andric   inline _LIBCPP_HIDE_FROM_ABI friend bool
103cb14a3feSDimitry Andric   operator==(const directory_iterator& __lhs, const directory_iterator& __rhs) noexcept;
1040eae32dcSDimitry Andric 
1050eae32dcSDimitry Andric   // construct the dir_stream
10606c3fb27SDimitry Andric   _LIBCPP_EXPORTED_FROM_ABI directory_iterator(const path&, error_code*, directory_options = directory_options::none);
1070eae32dcSDimitry Andric 
10806c3fb27SDimitry Andric   _LIBCPP_EXPORTED_FROM_ABI directory_iterator& __increment(error_code* __ec = nullptr);
1090eae32dcSDimitry Andric 
11006c3fb27SDimitry Andric   _LIBCPP_EXPORTED_FROM_ABI const directory_entry& __dereference() const;
1110eae32dcSDimitry Andric 
1120eae32dcSDimitry Andric private:
1130eae32dcSDimitry Andric   shared_ptr<__dir_stream> __imp_;
1140eae32dcSDimitry Andric };
1150eae32dcSDimitry Andric 
11681ad6265SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool
117cb14a3feSDimitry Andric operator==(const directory_iterator& __lhs, const directory_iterator& __rhs) noexcept {
1180eae32dcSDimitry Andric   return __lhs.__imp_ == __rhs.__imp_;
1190eae32dcSDimitry Andric }
1200eae32dcSDimitry Andric 
12181ad6265SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool
122cb14a3feSDimitry Andric operator!=(const directory_iterator& __lhs, const directory_iterator& __rhs) noexcept {
1230eae32dcSDimitry Andric   return !(__lhs == __rhs);
1240eae32dcSDimitry Andric }
1250eae32dcSDimitry Andric 
1260eae32dcSDimitry Andric // enable directory_iterator range-based for statements
127cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI directory_iterator begin(directory_iterator __iter) noexcept { return __iter; }
1280eae32dcSDimitry Andric 
129cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI directory_iterator end(directory_iterator) noexcept { return directory_iterator(); }
1300eae32dcSDimitry Andric 
13106c3fb27SDimitry Andric _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
1320eae32dcSDimitry Andric 
1330eae32dcSDimitry Andric _LIBCPP_END_NAMESPACE_FILESYSTEM
1340eae32dcSDimitry Andric 
13506c3fb27SDimitry Andric #  if _LIBCPP_STD_VER >= 20
1360eae32dcSDimitry Andric 
1370eae32dcSDimitry Andric template <>
138cb14a3feSDimitry Andric _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY inline constexpr bool
139cb14a3feSDimitry Andric     std::ranges::enable_borrowed_range<std::filesystem::directory_iterator> = true;
1400eae32dcSDimitry Andric 
1410eae32dcSDimitry Andric template <>
142cb14a3feSDimitry Andric _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY inline constexpr bool
143cb14a3feSDimitry Andric     std::ranges::enable_view<std::filesystem::directory_iterator> = true;
1440eae32dcSDimitry Andric 
14506c3fb27SDimitry Andric #  endif // _LIBCPP_STD_VER >= 20
1460eae32dcSDimitry Andric 
1475f757f3fSDimitry Andric #endif // _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
1480eae32dcSDimitry Andric 
149*b3edf446SDimitry Andric _LIBCPP_POP_MACROS
150*b3edf446SDimitry Andric 
1510eae32dcSDimitry Andric #endif // _LIBCPP___FILESYSTEM_DIRECTORY_ITERATOR_H
152