Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
985 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,243 @@ | ||
# copyable_function | ||
* functional[meta header] | ||
* class template[meta id-type] | ||
* std[meta namespace] | ||
* cpp26[meta cpp] | ||
|
||
```cpp | ||
namespace std { | ||
template<class... S> | ||
class copyable_function; // 宣言のみ | ||
|
||
template<class R, class... ArgTypes> | ||
class copyable_function<R(ArgTypes...) /*cv*/ /*ref*/ noexcept(/*noex*/)>; | ||
} | ||
``` | ||
## 概要 | ||
`copyable_function`クラステンプレートは、パラメータの型リスト`ArgTypes...`、戻り値の型`R`に合致する、あらゆる関数ポインタ、関数オブジェクト、メンバ関数ポインタ、メンバ変数ポインタを保持できるクラスである。 | ||
下記全ての組み合わせ(12種類)に対して、クラステンプレートの部分特殊化が提供される。 | ||
- CV修飾子 *cv* : `const`, CV修飾無し | ||
- 参照修飾子 *ref* : `&`, `&&`, 参照修飾無し | ||
- noexcept例外指定 *noex* : `true`, `false` | ||
### `function`との比較 | ||
[`std::function`](function.md)と比べて、`std::copyable_function`は下記の特徴をもつ。 | ||
- 関数型のCV修飾/参照修飾/noexcept例外指定をサポートする。 | ||
- const性などを正しく伝搬することでバグ発生リスクを軽減する | ||
- [`target_type`](function/target_type.md)型と[`target()`](function/target.md)を提供しない。 | ||
- 実行時型情報(RTTI)非依存 | ||
- [関数呼び出し](copyable_function/op_call.md)は強い事前条件を持つ。 | ||
- 関数呼び出し時のnullチェックが要求されない | ||
- クラステンプレート引数の[推論補助](/lang/cpp17/type_deduction_for_class_templates.md)を提供しない。 | ||
## メンバ関数 | ||
### 構築・破棄 | ||
| 名前 | 説明 | 対応バージョン | | ||
|-----------------|----------------|----------------| | ||
| [`(constructor)`](copyable_function/op_constructor.md) | コンストラクタ | C++26 | | ||
| [`(destructor)`](copyable_function/op_destructor.md) | デストラクタ | C++26 | | ||
| [`operator=`](copyable_function/op_assign.md) | 代入演算子 | C++26 | | ||
| [`swap`](copyable_function/swap.md) | 他の`copyable_function`オブジェクトと中身を入れ替える | C++26 | | ||
| [`operator bool`](copyable_function/op_bool.md) | 関数呼び出しが可能か調べる | C++26 | | ||
| [`operator()`](copyable_function/op_call.md) | 関数呼び出し | C++26 | | ||
## メンバ型 | ||
| 名前 | 説明 | 対応バージョン | | ||
|-----------------|----------------|----------------| | ||
| `result_type` | 関数の戻り値の型(テンプレートパラメータ`R`) | C++26 | | ||
## 非メンバ関数 | ||
| 名前 | 説明 | 対応バージョン | | ||
|-----------------|----------------|----------------| | ||
| [`operator==`](copyable_function/op_equal.md) | 等値比較 | C++26 | | ||
| [`operator!=`](copyable_function/op_not_equal.md) | 非等値比較 | C++26 | | ||
| [`swap`](copyable_function/swap_free.md) | 2つの`copyable_function`オブジェクトを入れ替える | C++26 | | ||
## 例 | ||
### 例1: 基本の使い方 | ||
```cpp example | ||
#include <functional> | ||
#include <iostream> | ||
int add(int x) { return x + 1; } | ||
int main() | ||
{ | ||
// 関数を代入 | ||
std::copyable_function<int(int)> f = add; | ||
// 関数オブジェクトを代入 | ||
f = [](int x) { return x + 1; }; | ||
// 保持している関数を呼び出す | ||
int result = f(1); | ||
std::cout << result << std::endl; | ||
} | ||
``` | ||
* std::copyable_function[color ff0000] | ||
* f(1)[link copyable_function/op_call.md] | ||
|
||
#### 出力 | ||
``` | ||
2 | ||
``` | ||
|
||
### 例2: const性の伝搬 | ||
```cpp | ||
#include <functional> | ||
#include <iostream> | ||
#include <string> | ||
#include <utility> | ||
|
||
struct Functor { | ||
std::string operator()() { | ||
return "non-const"; | ||
} | ||
std::string operator()() const { | ||
return "const"; | ||
} | ||
}; | ||
|
||
int main() | ||
{ | ||
std::cout << "-- copyable_function" << std::endl; | ||
std::copyable_function<std::string(void)> mof1 = Functor{}; | ||
const std::copyable_function<std::string(void)> mof2 = Functor{}; // (呼び出し時に不適格) | ||
std::copyable_function<std::string(void) const> mof3 = Functor{}; | ||
const std::copyable_function<std::string(void) const> mof4 = Functor{}; | ||
std::cout << "mof1: " << mof1() << std::endl; | ||
//std::cout << "mof2: " << mof2() << std::endl; // 不適格 | ||
std::cout << "mof3: " << mof3() << std::endl; | ||
std::cout << "mof4: " << mof4() << std::endl; | ||
|
||
std::cout << "-- function" << std::endl; | ||
std::function<std::string(void)> fn1 = Functor{}; | ||
const std::function<std::string(void)> fn2 = Functor{}; | ||
// std::function<std::string(void) const> fn3 = Functor{}; // 不適格 | ||
//const std::function<std::string(void) const> fn4 = Functor{}; // 不適格 | ||
std::cout << "fn1: " << fn1() << std::endl; | ||
std::cout << "fn2: " << fn2() << std::endl; | ||
} | ||
``` | ||
* std::copyable_function[color ff0000] | ||
* std::function[link function.md] | ||
#### 出力 | ||
``` | ||
-- copyable_function | ||
mof1: non-const | ||
mof3: const | ||
mof4: const | ||
-- function | ||
fn1: non-const | ||
fn2: non-const | ||
``` | ||
### 例3: 左辺値/右辺値の伝搬 | ||
```cpp example | ||
#include <functional> | ||
#include <iostream> | ||
#include <string> | ||
#include <utility> | ||
struct Functor { | ||
std::string operator()() & { | ||
return "L-val"; | ||
} | ||
std::string operator()() && { | ||
return "R-val"; | ||
} | ||
}; | ||
int main() | ||
{ | ||
std::cout << "-- copyable_function" << std::endl; | ||
std::copyable_function<std::string(void)> mof1 = Functor{}; | ||
std::copyable_function<std::string(void) &&> mof2 = Functor{}; | ||
std::cout << "mof1/L-val: " << mof1() << std::endl; | ||
std::cout << "mof1/R-val: " << std::move(mof1)() << std::endl; | ||
//std::cout << "mof2/L-val: " << mof2() << std::endl; // 不適格 | ||
std::cout << "mof2/R-val: " << std::move(mof2)() << std::endl; | ||
std::cout << "-- function" << std::endl; | ||
std::function<std::string(void)> fn1 = Functor{}; | ||
//std::function<std::string(void) &&> fn2 = Functor{}; // 不適格 | ||
std::cout << "fn1/L-val: " << fn1() << std::endl; | ||
std::cout << "fn1/R-val: " << std::move(fn1)() << std::endl; | ||
} | ||
``` | ||
* std::copyable_function[color ff0000] | ||
* std::function[link function.md] | ||
|
||
#### 出力 | ||
``` | ||
-- copyable_function | ||
mof1/L-val: L-val | ||
mof1/R-val: L-val | ||
mof2/R-val: R-val | ||
-- function | ||
fn1/L-val: L-val | ||
fn1/R-val: L-val | ||
``` | ||
|
||
### 例4: noexcept指定の伝搬 | ||
```cpp example | ||
#include <functional> | ||
|
||
void func() {} | ||
void func_noex() noexcept {} | ||
|
||
int main() | ||
{ | ||
std::copyable_function<void(void)> mof1 = func; | ||
std::copyable_function<void(void)> mof2 = func_noex; | ||
//std::copyable_function<void(void) noexcept> mof3 = func; // 不適格 | ||
std::copyable_function<void(void) noexcept> mof4 = func_noex; | ||
static_assert(not noexcept(mof1())); | ||
static_assert(not noexcept(mof2())); | ||
static_assert( noexcept(mof4())); | ||
|
||
std::function<void(void)> fn1 = func; | ||
std::function<void(void)> fn2 = func_noex; | ||
//std::function<void(void) noexcept> fn3 = func; // 不適格 | ||
//std::function<void(void) noexcept> fn4 = func_noex; // 不適格 | ||
static_assert(not noexcept(fn1())); | ||
static_assert(not noexcept(fn2())); | ||
} | ||
``` | ||
* std::copyable_function[color ff0000] | ||
* std::function[link function.md] | ||
|
||
#### 出力 | ||
``` | ||
``` | ||
|
||
|
||
## バージョン | ||
### 言語 | ||
- C++26 | ||
|
||
### 処理系 | ||
- [Clang](/implementation.md#clang): ?? | ||
- [GCC](/implementation.md#gcc): ?? | ||
- [ICC](/implementation.md#icc): ?? | ||
- [Visual C++](/implementation.md#visual_cpp): ?? | ||
|
||
|
||
## 関連項目 | ||
- [`function`](function.md) | ||
- [`move_only_function`](move_only_function.md) | ||
|
||
|
||
## 参照 | ||
- [P2548R6 copyable_function](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2548r6.pdf) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# operator= | ||
* functional[meta header] | ||
* std[meta namespace] | ||
* copyable_function[meta class] | ||
* function[meta id-type] | ||
* cpp26[meta cpp] | ||
|
||
```cpp | ||
copyable_function& operator=(const copyable_function& f); // (1) | ||
|
||
copyable_function& operator=(copyable_function&& f); // (2) | ||
|
||
copyable_function& operator=(nullptr_t); noexcept; // (3) | ||
|
||
template<class F> | ||
copyable_function& operator=(F&& f); // (4) | ||
``` | ||
|
||
## 効果 | ||
|
||
- (1) : コピー代入。[`copyable_function`](op_constructor.md)`(f).`[`swap`](swap.md)`(*this)` | ||
- (2) : ムーブ代入。[`copyable_function`](op_constructor.md)`(`[`std::move`](/reference/utility/move.md)`(f)).`[`swap`](swap.md)`(*this)` | ||
- (3) : `*this`が有効な関数ポインタ、メンバポインタ、もしくは関数オブジェクトを持っている場合、それを解放する。 | ||
- (4) : [`copyable_function`](op_constructor.md)`(`[`std::forward`](/reference/utility/forward.md)`<F>(f)).`[`swap`](swap.md)`(*this)` | ||
|
||
|
||
## 戻り値 | ||
`*this` | ||
|
||
|
||
## 例外 | ||
- (3) : 投げない | ||
|
||
|
||
## 例 | ||
```cpp example | ||
#include <iostream> | ||
#include <functional> | ||
|
||
int ident(int x) { return x; } | ||
|
||
int main() | ||
{ | ||
std::copyable_function<int(int)> f; | ||
|
||
// 関数を代入 | ||
f = ident; | ||
|
||
int result = f(1); | ||
std::cout << result << std::endl; | ||
} | ||
``` | ||
* f(1)[link op_call.md] | ||
### 出力 | ||
``` | ||
1 | ||
``` | ||
## バージョン | ||
### 言語 | ||
- C++26 | ||
### 処理系 | ||
- [Clang](/implementation.md#clang): ?? | ||
- [GCC](/implementation.md#gcc): ?? | ||
- [ICC](/implementation.md#icc): ?? | ||
- [Visual C++](/implementation.md#visual_cpp): ?? | ||
## 参照 | ||
- [P2548R6 copyable_function](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2548r6.pdf) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# operator bool | ||
* functional[meta header] | ||
* std[meta namespace] | ||
* copyable_function[meta class] | ||
* function[meta id-type] | ||
* cpp26[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::copyable_function<int(int)> f = ident; | ||
|
||
if (f) { | ||
std::cout << "not empty" << std::endl; | ||
} | ||
else { | ||
std::cout << "empty" << std::endl; | ||
} | ||
} | ||
``` | ||
### 出力 | ||
``` | ||
not empty | ||
``` | ||
## バージョン | ||
### 言語 | ||
- C++26 | ||
### 処理系 | ||
- [Clang](/implementation.md#clang): ?? | ||
- [GCC](/implementation.md#gcc): ?? | ||
- [ICC](/implementation.md#icc): ?? | ||
- [Visual C++](/implementation.md#visual_cpp): ?? | ||
## 参照 | ||
- [P2548R6 copyable_function](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2548r6.pdf) |
Oops, something went wrong.