Skip to content

Commit f22ecdd

Browse files
authored
[libc++] Move out flat_map::iterator (for reusing it in flat_multimap) (#117445)
1 parent 9ddc31d commit f22ecdd

File tree

7 files changed

+187
-124
lines changed

7 files changed

+187
-124
lines changed

libcxx/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,7 @@ set(files
360360
__filesystem/space_info.h
361361
__filesystem/u8path.h
362362
__flat_map/flat_map.h
363+
__flat_map/key_value_iterator.h
363364
__flat_map/sorted_unique.h
364365
__format/buffer.h
365366
__format/concepts.h

libcxx/include/__flat_map/flat_map.h

Lines changed: 5 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@
2323
#include <__algorithm/remove_if.h>
2424
#include <__assert>
2525
#include <__compare/synth_three_way.h>
26-
#include <__concepts/convertible_to.h>
2726
#include <__concepts/swappable.h>
2827
#include <__config>
2928
#include <__cstddef/byte.h>
3029
#include <__cstddef/ptrdiff_t.h>
30+
#include <__flat_map/key_value_iterator.h>
3131
#include <__flat_map/sorted_unique.h>
3232
#include <__functional/invoke.h>
3333
#include <__functional/is_transparent.h>
@@ -38,7 +38,6 @@
3838
#include <__iterator/next.h>
3939
#include <__iterator/ranges_iterator_traits.h>
4040
#include <__iterator/reverse_iterator.h>
41-
#include <__memory/addressof.h>
4241
#include <__memory/allocator_traits.h>
4342
#include <__memory/uses_allocator.h>
4443
#include <__memory/uses_allocator_construction.h>
@@ -57,8 +56,8 @@
5756
#include <__type_traits/is_allocator.h>
5857
#include <__type_traits/is_nothrow_constructible.h>
5958
#include <__type_traits/is_same.h>
60-
#include <__type_traits/maybe_const.h>
6159
#include <__utility/exception_guard.h>
60+
#include <__utility/move.h>
6261
#include <__utility/pair.h>
6362
#include <__utility/scope_guard.h>
6463
#include <__vector/vector.h>
@@ -82,9 +81,6 @@ template <class _Key,
8281
class _KeyContainer = vector<_Key>,
8382
class _MappedContainer = vector<_Tp>>
8483
class flat_map {
85-
template <bool _Const>
86-
struct __iterator;
87-
8884
template <class, class, class, class, class>
8985
friend class flat_map;
9086

@@ -93,6 +89,9 @@ class flat_map {
9389
static_assert(!is_same_v<_KeyContainer, std::vector<bool>>, "vector<bool> is not a sequence container");
9490
static_assert(!is_same_v<_MappedContainer, std::vector<bool>>, "vector<bool> is not a sequence container");
9591

92+
template <bool _Const>
93+
using __iterator = __key_value_iterator<flat_map, _KeyContainer, _MappedContainer, _Const>;
94+
9695
public:
9796
// types
9897
using key_type = _Key;
@@ -134,123 +133,6 @@ class flat_map {
134133

135134
_LIBCPP_HIDE_FROM_ABI static constexpr bool __is_compare_transparent = __is_transparent_v<_Compare, _Compare>;
136135

137-
template <bool _Const>
138-
struct __iterator {
139-
private:
140-
using __key_iterator = ranges::iterator_t<const key_container_type>;
141-
using __mapped_iterator = ranges::iterator_t<__maybe_const<_Const, mapped_container_type>>;
142-
using __reference = pair<iter_reference_t<__key_iterator>, iter_reference_t<__mapped_iterator>>;
143-
144-
struct __arrow_proxy {
145-
__reference __ref_;
146-
_LIBCPP_HIDE_FROM_ABI __reference* operator->() { return std::addressof(__ref_); }
147-
};
148-
149-
__key_iterator __key_iter_;
150-
__mapped_iterator __mapped_iter_;
151-
152-
friend flat_map;
153-
154-
public:
155-
using iterator_concept = random_access_iterator_tag;
156-
// `flat_map::iterator` only satisfy "Cpp17InputIterator" named requirements, because
157-
// its `reference` is not a reference type.
158-
// However, to avoid surprising runtime behaviour when it is used with the
159-
// Cpp17 algorithms or operations, iterator_category is set to random_access_iterator_tag.
160-
using iterator_category = random_access_iterator_tag;
161-
using value_type = flat_map::value_type;
162-
using difference_type = flat_map::difference_type;
163-
164-
_LIBCPP_HIDE_FROM_ABI __iterator() = default;
165-
166-
_LIBCPP_HIDE_FROM_ABI __iterator(__iterator<!_Const> __i)
167-
requires _Const && convertible_to<ranges::iterator_t<key_container_type>, __key_iterator> &&
168-
convertible_to<ranges::iterator_t<mapped_container_type>, __mapped_iterator>
169-
: __key_iter_(std::move(__i.__key_iter_)), __mapped_iter_(std::move(__i.__mapped_iter_)) {}
170-
171-
_LIBCPP_HIDE_FROM_ABI __iterator(__key_iterator __key_iter, __mapped_iterator __mapped_iter)
172-
: __key_iter_(std::move(__key_iter)), __mapped_iter_(std::move(__mapped_iter)) {}
173-
174-
_LIBCPP_HIDE_FROM_ABI __reference operator*() const { return __reference(*__key_iter_, *__mapped_iter_); }
175-
_LIBCPP_HIDE_FROM_ABI __arrow_proxy operator->() const { return __arrow_proxy{**this}; }
176-
177-
_LIBCPP_HIDE_FROM_ABI __iterator& operator++() {
178-
++__key_iter_;
179-
++__mapped_iter_;
180-
return *this;
181-
}
182-
183-
_LIBCPP_HIDE_FROM_ABI __iterator operator++(int) {
184-
__iterator __tmp(*this);
185-
++*this;
186-
return __tmp;
187-
}
188-
189-
_LIBCPP_HIDE_FROM_ABI __iterator& operator--() {
190-
--__key_iter_;
191-
--__mapped_iter_;
192-
return *this;
193-
}
194-
195-
_LIBCPP_HIDE_FROM_ABI __iterator operator--(int) {
196-
__iterator __tmp(*this);
197-
--*this;
198-
return __tmp;
199-
}
200-
201-
_LIBCPP_HIDE_FROM_ABI __iterator& operator+=(difference_type __x) {
202-
__key_iter_ += __x;
203-
__mapped_iter_ += __x;
204-
return *this;
205-
}
206-
207-
_LIBCPP_HIDE_FROM_ABI __iterator& operator-=(difference_type __x) {
208-
__key_iter_ -= __x;
209-
__mapped_iter_ -= __x;
210-
return *this;
211-
}
212-
213-
_LIBCPP_HIDE_FROM_ABI __reference operator[](difference_type __n) const { return *(*this + __n); }
214-
215-
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) {
216-
return __x.__key_iter_ == __y.__key_iter_;
217-
}
218-
219-
_LIBCPP_HIDE_FROM_ABI friend bool operator<(const __iterator& __x, const __iterator& __y) {
220-
return __x.__key_iter_ < __y.__key_iter_;
221-
}
222-
223-
_LIBCPP_HIDE_FROM_ABI friend bool operator>(const __iterator& __x, const __iterator& __y) { return __y < __x; }
224-
225-
_LIBCPP_HIDE_FROM_ABI friend bool operator<=(const __iterator& __x, const __iterator& __y) { return !(__y < __x); }
226-
227-
_LIBCPP_HIDE_FROM_ABI friend bool operator>=(const __iterator& __x, const __iterator& __y) { return !(__x < __y); }
228-
229-
_LIBCPP_HIDE_FROM_ABI friend auto operator<=>(const __iterator& __x, const __iterator& __y)
230-
requires three_way_comparable<__key_iterator>
231-
{
232-
return __x.__key_iter_ <=> __y.__key_iter_;
233-
}
234-
235-
_LIBCPP_HIDE_FROM_ABI friend __iterator operator+(const __iterator& __i, difference_type __n) {
236-
auto __tmp = __i;
237-
__tmp += __n;
238-
return __tmp;
239-
}
240-
241-
_LIBCPP_HIDE_FROM_ABI friend __iterator operator+(difference_type __n, const __iterator& __i) { return __i + __n; }
242-
243-
_LIBCPP_HIDE_FROM_ABI friend __iterator operator-(const __iterator& __i, difference_type __n) {
244-
auto __tmp = __i;
245-
__tmp -= __n;
246-
return __tmp;
247-
}
248-
249-
_LIBCPP_HIDE_FROM_ABI friend difference_type operator-(const __iterator& __x, const __iterator& __y) {
250-
return difference_type(__x.__key_iter_ - __y.__key_iter_);
251-
}
252-
};
253-
254136
public:
255137
// [flat.map.cons], construct/copy/destroy
256138
_LIBCPP_HIDE_FROM_ABI flat_map() noexcept(
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
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 <__ranges/access.h>
19+
#include <__type_traits/conditional.h>
20+
#include <__type_traits/maybe_const.h>
21+
#include <__utility/move.h>
22+
#include <__utility/pair.h>
23+
24+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
25+
# pragma GCC system_header
26+
#endif
27+
28+
_LIBCPP_PUSH_MACROS
29+
#include <__undef_macros>
30+
31+
#if _LIBCPP_STD_VER >= 23
32+
33+
_LIBCPP_BEGIN_NAMESPACE_STD
34+
35+
/**
36+
* __key_value_iterator is a proxy iterator which zips the underlying
37+
* _KeyContainer::iterator and the underlying _MappedContainer::iterator.
38+
* The two underlying iterators will be incremented/decremented together.
39+
* And the reference is a pair of the const key reference and the value reference.
40+
*/
41+
template <class _Owner, class _KeyContainer, class _MappedContainer, bool _Const>
42+
struct __key_value_iterator {
43+
private:
44+
using __key_iterator = ranges::iterator_t<const _KeyContainer>;
45+
using __mapped_iterator = ranges::iterator_t<__maybe_const<_Const, _MappedContainer>>;
46+
using __reference = _If<_Const, typename _Owner::const_reference, typename _Owner::reference>;
47+
48+
struct __arrow_proxy {
49+
__reference __ref_;
50+
_LIBCPP_HIDE_FROM_ABI __reference* operator->() { return std::addressof(__ref_); }
51+
};
52+
53+
__key_iterator __key_iter_;
54+
__mapped_iterator __mapped_iter_;
55+
56+
friend _Owner;
57+
58+
template <class, class, class, bool>
59+
friend struct __key_value_iterator;
60+
61+
public:
62+
using iterator_concept = random_access_iterator_tag;
63+
// `__key_value_iterator` only satisfy "Cpp17InputIterator" named requirements, because
64+
// its `reference` is not a reference type.
65+
// However, to avoid surprising runtime behaviour when it is used with the
66+
// Cpp17 algorithms or operations, iterator_category is set to random_access_iterator_tag.
67+
using iterator_category = random_access_iterator_tag;
68+
using value_type = typename _Owner::value_type;
69+
using difference_type = typename _Owner::difference_type;
70+
71+
_LIBCPP_HIDE_FROM_ABI __key_value_iterator() = default;
72+
73+
_LIBCPP_HIDE_FROM_ABI __key_value_iterator(__key_value_iterator<_Owner, _KeyContainer, _MappedContainer, !_Const> __i)
74+
requires _Const && convertible_to<ranges::iterator_t<_KeyContainer>, __key_iterator> &&
75+
convertible_to<ranges::iterator_t<_MappedContainer>, __mapped_iterator>
76+
: __key_iter_(std::move(__i.__key_iter_)), __mapped_iter_(std::move(__i.__mapped_iter_)) {}
77+
78+
_LIBCPP_HIDE_FROM_ABI __key_value_iterator(__key_iterator __key_iter, __mapped_iterator __mapped_iter)
79+
: __key_iter_(std::move(__key_iter)), __mapped_iter_(std::move(__mapped_iter)) {}
80+
81+
_LIBCPP_HIDE_FROM_ABI __reference operator*() const { return __reference(*__key_iter_, *__mapped_iter_); }
82+
_LIBCPP_HIDE_FROM_ABI __arrow_proxy operator->() const { return __arrow_proxy{**this}; }
83+
84+
_LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator++() {
85+
++__key_iter_;
86+
++__mapped_iter_;
87+
return *this;
88+
}
89+
90+
_LIBCPP_HIDE_FROM_ABI __key_value_iterator operator++(int) {
91+
__key_value_iterator __tmp(*this);
92+
++*this;
93+
return __tmp;
94+
}
95+
96+
_LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator--() {
97+
--__key_iter_;
98+
--__mapped_iter_;
99+
return *this;
100+
}
101+
102+
_LIBCPP_HIDE_FROM_ABI __key_value_iterator operator--(int) {
103+
__key_value_iterator __tmp(*this);
104+
--*this;
105+
return __tmp;
106+
}
107+
108+
_LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator+=(difference_type __x) {
109+
__key_iter_ += __x;
110+
__mapped_iter_ += __x;
111+
return *this;
112+
}
113+
114+
_LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator-=(difference_type __x) {
115+
__key_iter_ -= __x;
116+
__mapped_iter_ -= __x;
117+
return *this;
118+
}
119+
120+
_LIBCPP_HIDE_FROM_ABI __reference operator[](difference_type __n) const { return *(*this + __n); }
121+
122+
_LIBCPP_HIDE_FROM_ABI friend constexpr bool
123+
operator==(const __key_value_iterator& __x, const __key_value_iterator& __y) {
124+
return __x.__key_iter_ == __y.__key_iter_;
125+
}
126+
127+
_LIBCPP_HIDE_FROM_ABI friend bool operator<(const __key_value_iterator& __x, const __key_value_iterator& __y) {
128+
return __x.__key_iter_ < __y.__key_iter_;
129+
}
130+
131+
_LIBCPP_HIDE_FROM_ABI friend bool operator>(const __key_value_iterator& __x, const __key_value_iterator& __y) {
132+
return __y < __x;
133+
}
134+
135+
_LIBCPP_HIDE_FROM_ABI friend bool operator<=(const __key_value_iterator& __x, const __key_value_iterator& __y) {
136+
return !(__y < __x);
137+
}
138+
139+
_LIBCPP_HIDE_FROM_ABI friend bool operator>=(const __key_value_iterator& __x, const __key_value_iterator& __y) {
140+
return !(__x < __y);
141+
}
142+
143+
_LIBCPP_HIDE_FROM_ABI friend auto operator<=>(const __key_value_iterator& __x, const __key_value_iterator& __y)
144+
requires three_way_comparable<__key_iterator>
145+
{
146+
return __x.__key_iter_ <=> __y.__key_iter_;
147+
}
148+
149+
_LIBCPP_HIDE_FROM_ABI friend __key_value_iterator operator+(const __key_value_iterator& __i, difference_type __n) {
150+
auto __tmp = __i;
151+
__tmp += __n;
152+
return __tmp;
153+
}
154+
155+
_LIBCPP_HIDE_FROM_ABI friend __key_value_iterator operator+(difference_type __n, const __key_value_iterator& __i) {
156+
return __i + __n;
157+
}
158+
159+
_LIBCPP_HIDE_FROM_ABI friend __key_value_iterator operator-(const __key_value_iterator& __i, difference_type __n) {
160+
auto __tmp = __i;
161+
__tmp -= __n;
162+
return __tmp;
163+
}
164+
165+
_LIBCPP_HIDE_FROM_ABI friend difference_type
166+
operator-(const __key_value_iterator& __x, const __key_value_iterator& __y) {
167+
return difference_type(__x.__key_iter_ - __y.__key_iter_);
168+
}
169+
};
170+
171+
_LIBCPP_END_NAMESPACE_STD
172+
173+
#endif // _LIBCPP_STD_VER >= 23
174+
175+
_LIBCPP_POP_MACROS
176+
177+
#endif // _LIBCPP___FLAT_MAP_KEY_VALUE_ITERATOR_H

libcxx/include/module.modulemap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,6 +1235,7 @@ module std [system] {
12351235

12361236
module flat_map {
12371237
module flat_map { header "__flat_map/flat_map.h" }
1238+
module key_value_iterator { header "__flat_map/key_value_iterator.h" }
12381239
module sorted_unique { header "__flat_map/sorted_unique.h" }
12391240

12401241
header "flat_map"

libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/iter_iter_stability.pass.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <flat_map>
2424
#include <random>
2525
#include <map>
26+
#include <vector>
2627

2728
#include "test_macros.h"
2829

libcxx/test/std/containers/container.adaptors/flat.map/flat.map.iterators/reverse_iterator.pass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#include <deque>
2424
#include <flat_map>
2525
#include <functional>
26-
#include <string>
26+
#include <vector>
2727

2828
#include <iterator>
2929

libcxx/test/std/containers/container.adaptors/flat.map/incomplete_type.pass.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
// type.
1515

1616
#include <flat_map>
17+
#include <vector>
1718

1819
struct A {
1920
using Map = std::flat_map<A, A>;

0 commit comments

Comments
 (0)