namespace std {
namespace ranges {
inline namespace /*unspecified*/ {
inline constexpr /*unspecified*/ iter_swap = /*unspecified*/;
}
}
}
概要
iter_swap
はイテレータを2つ受け取り、そのイテレータの参照する要素の値を交換(swap
)するカスタマイゼーションポイントオブジェクトである。
効果
まず説明専用の関数テンプレートiter-exchange-move
を次のように定義しておく。
template<class X, class Y>
constexpr iter_value_t<X> iter-exchange-move(X&& x, Y&& y)
noexcept(noexcept(iter_value_t<X>(iter_move(x))) &&
noexcept(*x = iter_move(y)))
{
iter_value_t<X> old_value(iter_move(x));
*x = iter_move(y);
return old_value;
}
iter_swap(a, b)
のように呼び出された時、以下のいずれかと等価
-
引数
a, b
のどちらかの型がクラス型であるか列挙型であり、std::ranges::iter_swap
(本CPO)の宣言を含まず下記のiter_swap
関数宣言を含むコンテキストで、iter_swap(a, b)
が呼び出し可能ならば(void)iter_swap(a, b)
template<class I1, class I2> void iter_swap(I1, I2) = delete;
-
a, b
の型が共にindirectly_readable
のモデルであり、a, b
の参照先の型がswappable_with
のモデルとなるとき、ranges::swap(*a, *b)
-
a, b
の型T1, T2
がindirectly_movable_storable<T1, T2>
とindirectly_movable_storable<T2, T1>
のモデルとなるとき、(void)(*a = iter-exchange-move(b, a))
-
それ以外の場合、呼び出しは不適格。
1のケースの場合に、呼び出されるiter_swap(a, b)
が交換を行わない場合、プログラムは不適格(ただし、コンパイルエラーとならない可能性がある)。
戻り値
なし
例外
上記「効果」節のそれぞれのケース毎に
- 呼び出される
iter_swap()
が例外を投げるかに従う - 引数
a, b
の*
演算子および呼び出されるranges::swap()
が例外を投げるかに従う iter-exchange-move
操作およびその結果の*a
への代入が例外を投げるかに従う
定数式に評価される条件
- 呼び出される
iter_swap()
が定数評価可能かに従う - 引数
a, b
の*
演算子および呼び出されるranges::swap()
が定数評価可能かに従う iter-exchange-move
操作およびその結果の*a
への代入が定数評価可能かに従う
カスタマイゼーションポイント
1のケースでは、ユーザー定義のiter_swap()
を定義しておくことによって実行される交換操作をカスタマイズすることができる。
- 引数
a, b
の型と同じ名前空間で、もしくはHidden friendsとして、非メンバiter_swap()
関数を定義しておく a, b
の参照先の型についてranges::swap
にアダプトしておく- --
例
#include <iterator>
#include <vector>
#include <iostream>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::counted_iterator ci1{std::ranges::begin(vec), 5};
std::counted_iterator ci2{std::ranges::begin(vec) + 5, 5};
// ケース1の呼び出し
std::ranges::iter_swap(ci1, ci2);
std::cout << *ci1 << ", " << *ci2 << std::endl;
int* p1 = vec.data() + 1;
int* p2 = p1 + 5;
// ケース2の呼び出し
std::ranges::iter_swap(p1, p2);
std::cout << *p1 << ", " << *p2 << std::endl;
}
出力
6, 1
7, 2
バージョン
言語
- C++20
処理系
- Clang: ??
- GCC: 10.1 ✅
- Visual C++: 2019 Update 4 ✅