Skip to content

Commit a7b1a5e

Browse files
committed
memory: P1132R8 inout_ptr_t,inout_ptr追加(#1050)
1 parent ccd76f6 commit a7b1a5e

File tree

10 files changed

+388
-7
lines changed

10 files changed

+388
-7
lines changed

lang/cpp23.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ C++23とは、2023年中に改訂される予定の、C++バージョンの通
193193

194194

195195
### メモリ
196-
- [`<memory>`](/reference/memory.md)に、レガシーC関数からスマートポインタへの直接出力をサポートする、スマートポインタアダプタ[`std::out_ptr`](/reference/memory/out_ptr.md)[`std::inout_ptr`](/reference/memory/inout_ptr.md.nolink)を追加
196+
- [`<memory>`](/reference/memory.md)に、レガシーC関数からスマートポインタへの直接出力をサポートする、スマートポインタアダプタ[`std::out_ptr`](/reference/memory/out_ptr.md)[`std::inout_ptr`](/reference/memory/inout_ptr.md)を追加
197197
- [`std::unique_ptr`](/reference/memory/unique_ptr.md)クラスを`constexpr`に対応
198198
- [`<memory>`](/reference/memory.md)に、オブジェクトの生存期間を開始することを明示する関数として、[`std::start_lifetime_as()`](/reference/memory/start_lifetime_as.md.nolink)[`std::start_lifetime_as_array()`](/reference/memory/start_lifetime_as_array.md.nolink)を追加
199199
- [`<bit>`](/reference/bit.md)に、値のバイト入れ替え (エンディアン変換) を行う[`std::byteswap()`](/reference/bit/byteswap.md)関数を追加

reference/memory.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@
9696
|------|------|-------|
9797
| [`out_ptr_t`](memory/out_ptr_t.md) | スマートポインタへの出力サポート(class template) | C++23 |
9898
| [`out_ptr`](memory/out_ptr.md) | スマートポインタへの出力サポートヘルパ関数(function template) | C++23 |
99-
| [`inout_ptr_t`](memory/inout_ptr_t.md.nolink) | スマートポインタへの入出力サポート(class template) | C++23 |
100-
| [`inout_ptr`](memory/inout_ptr.md.nolink) | スマートポインタへの入出力サポートヘルパ関数(function template) | C++23 |
99+
| [`inout_ptr_t`](memory/inout_ptr_t.md) | スマートポインタへの入出力サポート(class template) | C++23 |
100+
| [`inout_ptr`](memory/inout_ptr.md) | スマートポインタへの入出力サポートヘルパ関数(function template) | C++23 |
101101

102102

103103
## スマートポインタのアトミック操作

reference/memory/inout_ptr.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# inout_ptr
2+
* memory[meta header]
3+
* function template[meta id-type]
4+
* std[meta namespace]
5+
* cpp23[meta cpp]
6+
7+
```cpp
8+
namespace std {
9+
template<class Pointer = void, class Smart, class... Args>
10+
auto inout_ptr(Smart& s, Args&&... args);
11+
}
12+
```
13+
14+
## 概要
15+
2重ポインタ`T**`引数経由で既存リソースを解放してから新規確保リソースへのポインタを返すレガシーC関数に対して、出力されたポインタ値をスマートポインタ`s`に格納するアダプタ[`inout_ptr_t`](inout_ptr_t.md)を返すヘルパ関数。
16+
17+
リソース占有管理セマンティクスを提供するC++標準スマートポインタ[`std::unique_ptr`](unique_ptr.md)を始め、互換インタフェースをもつ任意のスマートポインタ型`Smart`を取り扱える。
18+
19+
説明用の`P`型を次のように定義する :
20+
21+
- [`is_void_v`](/reference/type_traits/is_void.md)`<Pointer>`が`false`ならば`Pointer`
22+
- そうでなければ、`Smart::pointer`が有効な型名であれば`Smart::pointer`
23+
- そうでなければ、`Smart::element_type*`が有効な型名であれば`Smart::element_type*`
24+
- そうでなければ、[`pointer_traits`](pointer_traits.md)`<Smart>::element_type*`
25+
26+
27+
## 戻り値
28+
[`inout_ptr_t`](inout_ptr_t.md)`<Smart, P, Args&&...>(s,` [`std::forward<Args>`](/reference/utility/forward.md)`(args)...)`
29+
30+
31+
## 備考
32+
スマートポインタアダプタ`inout_ptr`は、リソース共有管理セマンティクスを提供する[`std::shared_ptr`](shared_ptr.md)をサポートしない。
33+
これは、共有管理されている既存リソースの所有権を放棄させるインタフェース(`release`)を提供しないためである。
34+
35+
36+
## 例
37+
### P1132R8引用
38+
```cpp example
39+
// Legacy C APIs
40+
error_num c_api_re_create_handle(int seed_value, int** p_handle);
41+
void c_api_delete_handle(int* handle);
42+
43+
// C++ program
44+
#include <memory>
45+
46+
struct resource_deleter {
47+
void operator()(int* handle) {
48+
c_api_delete_handle(handle);
49+
}
50+
};
51+
52+
int main() {
53+
std::unique_ptr<int, resource_deleter> resource(nullptr);
54+
error_num err = c_api_re_create_handle(
55+
24, std::inout_ptr(resource)
56+
);
57+
if (err == C_API_ERROR_CONDITION) {
58+
// handle errors
59+
}
60+
// resource.get() the out-value from the C API function
61+
}
62+
```
63+
* std::inout_ptr[color ff0000]
64+
65+
66+
## バージョン
67+
### 言語
68+
- C++23
69+
70+
### 処理系
71+
- [Clang](/implementation.md#clang): ??
72+
- [GCC](/implementation.md#gcc): ??
73+
- [ICC](/implementation.md#icc): ??
74+
- [Visual C++](/implementation.md#visual_cpp): ??
75+
76+
77+
## 関連項目
78+
- [`inout_ptr_t`](inout_ptr_t.md)
79+
- [`unique_ptr`](unique_ptr.md)
80+
81+
82+
## 参照
83+
- [P1132R8 out_ptr - a scalable output pointer abstraction](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1132r8.html)

reference/memory/inout_ptr_t.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# inout_ptr_t
2+
* memory[meta header]
3+
* class template[meta id-type]
4+
* std[meta namespace]
5+
* cpp23[meta cpp]
6+
7+
```cpp
8+
namespace std {
9+
template<class Smart, class Pointer, class... Args>
10+
class inout_ptr_t;
11+
}
12+
```
13+
14+
## 概要
15+
2重ポインタ`T**`(=`Pointer*`)引数経由で既存リソースを解放してから新規確保リソースへのポインタを返すレガシーC関数に対して、取得されたポインタ値をスマートポインタに格納するアダプタクラス。
16+
アダプタオブジェクトの生成には、[`std::inout_ptr()`](inout_ptr.md)ヘルパ関数を利用する。
17+
18+
C++標準スマートポインタ[`std::unique_ptr`](unique_ptr.md)を始め、互換インタフェースをもつ任意のスマートポインタ型`Smart`を取り扱える。
19+
20+
21+
## テンプレートパラメータ制約
22+
`Pointer`はCpp17NullablePointer要件を満たすこと
23+
24+
25+
## 適格要件
26+
`Smart`が[`shared_ptr`](shared_ptr.md)の特殊化の場合、プログラムは不適格となる。
27+
28+
29+
## メンバ関数
30+
31+
| 名前 | 説明 | 対応バージョン |
32+
|-----------------|----------------|----------------|
33+
| [`(constructor)`](inout_ptr_t/op_constructor.md) | コンストラクタ | C++23 |
34+
| [`(destructor)`](inout_ptr_t/op_destructor.md) | デストラクタ | C++23 |
35+
| [`operator Pointer*()`](inout_ptr_t/op_pointer.md) | `Pointer*`への暗黙変換 | C++23 |
36+
| [`operator void**()`](inout_ptr_t/op_voidpp.md) | `void**`への暗黙変換 | C++23 |
37+
38+
39+
## バージョン
40+
### 言語
41+
- C++23
42+
43+
### 処理系
44+
- [Clang](/implementation.md#clang): ??
45+
- [GCC](/implementation.md#gcc): ??
46+
- [ICC](/implementation.md#icc): ??
47+
- [Visual C++](/implementation.md#visual_cpp): ??
48+
49+
50+
## 関連項目
51+
- [`inout_ptr()`](inout_ptr.md)
52+
- [`unique_ptr`](unique_ptr.md)
53+
54+
55+
## 参照
56+
- [P1132R8 out_ptr - a scalable output pointer abstraction](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1132r8.html)
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# コンストラクタ
2+
* memory[meta header]
3+
* std[meta namespace]
4+
* inout_ptr_t[meta class]
5+
* function[meta id-type]
6+
* cpp23[meta cpp]
7+
8+
```cpp
9+
explicit inout_ptr_t(Smart& smart, Args... args); // (1)
10+
inout_ptr_t(const inout_ptr_t&) = delete; // (2)
11+
```
12+
13+
## 概要
14+
- (1) : `inout_ptr_t`オブジェクトの構築。
15+
- (2) : コピーコンストラクタ。コピー不可。
16+
17+
18+
## 効果
19+
(1) : `inout_ptr_t`クラスの説明用メンバ変数`s`, `a`, `p`を下記の通り初期化する。
20+
21+
- `Smart&`型メンバ変数`s` : `smart`
22+
- `tuple<Args...>`型メンバ変数`a` : [`std::forward`](/reference/utility/forward.md)`<Args>(args)...`
23+
- `Pointer`型メンバ`p` :
24+
- [`is_pointer_v`](/reference/type_traits/is_pointer.md)`<Smart>`が`true`ならば、`smart`
25+
- そうでなければ、`smart.get()`
26+
27+
28+
## 備考
29+
実装によっては`s.release()`を呼び出すかもしれない。
30+
コンストラクタで`release`メンバ関数を呼び出さない場合は、[デストラクタ](op_destructor.md)にて呼び出される。
31+
32+
33+
## バージョン
34+
### 言語
35+
- C++23
36+
37+
### 処理系
38+
- [Clang](/implementation.md#clang): ??
39+
- [GCC](/implementation.md#gcc): ??
40+
- [ICC](/implementation.md#icc): ??
41+
- [Visual C++](/implementation.md#visual_cpp): ??
42+
43+
44+
## 関連項目
45+
- [`inout_ptr()`](../inout_ptr.md)
46+
- [`(destructor)`](op_destructor.md)
47+
- [`operator Pointer*`](op_pointer.md)
48+
- [`operator void**`](op_voidpp.md)
49+
50+
51+
## 参照
52+
- [P1132R8 out_ptr - a scalable output pointer abstraction](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1132r8.html)
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# デストラクタ
2+
* memory[meta header]
3+
* std[meta namespace]
4+
* inout_ptr_t[meta class]
5+
* function[meta id-type]
6+
* cpp23[meta cpp]
7+
8+
```cpp
9+
~inout_ptr_t();
10+
```
11+
12+
## 概要
13+
指定した`Smart`型スマートポインタが管理するリソースを解放し、レガシーC関数呼び出しにより取得されたポインタ値を格納する。
14+
15+
スマートポインタのリソース解放には、`Smart::release()`メンバ関数が利用される。
16+
スマートポインタへのポインタ値格納には、`Smart::reset()`メンバ関数、もしくは`Smart`オブジェクト構築+ムーブ代入`operator=`が利用される。
17+
18+
19+
## 効果
20+
説明用の`SP`型を下記の通り定義する :
21+
22+
- `Smart::pointer`が有効な型名であれば`Smart::pointer`
23+
- そうでなければ、`Smart::element_type*`が有効な型名であれば`Smart::element_type*`
24+
- そうでなければ、[`pointer_traits`](../pointer_traits.md)`<Smart>::element_type*`
25+
- そうでなければ、`Pointer`
26+
27+
説明用の文`release-statement`を下記の通り定義する :
28+
29+
- [コンストラクタ](op_constructor.md)`s.release()`を呼び出さない実装であれば、`s.release()`
30+
- そうでなければ、空文
31+
32+
[説明用メンバ変数](op_constructor.md)`s`, `a`, `p`を用いて、以下と同じ効果を持つ :
33+
34+
- [`is_pointer_v`](/reference/type_traits/is_pointer.md)`<Smart>``true`ならば、
35+
36+
```cpp
37+
if (p) {
38+
apply([&](auto&&... args) {
39+
s = Smart(static_cast<SP>(p), std::forward<Args>(args)...); }, std::move(a));
40+
}
41+
```
42+
43+
-`s.reset(static_cast<SP>(p),` [`std::forward`](/reference/utility/forward.md)`<Args>(args)...)` が適格ならば、
44+
45+
```cpp
46+
if (p) {
47+
apply([&](auto&&... args) {
48+
release-statement;
49+
s.reset(static_cast<SP>(p), std::forward<Args>(args)...); }, std::move(a));
50+
}
51+
```
52+
* apply[link /reference/tuple/apply.md]
53+
54+
- [`is_constructible_v`](/reference/type_traits/is_constructible.md)`<Smart, SP, Args...>``true`ならば、
55+
56+
```cpp
57+
if (p) {
58+
apply([&](auto&&... args) {
59+
release-statement;
60+
s = Smart(static_cast<SP>(p), std::forward<Args>(args)...); }, std::move(a));
61+
}
62+
```
63+
* apply[link /reference/tuple/apply.md]
64+
65+
- そうでなければ、プログラムは不適格となる。
66+
67+
68+
## バージョン
69+
### 言語
70+
- C++23
71+
72+
### 処理系
73+
- [Clang](/implementation.md#clang): ??
74+
- [GCC](/implementation.md#gcc): ??
75+
- [ICC](/implementation.md#icc): ??
76+
- [Visual C++](/implementation.md#visual_cpp): ??
77+
78+
79+
## 関連項目
80+
- [`inout_ptr_t()`](../inout_ptr_t.md)
81+
- [`(constructor)`](op_constructor.md)
82+
- [`operator Pointer*`](op_pointer.md)
83+
- [`operator void**`](op_voidpp.md)
84+
85+
86+
## 参照
87+
- [P1132R8 out_ptr - a scalable output pointer abstraction](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1132r8.html)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# operator Pointer*
2+
* memory[meta header]
3+
* std[meta namespace]
4+
* inout_ptr_t[meta class]
5+
* function[meta id-type]
6+
* cpp23[meta cpp]
7+
8+
```cpp
9+
operator Pointer*() const noexcept;
10+
```
11+
12+
## 概要
13+
`Pointer`型の[説明用メンバ変数](op_constructor.md)へのポインタを取得する。
14+
15+
16+
## 事前条件
17+
`*this`[`operator void**()`](op_voidpp.md)が呼び出されていないこと
18+
19+
20+
## 戻り値
21+
[`addressof`](../addressof.md)`(const_cast<Pointer&>(p))`
22+
23+
24+
## 例外
25+
投げない
26+
27+
28+
## バージョン
29+
### 言語
30+
- C++23
31+
32+
### 処理系
33+
- [Clang](/implementation.md#clang): ??
34+
- [GCC](/implementation.md#gcc): ??
35+
- [ICC](/implementation.md#icc): ??
36+
- [Visual C++](/implementation.md#visual_cpp): ??
37+
38+
39+
## 関連項目
40+
- [`inout_ptr()`](../inout_ptr.md)
41+
42+
43+
## 参照
44+
- [P1132R8 out_ptr - a scalable output pointer abstraction](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1132r8.html)

0 commit comments

Comments
 (0)