Warning: This file is not a C or C++ file. It does not have highlighting.
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___FLAT_MAP_KEY_VALUE_ITERATOR_H |
11 | #define _LIBCPP___FLAT_MAP_KEY_VALUE_ITERATOR_H |
12 | |
13 | #include <__compare/three_way_comparable.h> |
14 | #include <__concepts/convertible_to.h> |
15 | #include <__config> |
16 | #include <__iterator/iterator_traits.h> |
17 | #include <__memory/addressof.h> |
18 | #include <__type_traits/conditional.h> |
19 | #include <__utility/move.h> |
20 | #include <__utility/pair.h> |
21 | |
22 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
23 | # pragma GCC system_header |
24 | #endif |
25 | |
26 | _LIBCPP_PUSH_MACROS |
27 | #include <__undef_macros> |
28 | |
29 | #if _LIBCPP_STD_VER >= 23 |
30 | |
31 | _LIBCPP_BEGIN_NAMESPACE_STD |
32 | |
33 | /** |
34 | * __key_value_iterator is a proxy iterator which zips the underlying |
35 | * _KeyContainer::iterator and the underlying _MappedContainer::iterator. |
36 | * The two underlying iterators will be incremented/decremented together. |
37 | * And the reference is a pair of the const key reference and the value reference. |
38 | */ |
39 | template <class _Owner, class _KeyContainer, class _MappedContainer, bool _Const> |
40 | struct __key_value_iterator { |
41 | private: |
42 | using __key_iterator _LIBCPP_NODEBUG = typename _KeyContainer::const_iterator; |
43 | using __mapped_iterator _LIBCPP_NODEBUG = |
44 | _If<_Const, typename _MappedContainer::const_iterator, typename _MappedContainer::iterator>; |
45 | using __reference _LIBCPP_NODEBUG = _If<_Const, typename _Owner::const_reference, typename _Owner::reference>; |
46 | |
47 | struct __arrow_proxy { |
48 | __reference __ref_; |
49 | _LIBCPP_HIDE_FROM_ABI __reference* operator->() { return std::addressof(__ref_); } |
50 | }; |
51 | |
52 | __key_iterator __key_iter_; |
53 | __mapped_iterator __mapped_iter_; |
54 | |
55 | friend _Owner; |
56 | |
57 | template <class, class, class, bool> |
58 | friend struct __key_value_iterator; |
59 | |
60 | public: |
61 | using iterator_concept = random_access_iterator_tag; |
62 | // `__key_value_iterator` only satisfy "Cpp17InputIterator" named requirements, because |
63 | // its `reference` is not a reference type. |
64 | // However, to avoid surprising runtime behaviour when it is used with the |
65 | // Cpp17 algorithms or operations, iterator_category is set to random_access_iterator_tag. |
66 | using iterator_category = random_access_iterator_tag; |
67 | using value_type = typename _Owner::value_type; |
68 | using difference_type = typename _Owner::difference_type; |
69 | |
70 | _LIBCPP_HIDE_FROM_ABI __key_value_iterator() = default; |
71 | |
72 | _LIBCPP_HIDE_FROM_ABI __key_value_iterator(__key_value_iterator<_Owner, _KeyContainer, _MappedContainer, !_Const> __i) |
73 | requires _Const && convertible_to<typename _KeyContainer::iterator, __key_iterator> && |
74 | convertible_to<typename _MappedContainer::iterator, __mapped_iterator> |
75 | : __key_iter_(std::move(__i.__key_iter_)), __mapped_iter_(std::move(__i.__mapped_iter_)) {} |
76 | |
77 | _LIBCPP_HIDE_FROM_ABI __key_value_iterator(__key_iterator __key_iter, __mapped_iterator __mapped_iter) |
78 | : __key_iter_(std::move(__key_iter)), __mapped_iter_(std::move(__mapped_iter)) {} |
79 | |
80 | _LIBCPP_HIDE_FROM_ABI __reference operator*() const { return __reference(*__key_iter_, *__mapped_iter_); } |
81 | _LIBCPP_HIDE_FROM_ABI __arrow_proxy operator->() const { return __arrow_proxy{**this}; } |
82 | |
83 | _LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator++() { |
84 | ++__key_iter_; |
85 | ++__mapped_iter_; |
86 | return *this; |
87 | } |
88 | |
89 | _LIBCPP_HIDE_FROM_ABI __key_value_iterator operator++(int) { |
90 | __key_value_iterator __tmp(*this); |
91 | ++*this; |
92 | return __tmp; |
93 | } |
94 | |
95 | _LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator--() { |
96 | --__key_iter_; |
97 | --__mapped_iter_; |
98 | return *this; |
99 | } |
100 | |
101 | _LIBCPP_HIDE_FROM_ABI __key_value_iterator operator--(int) { |
102 | __key_value_iterator __tmp(*this); |
103 | --*this; |
104 | return __tmp; |
105 | } |
106 | |
107 | _LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator+=(difference_type __x) { |
108 | __key_iter_ += __x; |
109 | __mapped_iter_ += __x; |
110 | return *this; |
111 | } |
112 | |
113 | _LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator-=(difference_type __x) { |
114 | __key_iter_ -= __x; |
115 | __mapped_iter_ -= __x; |
116 | return *this; |
117 | } |
118 | |
119 | _LIBCPP_HIDE_FROM_ABI __reference operator[](difference_type __n) const { return *(*this + __n); } |
120 | |
121 | _LIBCPP_HIDE_FROM_ABI friend constexpr bool |
122 | operator==(const __key_value_iterator& __x, const __key_value_iterator& __y) { |
123 | return __x.__key_iter_ == __y.__key_iter_; |
124 | } |
125 | |
126 | _LIBCPP_HIDE_FROM_ABI friend bool operator<(const __key_value_iterator& __x, const __key_value_iterator& __y) { |
127 | return __x.__key_iter_ < __y.__key_iter_; |
128 | } |
129 | |
130 | _LIBCPP_HIDE_FROM_ABI friend bool operator>(const __key_value_iterator& __x, const __key_value_iterator& __y) { |
131 | return __y < __x; |
132 | } |
133 | |
134 | _LIBCPP_HIDE_FROM_ABI friend bool operator<=(const __key_value_iterator& __x, const __key_value_iterator& __y) { |
135 | return !(__y < __x); |
136 | } |
137 | |
138 | _LIBCPP_HIDE_FROM_ABI friend bool operator>=(const __key_value_iterator& __x, const __key_value_iterator& __y) { |
139 | return !(__x < __y); |
140 | } |
141 | |
142 | _LIBCPP_HIDE_FROM_ABI friend auto operator<=>(const __key_value_iterator& __x, const __key_value_iterator& __y) |
143 | requires three_way_comparable<__key_iterator> |
144 | { |
145 | return __x.__key_iter_ <=> __y.__key_iter_; |
146 | } |
147 | |
148 | _LIBCPP_HIDE_FROM_ABI friend __key_value_iterator operator+(const __key_value_iterator& __i, difference_type __n) { |
149 | auto __tmp = __i; |
150 | __tmp += __n; |
151 | return __tmp; |
152 | } |
153 | |
154 | _LIBCPP_HIDE_FROM_ABI friend __key_value_iterator operator+(difference_type __n, const __key_value_iterator& __i) { |
155 | return __i + __n; |
156 | } |
157 | |
158 | _LIBCPP_HIDE_FROM_ABI friend __key_value_iterator operator-(const __key_value_iterator& __i, difference_type __n) { |
159 | auto __tmp = __i; |
160 | __tmp -= __n; |
161 | return __tmp; |
162 | } |
163 | |
164 | _LIBCPP_HIDE_FROM_ABI friend difference_type |
165 | operator-(const __key_value_iterator& __x, const __key_value_iterator& __y) { |
166 | return difference_type(__x.__key_iter_ - __y.__key_iter_); |
167 | } |
168 | }; |
169 | |
170 | _LIBCPP_END_NAMESPACE_STD |
171 | |
172 | #endif // _LIBCPP_STD_VER >= 23 |
173 | |
174 | _LIBCPP_POP_MACROS |
175 | |
176 | #endif // _LIBCPP___FLAT_MAP_KEY_VALUE_ITERATOR_H |
177 |
Warning: This file is not a C or C++ file. It does not have highlighting.