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