Skip to content

Commit

Permalink
functional: P0288R9 move_only_function追加(#1056)
Browse files Browse the repository at this point in the history
既存std::function<R(Args...)>をベースとして各ページを作成。
  • Loading branch information
yohhoy committed Jan 23, 2023
1 parent a7b1a5e commit 7389f02
Show file tree
Hide file tree
Showing 12 changed files with 794 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lang/cpp23.md
Expand Up @@ -188,7 +188,7 @@ C++23とは、2023年中に改訂される予定の、C++バージョンの通

### 関数オブジェクト
- [`std::invoke()`](/reference/functional/invoke.md)の戻り値型を指定するバージョンである[`std::invoke_r()`](/reference/functional/invoke_r.md)を追加
- ムーブのみ可能な[`std::function`](/reference/functional/function.md)クラスと等価な機能をもつ[`std::move_only_function`](/reference/functional/move_only_function.md.nolink)クラスを追加
- [`std::function`](/reference/functional/function.md)クラスと等価な機能をもつ、ムーブのみ可能な[`std::move_only_function`](/reference/functional/move_only_function.md)クラスを追加
- ユーザー定義のRangeアダプタがパイプライン演算子 `|` をサポートしやすくするために、末尾から引数を束縛する[`std::bind_back()`](/reference/functional/bind_back.md.nolink)関数を追加


Expand Down
5 changes: 5 additions & 0 deletions reference/functional/function.md
Expand Up @@ -113,6 +113,11 @@ int main()
### 言語
- C++11
## 関連項目
- [`move_only_function`](move_only_function.md)
## 参照
- [P0302R1 Removing Allocator Support in `std::function` (rev 1)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0302r1.html)
- [P0005R4 Adopt `not_fn` from Library Fundamentals 2 for C++17](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0005r4.html)
Expand Down
99 changes: 99 additions & 0 deletions reference/functional/move_only_function.md
@@ -0,0 +1,99 @@
# move_only_function
* functional[meta header]
* class template[meta id-type]
* std[meta namespace]
* cpp23[meta cpp]

```cpp
namespace std {
template<class... S> class move_only_function; // 宣言のみ

template<class R, class... ArgTypes>
class move_only_function<R(ArgTypes...) /*cv*/ /*ref*/ noexcept(/*noex*/)>;
}
```
## 概要
`move_only_function`クラステンプレートは、パラメータの型リスト`ArgTypes...`、戻り値の型`R`に合致する、あらゆる関数ポインタ、関数オブジェクト、メンバ関数ポインタ、メンバ変数ポインタを保持できるクラスである。
下記全ての組み合わせ(12種類)についてクラステンプレートの部分特殊化が提供される。
- CV修飾子 *cv* : `const`, CV修飾無し
- 参照修飾子 *ref* : `&`, `&&`, 参照修飾無し
- noexcept例外指定 *noex* : `true`, `false`
## メンバ関数
### 構築・破棄
| 名前 | 説明 | 対応バージョン |
|-----------------|----------------|----------------|
| [`(constructor)`](move_only_function/op_constructor.md) | コンストラクタ | C++23 |
| [`(destructor)`](move_only_function/op_destructor.md) | デストラクタ | C++23 |
| [`operator=`](move_only_function/op_assign.md) | 代入演算子 | C++23 |
| [`swap`](move_only_function/swap.md) | 他の`move_only_function`オブジェクトと中身を入れ替える | C++23 |
| [`operator bool`](move_only_function/op_bool.md) | 関数呼び出しが可能か調べる | C++23 |
| [`operator()`](move_only_function/op_call.md) | 関数呼び出し | C++23 |
## メンバ型
| 名前 | 説明 | 対応バージョン |
|-----------------|----------------|----------------|
| `result_type` | 関数の戻り値の型(テンプレートパラメータ`R`) | C++23 |
## 非メンバ関数
| 名前 | 説明 | 対応バージョン |
|-----------------|----------------|----------------|
| [`operator==`](move_only_function/op_equal.md) | 等値比較 | C++23 |
| [`operator!=`](move_only_function/op_not_equal.md) | 非等値比較 | C++23 |
| [`swap`](move_only_function/swap_free.md) | 2つの`move_only_function`オブジェクトを入れ替える | C++23 |
## 例
```cpp example
#include <iostream>
#include <functional>
int add(int x) { return x + 1; }
int main()
{
// 関数を代入
std::move_only_function<int(int)> f = add;
// 関数オブジェクトを代入
f = [](int x) { return x + 1; };
// 保持している関数を呼び出す
int result = f(1);
std::cout << result << std::endl;
}
```
* std::move_only_function[color ff0000]
* f(1)[link move_only_function/op_call.md]

### 出力
```
1
```


## バージョン
### 言語
- C++23

### 処理系
- [Clang](/implementation.md#clang): ??
- [GCC](/implementation.md#gcc): ??
- [ICC](/implementation.md#icc): ??
- [Visual C++](/implementation.md#visual_cpp): ??


## 関連項目
- [`function`](function.md)


## 参照
- [P0288R9 move_only_function](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0288r9.html)
69 changes: 69 additions & 0 deletions reference/functional/move_only_function/op_assign.md
@@ -0,0 +1,69 @@
# operator=
* functional[meta header]
* std[meta namespace]
* move_only_function[meta class]
* function[meta id-type]
* cpp23[meta cpp]

```cpp
move_only_function& operator=(move_only_function&& f); // (1)

move_only_function& operator=(nullptr_t); noexcept; // (2)

template<class F>
move_only_function& operator=(F&& f); // (3)
```

## 効果
- (1) : ムーブ代入。[`move_only_function`](op_constructor.md)`(`[`std::move`](/reference/utility/move.md)`(f)).`[`swap`](swap.md)`(*this)`
- (2) : `*this`が有効な関数ポインタ、メンバポインタ、もしくは関数オブジェクトを持っている場合、それを解放する。
- (3) : [`move_only_function`](op_constructor.md)`(`[`std::forward`](/reference/utility/forward.md)`<F>(f)).`[`swap`](swap.md)`(*this)`


## 戻り値
`*this`


## 例外
- (2) : 投げない


##
```cpp example
#include <iostream>
#include <functional>

int ident(int x) { return x; }

int main()
{
std::move_only_function<int(int)> f;

// 関数を代入
f = ident;

int result = f(1);
std::cout << result << std::endl;
}
```
* f(1)[link op_call.md]
### 出力
```
1
```
## バージョン
### 言語
- C++23
### 処理系
- [Clang](/implementation.md#clang): ??
- [GCC](/implementation.md#gcc): ??
- [ICC](/implementation.md#icc): ??
- [Visual C++](/implementation.md#visual_cpp): ??
## 参照
- [P0288R9 move_only_function](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0288r9.html)
58 changes: 58 additions & 0 deletions reference/functional/move_only_function/op_bool.md
@@ -0,0 +1,58 @@
# operator bool
* functional[meta header]
* std[meta namespace]
* move_only_function[meta class]
* function[meta id-type]
* cpp23[meta cpp]

```cpp
explicit operator bool() const noexcept;
```

## 概要
関数呼び出しが可能か調べる。


## 戻り値
呼び出す関数を持っていれば`true`、そうでなければ`false`を返す。


##
```cpp example
#include <iostream>
#include <functional>

int ident(int x) { return x; }

int main()
{
std::move_only_function<int(int)> f = ident;

if (f) {
std::cout << "not empty" << std::endl;
}
else {
std::cout << "empty" << std::endl;
}
}
```
### 出力
```
not empty
```
## バージョン
### 言語
- C++23
### 処理系
- [Clang](/implementation.md#clang): ??
- [GCC](/implementation.md#gcc): ??
- [ICC](/implementation.md#icc): ??
- [Visual C++](/implementation.md#visual_cpp): ??
## 参照
- [P0288R9 move_only_function](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0288r9.html)
67 changes: 67 additions & 0 deletions reference/functional/move_only_function/op_call.md
@@ -0,0 +1,67 @@
# operator()
* functional[meta header]
* std[meta namespace]
* move_only_function[meta class]
* function[meta id-type]
* cpp23[meta cpp]

```cpp
R operator()(ArgTypes... args) /*cv*/ /*ref*/ noexcept(/*noex*/);
```
## 概要
関数を呼び出す。
CV修飾子 *cv*, 参照修飾子 *ref*, noexcept例外指定 *noex* は[`move_only_function`](../move_only_function.md)に指定するテンプレートパラメータ`R(ArgTypes...)`部と等しい。
## 事前条件
`*this`は関数ポインタまたは関数オブジェクトを保持していること。
## 効果
`*this`が保持している`F`型の関数ポインタまたは関数オブジェクト`f`に対して、[`INVOKE<R>`](/reference/concepts/Invoke.md)`(static_cast<F inv-quals>(f),` [`std::forward`](/reference/utility/forward.md)`<ArgTypes>(args)...)`を行う。
## 戻り値
`R`型が`void`の場合は何も返さない。そうでなければ、関数呼び出しの戻り値を返す。
## 例
```cpp example
#include <iostream>
#include <functional>
int ident(int x)
{ return x; }
int main()
{
std::move_only_function<int(int)> f = ident;
// 関数呼び出し : 保持しているident()関数を呼び出す
int result = f(1);
std::cout << result << std::endl;
}
```

### 出力
```
1
```


## バージョン
### 言語
- C++23

### 処理系
- [Clang](/implementation.md#clang): ??
- [GCC](/implementation.md#gcc): ??
- [ICC](/implementation.md#icc): ??
- [Visual C++](/implementation.md#visual_cpp): ??


## 参照
- [P0288R9 move_only_function](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0288r9.html)

0 comments on commit 7389f02

Please sign in to comment.