Skip to content

Commit 7c8ccd8

Browse files
Hui XieHui Xie
authored andcommitted
[libc++] Move out (for reusing it in flat_multimap)
1 parent 213b849 commit 7c8ccd8

File tree

8 files changed

+193
-138
lines changed

8 files changed

+193
-138
lines changed

libcxx/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ set(files
358358
__filesystem/space_info.h
359359
__filesystem/u8path.h
360360
__flat_map/flat_map.h
361+
__flat_map/key_value_iterator.h
361362
__flat_map/sorted_unique.h
362363
__format/buffer.h
363364
__format/concepts.h

libcxx/include/__flat_map/flat_map.h

Lines changed: 17 additions & 137 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(
@@ -1307,22 +1189,20 @@ template <ranges::input_range _Range,
13071189
class _Compare = less<__range_key_type<_Range>>,
13081190
class _Allocator = allocator<byte>,
13091191
class = __enable_if_t<!__is_allocator<_Compare>::value && __is_allocator<_Allocator>::value>>
1310-
flat_map(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
1311-
-> flat_map<
1312-
__range_key_type<_Range>,
1313-
__range_mapped_type<_Range>,
1314-
_Compare,
1315-
vector<__range_key_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_key_type<_Range>>>,
1316-
vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_mapped_type<_Range>>>>;
1192+
flat_map(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator()) -> flat_map<
1193+
__range_key_type<_Range>,
1194+
__range_mapped_type<_Range>,
1195+
_Compare,
1196+
vector<__range_key_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_key_type<_Range>>>,
1197+
vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_mapped_type<_Range>>>>;
13171198

13181199
template <ranges::input_range _Range, class _Allocator, class = __enable_if_t<__is_allocator<_Allocator>::value>>
1319-
flat_map(from_range_t, _Range&&, _Allocator)
1320-
-> flat_map<
1321-
__range_key_type<_Range>,
1322-
__range_mapped_type<_Range>,
1323-
less<__range_key_type<_Range>>,
1324-
vector<__range_key_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_key_type<_Range>>>,
1325-
vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_mapped_type<_Range>>>>;
1200+
flat_map(from_range_t, _Range&&, _Allocator) -> flat_map<
1201+
__range_key_type<_Range>,
1202+
__range_mapped_type<_Range>,
1203+
less<__range_key_type<_Range>>,
1204+
vector<__range_key_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_key_type<_Range>>>,
1205+
vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_mapped_type<_Range>>>>;
13261206

13271207
template <class _Key, class _Tp, class _Compare = less<_Key>>
13281208
requires(!__is_allocator<_Compare>::value)
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
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/maybe_const.h>
20+
#include <__utility/move.h>
21+
#include <__utility/pair.h>
22+
23+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
24+
# pragma GCC system_header
25+
#endif
26+
27+
_LIBCPP_PUSH_MACROS
28+
#include <__undef_macros>
29+
30+
#if _LIBCPP_STD_VER >= 23
31+
32+
_LIBCPP_BEGIN_NAMESPACE_STD
33+
34+
template <class _Owner, class _KeyContainer, class _MappedContainer, bool _Const>
35+
struct __key_value_iterator {
36+
private:
37+
using __key_iterator = ranges::iterator_t<const _KeyContainer>;
38+
using __mapped_iterator = ranges::iterator_t<__maybe_const<_Const, _MappedContainer>>;
39+
using __reference = pair<iter_reference_t<__key_iterator>, iter_reference_t<__mapped_iterator>>;
40+
41+
struct __arrow_proxy {
42+
__reference __ref_;
43+
_LIBCPP_HIDE_FROM_ABI __reference* operator->() { return std::addressof(__ref_); }
44+
};
45+
46+
__key_iterator __key_iter_;
47+
__mapped_iterator __mapped_iter_;
48+
49+
friend _Owner;
50+
51+
template <class, class, class, bool>
52+
friend struct __key_value_iterator;
53+
54+
public:
55+
using iterator_concept = random_access_iterator_tag;
56+
// `flat_map::iterator` only satisfy "Cpp17InputIterator" named requirements, because
57+
// its `reference` is not a reference type.
58+
// However, to avoid surprising runtime behaviour when it is used with the
59+
// Cpp17 algorithms or operations, iterator_category is set to random_access_iterator_tag.
60+
using iterator_category = random_access_iterator_tag;
61+
using value_type = typename _Owner::value_type;
62+
using difference_type = typename _Owner::difference_type;
63+
64+
_LIBCPP_HIDE_FROM_ABI __key_value_iterator() = default;
65+
66+
_LIBCPP_HIDE_FROM_ABI __key_value_iterator(__key_value_iterator<_Owner, _KeyContainer, _MappedContainer, !_Const> __i)
67+
requires _Const && convertible_to<ranges::iterator_t<_KeyContainer>, __key_iterator> &&
68+
convertible_to<ranges::iterator_t<_MappedContainer>, __mapped_iterator>
69+
: __key_iter_(std::move(__i.__key_iter_)), __mapped_iter_(std::move(__i.__mapped_iter_)) {}
70+
71+
_LIBCPP_HIDE_FROM_ABI __key_value_iterator(__key_iterator __key_iter, __mapped_iterator __mapped_iter)
72+
: __key_iter_(std::move(__key_iter)), __mapped_iter_(std::move(__mapped_iter)) {}
73+
74+
_LIBCPP_HIDE_FROM_ABI __reference operator*() const { return __reference(*__key_iter_, *__mapped_iter_); }
75+
_LIBCPP_HIDE_FROM_ABI __arrow_proxy operator->() const { return __arrow_proxy{**this}; }
76+
77+
_LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator++() {
78+
++__key_iter_;
79+
++__mapped_iter_;
80+
return *this;
81+
}
82+
83+
_LIBCPP_HIDE_FROM_ABI __key_value_iterator operator++(int) {
84+
__key_value_iterator __tmp(*this);
85+
++*this;
86+
return __tmp;
87+
}
88+
89+
_LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator--() {
90+
--__key_iter_;
91+
--__mapped_iter_;
92+
return *this;
93+
}
94+
95+
_LIBCPP_HIDE_FROM_ABI __key_value_iterator operator--(int) {
96+
__key_value_iterator __tmp(*this);
97+
--*this;
98+
return __tmp;
99+
}
100+
101+
_LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator+=(difference_type __x) {
102+
__key_iter_ += __x;
103+
__mapped_iter_ += __x;
104+
return *this;
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 __reference operator[](difference_type __n) const { return *(*this + __n); }
114+
115+
_LIBCPP_HIDE_FROM_ABI friend constexpr bool
116+
operator==(const __key_value_iterator& __x, const __key_value_iterator& __y) {
117+
return __x.__key_iter_ == __y.__key_iter_;
118+
}
119+
120+
_LIBCPP_HIDE_FROM_ABI friend bool operator<(const __key_value_iterator& __x, const __key_value_iterator& __y) {
121+
return __x.__key_iter_ < __y.__key_iter_;
122+
}
123+
124+
_LIBCPP_HIDE_FROM_ABI friend bool operator>(const __key_value_iterator& __x, const __key_value_iterator& __y) {
125+
return __y < __x;
126+
}
127+
128+
_LIBCPP_HIDE_FROM_ABI friend bool operator<=(const __key_value_iterator& __x, const __key_value_iterator& __y) {
129+
return !(__y < __x);
130+
}
131+
132+
_LIBCPP_HIDE_FROM_ABI friend bool operator>=(const __key_value_iterator& __x, const __key_value_iterator& __y) {
133+
return !(__x < __y);
134+
}
135+
136+
_LIBCPP_HIDE_FROM_ABI friend auto operator<=>(const __key_value_iterator& __x, const __key_value_iterator& __y)
137+
requires three_way_comparable<__key_iterator>
138+
{
139+
return __x.__key_iter_ <=> __y.__key_iter_;
140+
}
141+
142+
_LIBCPP_HIDE_FROM_ABI friend __key_value_iterator operator+(const __key_value_iterator& __i, difference_type __n) {
143+
auto __tmp = __i;
144+
__tmp += __n;
145+
return __tmp;
146+
}
147+
148+
_LIBCPP_HIDE_FROM_ABI friend __key_value_iterator operator+(difference_type __n, const __key_value_iterator& __i) {
149+
return __i + __n;
150+
}
151+
152+
_LIBCPP_HIDE_FROM_ABI friend __key_value_iterator operator-(const __key_value_iterator& __i, difference_type __n) {
153+
auto __tmp = __i;
154+
__tmp -= __n;
155+
return __tmp;
156+
}
157+
158+
_LIBCPP_HIDE_FROM_ABI friend difference_type
159+
operator-(const __key_value_iterator& __x, const __key_value_iterator& __y) {
160+
return difference_type(__x.__key_iter_ - __y.__key_iter_);
161+
}
162+
};
163+
164+
_LIBCPP_END_NAMESPACE_STD
165+
166+
#endif // _LIBCPP_STD_VER >= 23
167+
168+
_LIBCPP_POP_MACROS
169+
170+
#endif // _LIBCPP___FLAT_MAP_KEY_VALUE_ITERATOR_H

libcxx/include/flat_map

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ namespace std {
4040
#include <__assert> // all public C++ headers provide the assertion handler
4141
#include <__config>
4242
#include <__flat_map/flat_map.h>
43+
#include <__flat_map/key_value_iterator.h>
4344
#include <__flat_map/sorted_unique.h>
4445
#include <version>
4546

0 commit comments

Comments
 (0)