Skip to content

Commit 292f841

Browse files
committed
flat_map : insert_rangeを追加 #1078
1 parent f3f7503 commit 292f841

File tree

3 files changed

+132
-48
lines changed

3 files changed

+132
-48
lines changed

reference/flat_map/flat_map.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ namespace std {
6060
| [`clear`](flat_map/clear.md) | 全ての要素を削除する | C++23 |
6161
| [`insert`](flat_map/insert.md) | 要素を挿入する | C++23 |
6262
| [`insert_or_assign`](flat_map/insert_or_assign.md.nolink) | 要素を挿入、あるいは代入する | C++23 |
63-
| [`insert_range`](flat_map/insert_range.md.nolink) | Rangeを挿入する | C++23 |
63+
| [`insert_range`](flat_map/insert_range.md) | Rangeを挿入する | C++23 |
6464
| [`emplace`](flat_map/emplace.md) | 要素を直接構築する | C++23 |
6565
| [`emplace_hint`](flat_map/emplace_hint.md) | ヒントを使って要素を直接構築する | C++23 |
6666
| [`try_emplace`](flat_map/try_emplace.md) | キーが存在しない場合のみ要素を直接構築する | C++23 |

reference/flat_map/flat_map/insert.md

+11-47
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,10 @@ void insert(sorted_unique_t,
3030
InputIterator first,
3131
InputIterator last); // (8) C++23
3232

33-
template<container-compatible-range<value_type> R>
34-
void insert_range(R&& rg); // (9) C++23
35-
36-
void insert(initializer_list<value_type> il); // (10) C++23
33+
void insert(initializer_list<value_type> il); // (9) C++23
3734

3835
void insert(sorted_unique_t s,
39-
initializer_list<value_type> il); // (11) C++23
36+
initializer_list<value_type> il); // (10) C++23
4037
```
4138
* pair[link /reference/utility/pair.md]
4239
* initializer_list[link /reference/initializer_list/initializer_list.md]
@@ -64,9 +61,8 @@ void insert(sorted_unique_t s,
6461
- (6) : 指定された位置に、要素型`value_type`のコンストラクタ引数を受け取って挿入する
6562
- (7) : イテレータ範囲`[first, last)`を挿入する
6663
- (8) : ソート済みかつ重複要素のないイテレータ範囲`[first, last)`を挿入する
67-
- (9) : Rangeを挿入する
68-
- (10) : 初期化子リストを挿入する
69-
- (11) : ソート済みかつ重複要素のない初期化子リストを挿入する
64+
- (9) : 初期化子リストを挿入する
65+
- (10) : ソート済みかつ重複要素のない初期化子リストを挿入する
7066
7167
7268
## 要件
@@ -181,44 +177,12 @@ void insert(sorted_unique_t s,
181177
* key_equiv[link key_equiv.md]
182178
* distance[link /reference/iterator/distance.md]
183179
184-
- (9) : メンバ変数として保持しているコンテナ`c`に、以下のように挿入する:
185-
```cpp
186-
for (const auto& e : rg) {
187-
c.keys.insert(c.keys.end(), e.first);
188-
c.values.insert(c.values.end(), e.second);
189-
}
190-
```
191-
* c.keys[link containers.md]
192-
* c.values[link containers.md]
193-
* end()[link /reference/vector/vector/end.md]
194-
* insert[link /reference/vector/vector/insert.md]
195-
* first[link /reference/utility/pair.md]
196-
* second[link /reference/utility/pair.md]
197-
198-
- 次に、新しく挿入された要素の範囲を`value_comp()`を基準にソートする
199-
- 次に、ソートされた結果の範囲と、既存の要素のソートされた範囲をひとつのソートされた範囲にマージする
200-
- 最後に、重複する要素を以下のように削除する:
201-
202-
```cpp
203-
auto zv = ranges::zip_view(c.keys, c.values);
204-
auto it = ranges::unique(zv, key_equiv(compare)).begin();
205-
auto dist = distance(zv.begin(), it);
206-
c.keys.erase(c.keys.begin() + dist, c.keys.end());
207-
c.values.erase(c.values.begin() + dist, c.values.end());
208-
```
209-
* c.keys[link containers.md]
210-
* c.values[link containers.md]
211-
* ranges::zip_view[link /ranges/zip_view.md.nolink]
212-
* ranges::unique[link /reference/algorithm/ranges_unique.md]
213-
* key_equiv[link key_equiv.md]
214-
* distance[link /reference/iterator/distance.md]
215-
216-
- (10) :
180+
- (9) :
217181
```cpp
218182
insert(il.begin(), il.end());
219183
```
220184
221-
- (11) :
185+
- (10) :
222186
```cpp
223187
insert(s, il.begin(), il.end());
224188
```
@@ -231,17 +195,16 @@ void insert(sorted_unique_t s,
231195
- (3), (4), (6) :
232196
- 挿入された場合には、新しく挿入された要素を指すイテレータを返す。
233197
- 挿入されなかった場合には、`x`のキーと等価のキーを持つ要素へのイテレータを返す。
234-
- (7), (8), (9), (10), (11) : なし
198+
- (7), (8), (9), (10) : なし
235199
236200
237201
## 計算量
238202
- (7) : Nをこの操作の前の[`size()`](size.md)、Mを[`distance`](/reference/iterator/distance.md)`(first, last)`として、N + MlogM
239-
- (7) : Nをこの操作のあとの[`size()`](size.md)として、Nに対して線形
240-
- (8) : Nをこの操作の前の[`size()`](size.md)、Mを[`ranges::distance`](/reference/iterator/ranges_distance.md)`(rg)`として、N + MlogM
203+
- (8) : Nをこの操作のあとの[`size()`](size.md)として、Nに対して線形
241204
242205
243206
## 備考
244-
- (7), (8), (9) : この操作はインプレース・マージを行うため、追加のメモリ確保を行う可能性がある
207+
- (7), (8) : この操作はインプレース・マージを行うため、追加のメモリ確保を行う可能性がある
245208
246209
247210
## 例
@@ -263,7 +226,6 @@ int main()
263226
};
264227
265228
// シーケンスを挿入する
266-
fm.insert(fm2);
267229
fm.insert(fm2.begin(), fm2.end());
268230
269231
// 挿入するシーケンスがソート済みかつ重複要素がないことがわかっている場合、
@@ -275,6 +237,7 @@ int main()
275237
}
276238
}
277239
```
240+
* insert[color ff0000]
278241
* begin()[link begin.md]
279242
* end()[link end.md]
280243
* std::sorted_unique[link /reference/flat_map/sorted_unique_t.md]
@@ -298,6 +261,7 @@ int main()
298261
| 名前 | 説明 |
299262
|------------------------------------------------|--------------------------------------------|
300263
| [`flat_map::insert_or_assign`](insert_or_assign.md.nolink) | 要素を挿入、あるいは代入する |
264+
| [`flat_map::insert_range`](insert_range.md) | Rangeを挿入する |
301265
| [`flat_map::emplace`](emplace.md) | 要素を直接構築する |
302266
| [`flat_map::emplace_hint`](emplace_hint.md) | ヒントを使って要素を直接構築する |
303267
| [`flat_map::try_emplace`](try_emplace.md) | キーが存在しない場合のみ要素を直接構築する |
+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# insert_range
2+
* flat_map[meta header]
3+
* std[meta namespace]
4+
* flat_map[meta class]
5+
* function[meta id-type]
6+
* cpp23[meta cpp]
7+
8+
```cpp
9+
template<container-compatible-range<value_type> R>
10+
void insert_range(R&& rg); // (1) C++23
11+
```
12+
* container-compatible-range[link /reference/exposition-only/container-compatible-range.md]
13+
14+
## 概要
15+
Rangeを挿入し、コンテナを拡張する。
16+
17+
これは、挿入された要素の数だけコンテナの [`size()`](size.md) を増やす。
18+
19+
`flat_map` コンテナは重複したキーを持つ要素を許さないため、挿入操作はそれぞれの要素が他のコンテナ内の既存要素と同じキーかどうかをチェックする。もし同じであれば要素は挿入されない。
20+
21+
重複した値を許す、類似したコンテナについては `flat_multimap` を参照。
22+
23+
内部的に `flat_map` コンテナは、コンストラクト時に指定された比較オブジェクトによって要素を下位から上位へとソートして保持する。
24+
25+
26+
## 効果
27+
- メンバ変数として保持しているコンテナ`c`に、以下のように挿入する:
28+
```cpp
29+
for (const auto& e : rg) {
30+
c.keys.insert(c.keys.end(), e.first);
31+
c.values.insert(c.values.end(), e.second);
32+
}
33+
```
34+
* c.keys[link containers.md]
35+
* c.values[link containers.md]
36+
* end()[link /reference/vector/vector/end.md]
37+
* insert[link /reference/vector/vector/insert.md]
38+
* first[link /reference/utility/pair.md]
39+
* second[link /reference/utility/pair.md]
40+
41+
- 次に、新しく挿入された要素の範囲を`value_comp()`を基準にソートする
42+
- 次に、ソートされた結果の範囲と、既存の要素のソートされた範囲をひとつのソートされた範囲にマージする
43+
- 最後に、重複する要素を以下のように削除する:
44+
45+
```cpp
46+
auto zv = ranges::zip_view(c.keys, c.values);
47+
auto it = ranges::unique(zv, key_equiv(compare)).begin();
48+
auto dist = distance(zv.begin(), it);
49+
c.keys.erase(c.keys.begin() + dist, c.keys.end());
50+
c.values.erase(c.values.begin() + dist, c.values.end());
51+
```
52+
* c.keys[link containers.md]
53+
* c.values[link containers.md]
54+
* ranges::zip_view[link /ranges/zip_view.md.nolink]
55+
* ranges::unique[link /reference/algorithm/ranges_unique.md]
56+
* key_equiv[link key_equiv.md]
57+
* distance[link /reference/iterator/distance.md]
58+
59+
60+
## 戻り値
61+
なし
62+
63+
64+
## 計算量
65+
- Nをこの操作の前の[`size()`](size.md)、Mを[`ranges::distance`](/reference/iterator/ranges_distance.md)`(rg)`として、N + MlogM
66+
67+
68+
## 備考
69+
- この操作はインプレース・マージを行うため、追加のメモリ確保を行う可能性がある
70+
71+
72+
## 例
73+
```cpp example
74+
#include <iostream>
75+
#include <flat_map>
76+
77+
int main()
78+
{
79+
std::flat_map<int, char> fm = {
80+
{3, 'a'}
81+
};
82+
83+
std::flat_map<int, char> fm2 = {
84+
{5, 'd'},
85+
{15, 'e'}
86+
};
87+
88+
fm.insert_range(fm2);
89+
90+
for (const auto& [key, value] : fm) {
91+
std::cout << key << " : " << value << std::endl;
92+
}
93+
}
94+
```
95+
* insert_range[color ff0000]
96+
97+
### 出力
98+
```
99+
3 : a
100+
5 : d
101+
15 : e
102+
```
103+
104+
## バージョン
105+
### 処理系
106+
- [Clang](/implementation.md#clang): ??
107+
- [GCC](/implementation.md#gcc): ??
108+
- [Visual C++](/implementation.md#visual_cpp): ??
109+
110+
111+
## 関連項目
112+
113+
| 名前 | 説明 |
114+
|------------------------------------------------|--------------------------------------------|
115+
| [`flat_map::insert`](insert.md) | 要素を挿入する |
116+
| [`flat_map::insert_or_assign`](insert_or_assign.md.nolink) | 要素を挿入、あるいは代入する |
117+
| [`flat_map::emplace`](emplace.md) | 要素を直接構築する |
118+
| [`flat_map::emplace_hint`](emplace_hint.md) | ヒントを使って要素を直接構築する |
119+
| [`flat_map::try_emplace`](try_emplace.md) | キーが存在しない場合のみ要素を直接構築する |
120+

0 commit comments

Comments
 (0)