Skip to content

Commit

Permalink
C++26対応としてreference_wrapperのoperator==と<=>を追加 cpprefjp#1340
Browse files Browse the repository at this point in the history
  • Loading branch information
faithandbrave committed Sep 17, 2024
1 parent 2d80797 commit 9437e4e
Show file tree
Hide file tree
Showing 4 changed files with 218 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lang/cpp26.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ C++26とは、2026年中に改訂される予定の、C++バージョンの通
- [`std::move_only_function`](/reference/functional/move_only_function.md)のコピー可能版として、[`<functional>`](/reference/functional.md)[`std::copyable_function`](/reference/functional/copyable_function.md)クラスを追加
- [`std::bind_front()`](/reference/functional/bind_front.md)[`std::bind_back()`](/reference/functional/bind_back.md)に、非型テンプレート引数として関数を指定するオーバーロードを追加
- 関連して、非型テンプレート引数の関数オブジェクトを反転させられるよう、[`not_fn()`](/reference/functional/not_fn.md)に非型テンプレート引数版のオーバーロードを追加
- [`std::reference_wrapper`](/reference/functional/reference_wrapper.md)に、比較演算子[`==`](/reference/functional/reference_wrapper/op_equal.md.nolink)[`<=>`](/reference/functional/reference_wrapper/op_compare_3way.md.nolink)を追加
- [`std::reference_wrapper`](/reference/functional/reference_wrapper.md)に、比較演算子[`==`](/reference/functional/reference_wrapper/op_equal.md)[`<=>`](/reference/functional/reference_wrapper/op_compare_3way.md)を追加


