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_PATH_ITERATOR_H
110eae32dcSDimitry Andric #define _LIBCPP___FILESYSTEM_PATH_ITERATOR_H
120eae32dcSDimitry Andric 
1381ad6265SDimitry Andric #include <__assert>
140eae32dcSDimitry Andric #include <__availability>
150eae32dcSDimitry Andric #include <__config>
160eae32dcSDimitry Andric #include <__filesystem/path.h>
170eae32dcSDimitry Andric #include <__iterator/iterator_traits.h>
180eae32dcSDimitry Andric #include <cstddef>
190eae32dcSDimitry Andric #include <string>
200eae32dcSDimitry Andric #include <string_view>
210eae32dcSDimitry Andric 
2281ad6265SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2381ad6265SDimitry Andric #  pragma GCC system_header
2481ad6265SDimitry Andric #endif
2581ad6265SDimitry Andric 
265f757f3fSDimitry Andric #if _LIBCPP_STD_VER >= 17
270eae32dcSDimitry Andric 
280eae32dcSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
290eae32dcSDimitry Andric 
3006c3fb27SDimitry Andric class _LIBCPP_EXPORTED_FROM_ABI path::iterator {
310eae32dcSDimitry Andric public:
320eae32dcSDimitry Andric   enum _ParserState : unsigned char {
330eae32dcSDimitry Andric     _Singular,
340eae32dcSDimitry Andric     _BeforeBegin,
350eae32dcSDimitry Andric     _InRootName,
360eae32dcSDimitry Andric     _InRootDir,
370eae32dcSDimitry Andric     _InFilenames,
380eae32dcSDimitry Andric     _InTrailingSep,
390eae32dcSDimitry Andric     _AtEnd
400eae32dcSDimitry Andric   };
410eae32dcSDimitry Andric 
420eae32dcSDimitry Andric public:
4304eeddc0SDimitry Andric   typedef input_iterator_tag iterator_category;
4404eeddc0SDimitry Andric   typedef bidirectional_iterator_tag iterator_concept;
450eae32dcSDimitry Andric 
460eae32dcSDimitry Andric   typedef path value_type;
470eae32dcSDimitry Andric   typedef ptrdiff_t difference_type;
480eae32dcSDimitry Andric   typedef const path* pointer;
4904eeddc0SDimitry Andric   typedef path reference;
500eae32dcSDimitry Andric 
510eae32dcSDimitry Andric public:
iterator()52cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI iterator() : __stashed_elem_(), __path_ptr_(nullptr), __entry_(), __state_(_Singular) {}
530eae32dcSDimitry Andric 
5406c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI iterator(const iterator&) = default;
5506c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI ~iterator()               = default;
560eae32dcSDimitry Andric 
5706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI iterator& operator=(const iterator&) = default;
580eae32dcSDimitry Andric 
59cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __stashed_elem_; }
600eae32dcSDimitry Andric 
61cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return &__stashed_elem_; }
620eae32dcSDimitry Andric 
63cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI iterator& operator++() {
64*1db9f3b2SDimitry Andric     _LIBCPP_ASSERT_NON_NULL(__state_ != _Singular, "attempting to increment a singular iterator");
65cb14a3feSDimitry Andric     _LIBCPP_ASSERT_UNCATEGORIZED(__state_ != _AtEnd, "attempting to increment the end iterator");
660eae32dcSDimitry Andric     return __increment();
670eae32dcSDimitry Andric   }
680eae32dcSDimitry Andric 
69cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI iterator operator++(int) {
700eae32dcSDimitry Andric     iterator __it(*this);
710eae32dcSDimitry Andric     this->operator++();
720eae32dcSDimitry Andric     return __it;
730eae32dcSDimitry Andric   }
740eae32dcSDimitry Andric 
75cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI iterator& operator--() {
76*1db9f3b2SDimitry Andric     _LIBCPP_ASSERT_NON_NULL(__state_ != _Singular, "attempting to decrement a singular iterator");
77cb14a3feSDimitry Andric     _LIBCPP_ASSERT_UNCATEGORIZED(
78cb14a3feSDimitry Andric         __entry_.data() != __path_ptr_->native().data(), "attempting to decrement the begin iterator");
790eae32dcSDimitry Andric     return __decrement();
800eae32dcSDimitry Andric   }
810eae32dcSDimitry Andric 
82cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI iterator operator--(int) {
830eae32dcSDimitry Andric     iterator __it(*this);
840eae32dcSDimitry Andric     this->operator--();
850eae32dcSDimitry Andric     return __it;
860eae32dcSDimitry Andric   }
870eae32dcSDimitry Andric 
880eae32dcSDimitry Andric private:
890eae32dcSDimitry Andric   friend class path;
900eae32dcSDimitry Andric 
91cb14a3feSDimitry Andric   inline _LIBCPP_HIDE_FROM_ABI friend bool operator==(const iterator&, const iterator&);
920eae32dcSDimitry Andric 
930eae32dcSDimitry Andric   iterator& __increment();
940eae32dcSDimitry Andric   iterator& __decrement();
950eae32dcSDimitry Andric 
960eae32dcSDimitry Andric   path __stashed_elem_;
970eae32dcSDimitry Andric   const path* __path_ptr_;
980eae32dcSDimitry Andric   path::__string_view __entry_;
990eae32dcSDimitry Andric   _ParserState __state_;
1000eae32dcSDimitry Andric };
1010eae32dcSDimitry Andric 
10206c3fb27SDimitry Andric _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
103cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator==(const path::iterator& __lhs, const path::iterator& __rhs) {
104cb14a3feSDimitry Andric   return __lhs.__path_ptr_ == __rhs.__path_ptr_ && __lhs.__entry_.data() == __rhs.__entry_.data();
1050eae32dcSDimitry Andric }
1060eae32dcSDimitry Andric 
10706c3fb27SDimitry Andric _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
108cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const path::iterator& __lhs, const path::iterator& __rhs) {
1090eae32dcSDimitry Andric   return !(__lhs == __rhs);
1100eae32dcSDimitry Andric }
1110eae32dcSDimitry Andric 
1120eae32dcSDimitry Andric _LIBCPP_END_NAMESPACE_FILESYSTEM
1130eae32dcSDimitry Andric 
1145f757f3fSDimitry Andric #endif // _LIBCPP_STD_VER >= 17
1150eae32dcSDimitry Andric 
1160eae32dcSDimitry Andric #endif // _LIBCPP___FILESYSTEM_PATH_ITERATOR_H
117