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_PATH_ITERATOR_H
11#define _LIBCPP___FILESYSTEM_PATH_ITERATOR_H
12
13#include <__assert>
14#include <__config>
15#include <__filesystem/path.h>
16#include <__iterator/iterator_traits.h>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19# pragma GCC system_header
20#endif
21
22#if _LIBCPP_STD_VER >= 17
23
24_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
25_LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS
26
27class _LIBCPP_EXPORTED_FROM_ABI path::iterator {
28public:
29 enum _ParserState : unsigned char {
30 _Singular,
31 _BeforeBegin,
32 _InRootName,
33 _InRootDir,
34 _InFilenames,
35 _InTrailingSep,
36 _AtEnd
37 };
38
39public:
40 typedef input_iterator_tag iterator_category;
41 typedef bidirectional_iterator_tag iterator_concept;
42
43 typedef path value_type;
44 typedef ptrdiff_t difference_type;
45 typedef const path* pointer;
46 typedef path reference;
47
48public:
49 _LIBCPP_HIDE_FROM_ABI iterator() : __stashed_elem_(), __path_ptr_(nullptr), __entry_(), __state_(_Singular) {}
50
51 _LIBCPP_HIDE_FROM_ABI iterator(const iterator&) = default;
52 _LIBCPP_HIDE_FROM_ABI ~iterator() = default;
53
54 _LIBCPP_HIDE_FROM_ABI iterator& operator=(const iterator&) = default;
55
56 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __stashed_elem_; }
57
58 _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return &__stashed_elem_; }
59
60 _LIBCPP_HIDE_FROM_ABI iterator& operator++() {
61 _LIBCPP_ASSERT_NON_NULL(__state_ != _Singular, "attempting to increment a singular iterator");
62 _LIBCPP_ASSERT_UNCATEGORIZED(__state_ != _AtEnd, "attempting to increment the end iterator");
63 return __increment();
64 }
65
66 _LIBCPP_HIDE_FROM_ABI iterator operator++(int) {
67 iterator __it(*this);
68 this->operator++();
69 return __it;
70 }
71
72 _LIBCPP_HIDE_FROM_ABI iterator& operator--() {
73 _LIBCPP_ASSERT_NON_NULL(__state_ != _Singular, "attempting to decrement a singular iterator");
74 _LIBCPP_ASSERT_UNCATEGORIZED(
75 __entry_.data() != __path_ptr_->native().data(), "attempting to decrement the begin iterator");
76 return __decrement();
77 }
78
79 _LIBCPP_HIDE_FROM_ABI iterator operator--(int) {
80 iterator __it(*this);
81 this->operator--();
82 return __it;
83 }
84
85private:
86 friend class path;
87
88 inline _LIBCPP_HIDE_FROM_ABI friend bool operator==(const iterator&, const iterator&);
89
90 iterator& __increment();
91 iterator& __decrement();
92
93 path __stashed_elem_;
94 const path* __path_ptr_;
95 path::__string_view __entry_;
96 _ParserState __state_;
97};
98
99inline _LIBCPP_HIDE_FROM_ABI bool operator==(const path::iterator& __lhs, const path::iterator& __rhs) {
100 return __lhs.__path_ptr_ == __rhs.__path_ptr_ && __lhs.__entry_.data() == __rhs.__entry_.data();
101}
102
103inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const path::iterator& __lhs, const path::iterator& __rhs) {
104 return !(__lhs == __rhs);
105}
106
107_LIBCPP_END_EXPLICIT_ABI_ANNOTATIONS
108_LIBCPP_END_NAMESPACE_FILESYSTEM
109
110#endif // _LIBCPP_STD_VER >= 17
111
112#endif // _LIBCPP___FILESYSTEM_PATH_ITERATOR_H
113