Skip to content

Commit e2606de

Browse files
committed
polymorphic_allocator : P0339R6対応 #642
1 parent d2203cf commit e2606de

File tree

9 files changed

+664
-8
lines changed

9 files changed

+664
-8
lines changed

reference/memory_resource/memory_resource/allocate.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,16 @@ void* allocate(size_t bytes, size_t alignment = alignof(max_align_t)); // (1) C+
1515
* max_align_t[link /reference/cstddef/max_align_t.md]
1616
1717
## 概要
18-
メモリを確保する。
18+
19+
指定されたバイト数とアライメントでメモリを確保する。
1920
2021
## 事前条件
2122
呼び出す`do_allocate`の要件として
2223
`alignment`は2の累乗であること。
2324
2425
## 引数
25-
- `bytes` -- 確保したい領域のサイズ
26-
- `alignment` -- 確保領域のアライメント要求
26+
- `bytes` -- 確保したい領域のサイズ(バイト数)
27+
- `alignment` -- 確保領域へのアライメント要求
2728
2829
## 効果
2930
`return this->do_allocate(bytes, alignment);` と等価。

reference/memory_resource/memory_resource/deallocate.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ void deallocate(void* p, std::size_t bytes, std::size_t alignment = alignof(std:
1313
## 概要
1414
[`allocate`](allocate.md)によって確保されたメモリを解放する。
1515
16-
## 要件
16+
## 事前条件
1717
呼び出す`do_deallocate`の要件として
1818
`p`の指すサイズ`bytes`のメモリ領域は、`*this`もしくは等しい`memory_resource`オブジェクト(`this->is_equal(other) == true`となるような`other`)の[`allocate`](allocate.md)`(bytes, alignment)`によって事前に確保された領域であること。
1919
かつ、そのメモリ領域は未解放であること。

reference/memory_resource/polymorphic_allocator.md

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,54 @@
77
```cpp
88
namespace std::pmr {
99
template <class Tp>
10-
class polymorphic_allocator;
10+
class polymorphic_allocator; //C++17
11+
12+
template <class Tp = byte>
13+
class polymorphic_allocator; //C++20
1114
}
1215
```
16+
* byte[link /reference/cstddef/byte.md]
1317
1418
## 概要
1519
`polymorphic_allocator`は任意の[`memory_resource`](memory_resource.md)実装によりメモリ確保・解放戦略に関わる実際の処理を動的に切り替えることのできるアロケータである。この様な設計は一般にStrategyパターンというデザインパターンの一つとして知られている。
1620
1721
このクラスと[`memory_resource`](memory_resource.md)の利用により、同じ静的型`polymorphic_allocator<Tp>`で実行時に異なるメモリの確保・解放戦略をとるアロケータの利用が可能になる。
1822
23+
C++20にてC++プログラミングにおいての基礎部品となる型(*vocabulary type*)となるように改修され、`polymorphic_allocator<>`の形で幅広く利用できるようになった。
24+
1925
## メンバ関数
2026
27+
### 構築・破棄
28+
2129
| 名前 | 説明 | 対応バージョン |
2230
|-----------------|----------------|----------------|
2331
| [`(constructor)`](polymorphic_allocator/op_constructor.md) | コンストラクタ | C++17 |
2432
| `operator=(const polymorphic_allocator& rhs) = delete;` | コピー代入演算子(コピー禁止) | C++17 |
25-
| [`allocate`](polymorphic_allocator/allocate.md) | メモリを確保する | C++17 |
26-
| [`deallocate`](polymorphic_allocator/deallocate.md) | メモリを解放する | C++17 |
33+
34+
### メモリ確保・解放のみを行う関数
35+
36+
| 名前 | 説明 | 対応バージョン |
37+
|-----------------|----------------|----------------|
38+
| [`allocate`](polymorphic_allocator/allocate.md) | `Tp`の指定した要素数分のメモリを確保する | C++17 |
39+
| [`deallocate`](polymorphic_allocator/deallocate.md) | `Tp`の指定した要素数分のメモリを解放する | C++17 |
40+
| [`allocate_bytes`](polymorphic_allocator/allocate_bytes.md) | 指定したバイト数のメモリを確保する | C++20 |
41+
| [`deallocate_bytes`](polymorphic_allocator/deallocate_bytes.md) | 指定したバイト数のメモリを解放する | C++20 |
42+
| [`allocate_object`](polymorphic_allocator/allocate_object.md) | 指定した型の指定した要素数分のメモリを確保する | C++20 |
43+
| [`deallocate_object`](polymorphic_allocator/deallocate_object.md) | 指定した型の指定した要素数分のメモリを解放する | C++20 |
44+
45+
### オブジェクト構築・破棄を行う関数
46+
47+
| 名前 | 説明 | 対応バージョン |
48+
|-----------------|----------------|----------------|
2749
| [`construct`](polymorphic_allocator/construct.md) | 指定された領域にオブジェクトを構築する | C++17 |
2850
| [`destroy`](polymorphic_allocator/destroy.md) | 指定された領域のオブジェクトを破棄する | C++17 |
51+
| [`new_object`](polymorphic_allocator/new_object.md) | メモリを確保し指定した型の構築(`new`式相当の処理)を行う | C++20 |
52+
| [`delete_object`](polymorphic_allocator/delete_object.md) | 指定した型の破棄とそのメモリ領域の解放(`delete`式相当の処理)を行う | C++20 |
53+
54+
### その他関数
55+
56+
| 名前 | 説明 | 対応バージョン |
57+
|-----------------|----------------|----------------|
2958
| [`select_on_container_copy_construction`](polymorphic_allocator/select_on_container_copy_construction.md) | コンテナのコピー構築時に新しい`polymorphic_allocator<Tp>`を取得する | C++17 |
3059
| [`resource`](polymorphic_allocator/resource.md) | 使用している`memory_resource`を取得する | C++17 |
3160
@@ -61,4 +90,5 @@ namespace std::pmr {
6190
- [Polymorphic Allocator in C++17 - Qita](https://qiita.com/MitsutakaTakeda/items/48980faa9498c46b15b2)
6291
- [P0220R1 Adopt Library Fundamentals V1 TS Components for C++17 (R1)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0220r1.html)
6392
- [P0337r0 | Delete operator= for polymorphic_allocator](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0337r0.html)
64-
- [Working Draft, C++ Extensions for Library Fundamentals, Version 2](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4562.html#memory.resource.synop)
93+
- [Working Draft, C++ Extensions for Library Fundamentals, Version 2](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4562.html#memory.resource.synop)
94+
- [P0339R6 polymorphic_allocator<> as a vocabulary type](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0339r6.pdf)
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# allocate_bytes
2+
* memory_resource[meta header]
3+
* function[meta id-type]
4+
* std::pmr[meta namespace]
5+
* polymorphic_allocator[meta class]
6+
* cpp17[meta cpp]
7+
8+
```cpp
9+
void* allocate_bytes(size_t nbytes, size_t alignment = alignof(max_align_t));
10+
```
11+
* max_align_t[link /reference/cstddef/max_align_t.md]
12+
13+
## 概要
14+
15+
指定されたバイト数とアライメントでメモリを確保する。
16+
17+
## 事前条件
18+
19+
`alignment`は2の累乗であること。
20+
21+
## 引数
22+
23+
- `nbytes` -- 確保したい領域のサイズ(バイト数)
24+
- `alignment` -- 確保領域へのアライメント要求
25+
26+
27+
## 効果
28+
29+
利用する[`memory_resource`](/reference/memory_resource/memory_resource.md)のポインタを`memory_rsrc`というメンバに保持しているとすると、以下と等価。
30+
31+
```cpp
32+
return memory_­rsrc->allocate(nbytes, alignment);
33+
```
34+
* allocate[link /reference/memory_resource/memory_resource/allocate.md]
35+
36+
## 戻り値
37+
38+
確保した領域の先頭へのポインタ。
39+
40+
## 例外
41+
42+
要求されたアライメントでサイズ`nbytes`のメモリを確保できない場合、例外が送出される。
43+
44+
##
45+
```cpp example
46+
#include <iostream>
47+
#include <memory_resource>
48+
49+
int main() {
50+
constexpr int N = 10;
51+
52+
std::pmr::polymorphic_allocator<> alloc{};
53+
54+
//int型10個分の領域をデフォルトアライメントで確保
55+
void* vp = alloc.allocate_bytes(sizeof(int) * N, alignof(int));
56+
57+
//確保したメモリ領域へのポインタを所望の型のものにキャスト
58+
int* p = static_cast<int*>(vp);
59+
60+
//確保したメモリ領域にintのオブジェクトを構築(コンストラクタ呼び出し)
61+
for (int i = 0; i < N; ++i) {
62+
alloc.construct(p+i, i);
63+
}
64+
65+
66+
std::cout << "address : " << vp << std::endl;
67+
68+
for (int i = 0; i < N; ++i) {
69+
std::cout << p[i] << "\n";
70+
}
71+
72+
73+
//領域上のオブジェクトを破棄(デストラクタ呼び出し)
74+
for (int i = 0; i < N; ++i) {
75+
alloc.destroy(p+i);
76+
}
77+
78+
//確保したメモリ領域を解放
79+
alloc.deallocate_bytes(vp, N, alignof(int));
80+
}
81+
```
82+
* allocate_bytes[color ff0000]
83+
* construct[link construct.md]
84+
* destroy[link destroy.md]
85+
* deallocate_bytes[link deallocate_bytes.md]
86+
87+
### 出力例(GCC9.2)
88+
```
89+
address : 0x1c38150
90+
0
91+
1
92+
2
93+
3
94+
4
95+
5
96+
6
97+
7
98+
8
99+
9
100+
```
101+
102+
## バージョン
103+
### 言語
104+
- C++20
105+
106+
### 処理系
107+
- [Clang](/implementation.md#clang): ??
108+
- [GCC](/implementation.md#gcc): 9.1
109+
- [Visual C++](/implementation.md#visual_cpp): ??
110+
111+
## 関連項目
112+
- [`memory_resource::allocate`](/reference/memory_resource/memory_resource/allocate.md)
113+
114+
## 参照
115+
- [P0339R6 polymorphic_allocator<> as a vocabulary type](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0339r6.pdf)
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# allocate_object
2+
* memory_resource[meta header]
3+
* function[meta id-type]
4+
* std::pmr[meta namespace]
5+
* polymorphic_allocator[meta class]
6+
* cpp17[meta cpp]
7+
8+
```cpp
9+
template <class T>
10+
T* allocate_object(size_t n = 1);
11+
```
12+
13+
## 概要
14+
15+
指定された個数の`T`型の配列として十分なメモリを確保する。
16+
17+
## 引数
18+
19+
- `n` -- 確保する領域の数、バイト数ではなく配列の要素数相当
20+
21+
## 効果
22+
23+
以下と等価。
24+
25+
```cpp
26+
return static_cast<T*>(this->allocate_bytes(n*sizeof(T), alignof(T)));
27+
```
28+
* allocate_bytes[link allocate_bytes.md]
29+
30+
## 戻り値
31+
確保した領域の先頭へのポインタ。
32+
33+
## 例外
34+
35+
[`SIZE_MAX`](/reference/cstdint/size_max.md) `/ sizeof(T) < n`である場合、[`std::length_error`](/reference/stdexcept.md)例外を送出する
36+
37+
## 備考
38+
39+
`T`は引数から推論することができないため、明示的に指定する必要がある。
40+
41+
##
42+
```cpp example
43+
#include <iostream>
44+
#include <memory_resource>
45+
46+
int main() {
47+
48+
constexpr int N = 10;
49+
50+
std::pmr::polymorphic_allocator<> alloc{};
51+
52+
//int型10個分の領域を確保
53+
int* p = alloc.allocate_object<int>(N);
54+
55+
//確保した領域にintのオブジェクトを構築
56+
for (int i = 0; i < N; ++i) {
57+
alloc.construct(p+i, i);
58+
}
59+
60+
61+
for (int i = 0; i < N; ++i) {
62+
std::cout << p[i] << "\n";
63+
}
64+
65+
66+
//領域上のオブジェクトを破棄
67+
for (int i = 0; i < N; ++i) {
68+
alloc.destroy(p+i);
69+
}
70+
71+
//確保したメモリ領域を解放
72+
alloc.deallocate_object(p, N);
73+
}
74+
```
75+
* allocate_object[color ff0000]
76+
* construct[link construct.md]
77+
* destroy[link destroy.md]
78+
* deallocate_object[link deallocate_object.md]
79+
80+
### 出力
81+
```
82+
0
83+
1
84+
2
85+
3
86+
4
87+
5
88+
6
89+
7
90+
8
91+
9
92+
```
93+
94+
## バージョン
95+
### 言語
96+
- C++20
97+
98+
### 処理系
99+
- [Clang](/implementation.md#clang): ??
100+
- [GCC](/implementation.md#gcc): 9.1
101+
- [Visual C++](/implementation.md#visual_cpp): ??
102+
103+
## 関連項目
104+
- [`allocate_bytes`](/reference/memory_resource/polymorphic_allocator/allocate_bytes.md)
105+
106+
## 参照
107+
- [P0339R6 polymorphic_allocator<> as a vocabulary type](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0339r6.pdf)

0 commit comments

Comments
 (0)