Skip to content

Commit

Permalink
basic_const_iterator : == <=>追加 #1084
Browse files Browse the repository at this point in the history
  • Loading branch information
onihusube committed Aug 4, 2023
1 parent b2a86cc commit 09c1ad7
Show file tree
Hide file tree
Showing 3 changed files with 210 additions and 3 deletions.
6 changes: 3 additions & 3 deletions reference/iterator/basic_const_iterator.md
Expand Up @@ -30,13 +30,13 @@ namespace std {
| [`operator-=`](basic_const_iterator/op_minus_assign.md) | イテレータ自身を逆に進める | C++23 |
| [`operator-`](basic_const_iterator/op_minus.md) | 2つの`basic_const_iterator`の差を求める | C++23 |
| [`operator[]`](basic_const_iterator/op_at.md) | 任意の位置にランダムアクセスする | C++23 |
| [`operator==`](basic_const_iterator/op_equal.md.nolink) | 等値比較 | C++23 |
| [`operator!=`](basic_const_iterator/op_equal.md.nolink) | 非等値比較 | C++23 |
| [`operator==`](basic_const_iterator/op_equal.md) | 等値比較 | C++23 |
| `operator!=` | 非等値比較 ([`==`](basic_const_iterator/op_equal.md)により使用可能) | C++23 |
| [`operator<`](basic_const_iterator/op_less.md.nolink) | 左辺が右辺より小さいかの判定を行う | C++23 |
| [`operator<=`](basic_const_iterator/op_less_equal.md.nolink) | 左辺が右辺以下かの判定を行う | C++23 |
| [`operator>`](basic_const_iterator/op_greater.md.nolink) | 左辺が右辺より大きいかの判定を行う | C++23 |
| [`operator>=`](basic_const_iterator/op_greater_equal.md.nolink) | 左辺が右辺以上かの判定を行う | C++23 |
| [`operator<=>`](basic_const_iterator/op_compare_3way.md.nolink) | 三方比較を行う | C++23 |
| [`operator<=>`](basic_const_iterator/op_compare_3way.md) | 三方比較を行う | C++23 |
## メンバ型
Expand Down
103 changes: 103 additions & 0 deletions reference/iterator/basic_const_iterator/op_compare_3way.md
@@ -0,0 +1,103 @@
# operator<=>
* iterator[meta header]
* std[meta namespace]
* basic_const_iterator[meta class]
* function[meta id-type]
* cpp23[meta cpp]

```cpp
constexpr auto operator<=>(const basic_const_iterator& y) const
requires random_access_iterator<Iterator> && three_way_comparable<Iterator>; // (1)

template<different-from<basic_const_iterator> I>
constexpr auto operator<=>(const I& y) const
requires random_access_iterator<Iterator> && totally_ordered_with<Iterator, I> &&
three_way_comparable_with<Iterator, I>; // (2)
```
* different-from[link /reference/ranges/different-from.md]
* random_access_iterator[link /reference/iterator/random_access_iterator.md]
* three_way_comparable[link /reference/compare/three_way_comparable.md]
* totally_ordered_with[link /reference/concepts/totally_ordered_with.md]

## 概要


`basic_const_iterator<Iterator>`オブジェクトと別のイテレータ(`basic_const_iterator<Iterator>``Iterator``Iterator`と比較可能なオブジェクト)の三方比較を行う。

- (1) : `basic_const_iterator`同士の比較を行う
- (2) : ラップしているイテレータ(`Iterator`)と直接比較可能な型との間で比較を行う

## 効果

ラップするイテレータを`current_`というメンバに保持するとして

- (1) : 以下と等価
```cpp
return current_ <=> y.current_;
```

- (2) : 以下と等価
```cpp
return current_ <=> y;
```

## 備考

(2)の演算子により以下の演算子が使用可能になる(制約は同じものが適用される)。

```cpp
// 逆順
template<different-from<basic_const_iterator> I>
friend constexpr auto operator<=>(const I&, const basic_const_iterator&);
```

##
```cpp example
#include <iostream>
#include <iterator>
#include <vector>
#include <compare>

int main() {
std::vector vec = {1, 2, 3, 4, 5};

std::basic_const_iterator cit = vec.begin();
auto se = vec.end();
std::basic_const_iterator cse = se;


std::cout << std::boolalpha;

// (1) basic_const_iterator同士の比較
std::cout << std::is_lt(cit <=> cse) << '\n';
std::cout << std::is_lt(cse <=> cit) << '\n';

// (2) 元のイテレータとの比較
std::cout << std::is_lt(cit <=> se) << '\n';
std::cout << std::is_lt(se <=> cit) << '\n';
}
```
* <=>[color ff0000]
* is_lt[link /reference/compare/named_comparison_functions.md]

### 出力

```
true
false
true
false
```

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

### 処理系
- [Clang](/implementation.md#clang): ??
- [GCC](/implementation.md#gcc): 13.1
- [Visual C++](/implementation.md#visual_cpp): 2022 Update 6

## 参照

- [P2278R4 `cbegin` should always return a constant iterator](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2278r4.html)
104 changes: 104 additions & 0 deletions reference/iterator/basic_const_iterator/op_equal.md
@@ -0,0 +1,104 @@
# operator==
* iterator[meta header]
* std[meta namespace]
* basic_const_iterator[meta class]
* function[meta id-type]
* cpp23[meta cpp]

```cpp
template<sentinel_for<Iterator> S>
constexpr bool operator==(const S& s) const;
```
* sentinel_for[link /reference/iterator/sentinel_for.md]

## 概要

`basic_const_iterator<Iterator>`オブジェクトと別のイテレータ(`basic_const_iterator<Iterator>``Iterator`のオブジェクト)が同じ要素を指しているかを判定する。

## 効果

ラップしているイテレータを`current_`メンバ変数に保持するとして、以下と等価

```cpp
return current_ == s;
```

## 戻り値

2つのイテレータが同じ要素を指している場合に`true`を返す。


## 備考

この演算子により以下の演算子が使用可能になる。

```cpp
// !=
template<sentinel_for<Iterator> S>
constexpr bool operator!=(const S&) const;

// 逆順
template<sentinel_for<Iterator> S>
friend constexpr bool operator==(const S&, const basic_const_iterator<Iterator>&);

template<sentinel_for<Iterator> S>
friend constexpr bool operator!=(const S&, const basic_const_iterator<Iterator>&);
```

##
```cpp example
#include <iostream>
#include <iterator>
#include <vector>

int main() {
std::vector vec = {1, 2, 3, 4, 5};

std::basic_const_iterator cit = vec.begin();
auto se = vec.end();

std::cout << std::boolalpha;

// 元のイテレータとの比較
std::cout << (cit == se) << '\n';
std::cout << (se == cit) << '\n';

std::basic_const_iterator cse = se;

// basic_const_iterator同士の比較
std::cout << (cit == cse) << '\n';
std::cout << (cse == cit) << '\n';

// !=の導出
std::cout << (cit != se) << '\n';
std::cout << (se != cit) << '\n';
std::cout << (cit != cse) << '\n';
std::cout << (cse != cit) << '\n';
}
```
* ==[color ff0000]

### 出力
```
false
false
false
false
true
true
true
true
```

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

### 処理系
- [Clang](/implementation.md#clang): ??
- [GCC](/implementation.md#gcc): 13.1
- [Visual C++](/implementation.md#visual_cpp): 2022 Update 6

## 参照

- [P2278R4 `cbegin` should always return a constant iterator](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2278r4.html)

0 comments on commit 09c1ad7

Please sign in to comment.