### 文字列
Expand Down
14 changes: 14 additions & 0 deletions reference/functional/reference_wrapper.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,26 @@ C++17からは、このクラスは[トリビアルコピー可能](/reference/t
## 非メンバ関数
### ヘルパ関数
| 名前 | 説明 | 対応バージョン |
|------|------|----------------|
| [`ref`](ref.md) | `T&`に対応する`reference_wrapper`オブジェクトの生成 | C++11 |
| [`cref`](cref.md) | `const T&`に対応する`reference_wrapper`オブジェクトの生成 | C++11 |
### 比較演算子
| 名前 | 説明 | 対応バージョン |
|------|------|----------------|
| [`operator==`](reference_wrapper/op_equal.md) | 等値比較 | C++26 |
| `operator!=` | 非等値比較 (`==`により使用可能) | C++26 |
| [`operator<=>`](reference_wrapper/op_compare_3way.md) | 三方比較 | C++26 |
| `operator<` | 左辺が右辺より小さいかを判定する (`<=>`により使用可能) | C++26 |
| `operator<=` | 左辺が右辺以下を判定する (`<=>`により使用可能) | C++26 |
| `operator>` | 左辺が右辺より大きいかを判定する (`<=>`により使用可能) | C++26 |
| `operator>=` | 左辺が右辺以上かを判定する (`<=>`により使用可能) | C++26 |
## 推論補助
| 名前 | 説明 | 対応バージョン |
Expand Down
104 changes: 104 additions & 0 deletions reference/functional/reference_wrapper/op_compare_3way.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# operator<=>
* functional[meta header]
* std[meta namespace]
* reference_wrapper[meta class]
* function template[meta id-type]

```cpp
friend constexpr synth-three-way-result<T>
operator<=>(reference_wrapper x,
reference_wrapper y); // (1) C++26

friend constexpr synth-three-way-result<T>
operator<=>(reference_wrapper x,
const T& y); // (2) C++26

friend constexpr synth-three-way-result<T>
operator<=>(reference_wrapper x,
reference_wrapper<const T> y); // (3) C++26
```

## 概要
三方比較を行う。

- (1) : 同じ要素型の`reference_wrapper`同士を三方比較する
- (2) : `reference_wrapper`と要素型`T`を三方比較する
- (3) : `reference_wrapper<T>``reference_wrapper<const T>`を三方比較する

(2)と(3)はオペランドを左右で逆にしても使用できる。


## テンプレートパラメータ制約
- (3) : [`is_const_v`](/reference/type_traits/is_const.md)`<T>``false`であること


## 戻り値
- (1) :
```cpp
return synth-three-way(x.get(), y.get());
```
* get()[link get.md]

- (2) :
```cpp
return synth-three-way(x.get(), y);
```
* get()[link get.md]

- (3) :
```cpp
return synth-three-way(x.get(), y.get());
```
* get()[link get.md]


## 備考
- この演算子により、以下の演算子が使用可能になる:
- `operator<`
- `operator<=`
- `operator>`
- `operator>=`


## 例
```cpp example
#include <cassert>
#include <compare>
#include <functional>

int main()
{
int x = 3;
int y = 3;
int z = 4;

assert((std::ref(x) <=> std::ref(y)) == 0);
assert(std::ref(x) < std::ref(z));
assert(std::ref(x) <= std::ref(z));
assert(std::ref(z) > std::ref(x));
assert(std::ref(z) >= std::ref(x));

assert((std::ref(x) <=> 3) == 0);
assert((3 <=> std::ref(x)) == 0);

assert((std::ref(x) <=> std::cref(y)) == 0);
assert((std::cref(x) <=> std::ref(y)) == 0);
}
```

### 出力
```
```

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

### 処理系
- [Clang](/implementation.md#clang): 11.0 [mark verified]
- [GCC](/implementation.md#gcc): 10 [mark verified]
- [Visual C++](/implementation.md#visual_cpp): 2019 [mark verified]


## 参照
- [P2944R3 Comparisons for `reference_wrapper`](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2944r3.html)
99 changes: 99 additions & 0 deletions reference/functional/reference_wrapper/op_equal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# operator==
* functional[meta header]
* std[meta namespace]
* reference_wrapper[meta class]
* function template[meta id-type]

```cpp
friend constexpr bool
operator==(reference_wrapper x,
reference_wrapper y); // (1) C++26

friend constexpr bool
operator==(reference_wrapper x,
const T& y); // (2) C++26

friend constexpr bool
operator==(reference_wrapper x,
reference_wrapper<const T> y); // (3) C++26
```

## 概要
等値比較を行う。

- (1) : 同じ要素型の`reference_wrapper`同士を等値比較する
- (2) : `reference_wrapper`と要素型`T`を等値比較する
- (3) : `reference_wrapper<T>``reference_wrapper<const T>`を等値比較する

(2)と(3)はオペランドを左右で逆にしても使用できる。


## テンプレートパラメータ制約
- (1) : 式`x.`[`get()`](get.md) `== y.`[`get()`](get.md)が妥当であり、その戻り値型が`bool`に変換可能であること
- (2) : 式`x.`[`get()`](get.md) `== y`が妥当であり、その戻り値型が`bool`に変換可能であること
- (3) : 式`x.`[`get()`](get.md) `== y.`[`get()`](get.md)が妥当であり、その戻り値型が`bool`に変換可能であること


## 戻り値
- (1) :
```cpp
return x.get() == y.get();
```
* get()[link get.md]

- (2) :
```cpp
return x.get() == y;
```
* get()[link get.md]

- (3) :
```cpp
return x.get() == y.get();
```
* get()[link get.md]


## 備考
- この演算子により、以下の演算子が使用可能になる:
- `operator!=`


## 例
```cpp example
#include <cassert>
#include <functional>

int main()
{
int x = 3;
int y = 3;

assert(std::ref(x) == std::ref(y));

assert(std::ref(x) == 3);
assert(3 == std::ref(x));

assert(std::ref(x) == std::cref(y));
assert(std::cref(x) == std::ref(y));
}
```
* std::ref[link /reference/functional/ref.md]
* std::cref[link /reference/functional/cref.md]

### 出力
```
```

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

### 処理系
- [Clang](/implementation.md#clang): 3.0 [mark verified]
- [GCC](/implementation.md#gcc): 4.4 [mark verified]
- [Visual C++](/implementation.md#visual_cpp): 2019 [mark verified]


## 参照
- [P2944R3 Comparisons for `reference_wrapper`](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2944r3.html)

0 comments on commit 9437e4e

Please sign in to comment.