Skip to content

Latest commit

 

History

History
463 lines (337 loc) · 37.3 KB

ranges.md

File metadata and controls

463 lines (337 loc) · 37.3 KB

ranges

  • ranges[meta header]
  • cpp20[meta cpp]

<ranges> では、イテレータの組ではなく、コンテナや配列、部分的なコンテナなどの範囲(Range)を直接扱うライブラリを提供する。

C++17までは、標準アルゴリズム関数はイテレータの組を扱い、範囲を直接扱ってはいなかった。 このようなライブラリはBoost.Range、range-v3、cpplinqなどで実績があり、C++標準にも取り込まれることになった。

また、従来のイテレータの組は基本的に同じ型であることが期待されていたが、C++20のRangesではendで得られるものは番兵(sentinel)と規定され、イテレータと同じ型でなくてもよくなった。

<ranges>で定義されるコンセプトはイテレータを用いて定義されるものが多い。イテレータや番兵に関するコンセプトなどは引き続き<iterator>で提供される。

また、Range対応版のアルゴリズム関数は引き続き<algorithm>で提供される。

名前空間構造

<ranges>で定義されるものは全てstd::ranges名前空間の下にある。また、各種view型を生成するRangeアダプタ/ファクトリオブジェクトはstd::ranges::views名前空間の下で定義され、std::viewsからもアクセスする事ができる。

名前空間だけを見てみると次のようになっている。

namespace std {
  // 通常のstd名前空間

  namespace ranges {
    // <ranges>のものはここに定義される

    namespace views {
      // Rangeアダプタ/ファクトリオブジェクトが定義される

    }
  }

  // この名前空間エイリアスによって、std::viewsとしてstd::ranges::viewsにアクセスできる
  namespace views = ranges::views;
}

Rangeアクセス

これらの機能は従来<iterator>でフリー関数として提供されていた。 C++20では関数によるカスタマイゼーションポイントの問題点を解消するため、関数オブジェクトとして再実装されている。 互換性を維持するために従来の関数も残っているが、これらのカスタマイゼーションポイントオブジェクトを使用することが推奨される。

名前 説明 対応バージョン
begin Rangeの先頭を指すイテレータを取得する (customization point object) C++20
end Rangeの末尾の次を指すイテレータもしくは番兵を取得する (customization point object) C++20
cbegin Rangeの先頭を指す読み取り専用イテレータを取得する (customization point object) C++20
cend Rangeの末尾の次を指す読み取り専用イテレータもしくは番兵を取得する (customization point object) C++20
rbegin Rangeの末尾を指す逆イテレータを取得する (customization point object) C++20
rend Rangeの先頭の前を指す逆イテレータもしくは番兵を取得する (customization point object) C++20
crbegin Rangeの末尾を指す読み取り専用逆イテレータを取得する (customization point object) C++20
crend Rangeの先頭の前を指す読み取り専用逆イテレータもしくは番兵を取得する (customization point object) C++20
size Rangeの要素数を取得する (customization point object) C++20
ssize Rangeの要素数を、符号付き整数型で取得する (customization point object) C++20
empty Rangeが空かどうかを判定する (customization point object) C++20
data Rangeの要素配列へのポインタを取得する (customization point object) C++20
cdata Rangeの要素配列への読み取り専用ポインタを取得する (customization point object) C++20

Rangeに関連する型へのアクセス

名前 説明 対応バージョン
iterator_t イテレータ型を取得する (alias template) C++20
sentinel_t 番兵型を取得する (alias template) C++20
const_iterator_t 定数イテレータ型を取得する (alias template) C++23
const_sentinel_t 定数番兵型を取得する (alias template) C++23
range_difference_t イテレータの差の型を取得する (alias template) C++20
range_size_t サイズの型を取得する(alias template) C++20
range_value_t 要素の型を取得する (alias template) C++20
range_reference_t 要素の参照型を取得する (alias template) C++20
range_const_reference_t 要素の定数参照型を取得する (alias template) C++23
range_rvalue_reference_t 要素の右辺値参照型を取得する (alias template) C++20

Rangeコンセプト

名前 説明 対応バージョン
range Rangeを定義するコンセプト (concept) C++20
borrowed_range 所有権を持たないRange (concept) C++20
sized_range サイズを償却定数時間で求められるRange (concept) C++20
view ビューであるRange (concept) C++20
output_range イテレータが出力イテレータであるRange (concept) C++20
input_range イテレータが入力イテレータであるRange (concept) C++20
forward_range イテレータが前進イテレータであるRange (concept) C++20
bidirectional_range イテレータが双方向イテレータであるRange (concept) C++20
random_access_range イテレータがランダムアクセスイテレータであるRange (concept) C++20
contiguous_range イテレータが隣接イテレータであるRange (concept) C++20
common_range イテレータと番兵の型が等しいRange (concept) C++20
viewable_range ビューに変換できるRange (concept) C++20
constant_range 要素が定数なRange (concept) C++23

カスタマイゼーションポイント

名前 説明 対応バージョン
enable_borrowed_range Rangeをborrowed_rangeにする (variable template) C++20
enable_view Rangeをviewにする (variable template) C++20
disable_sized_range Rangeをsized_rangeにならないようにする (variable template) C++20

ビューインターフェース

名前 説明 対応バージョン
view_base 基底クラスとすることでviewとなるタグ型 (class) C++20
view_interface ビューの基底クラスとして推奨されるクラス (class template) C++20

部分Range

名前 説明 対応バージョン
subrange_kind 部分Rangeの種類を表す列挙体 (enum class) C++20
subrange イテレータペアをRangeとして扱う型 (class template) C++20

ダングリングイテレータハンドリング

名前 説明 対応バージョン
dangling ダングリングイテレータ、ダングリングRangeを表す型 (class) C++20
borrowed_iterator_t Rangeがborrowed_rangeではないときdanglingとなるイテレータ (alias template) C++20
borrowed_subrange_t Rangeがborrowed_rangeではないときdanglingとなる部分Range (alias template) C++20

Rangeジェネレータ

名前 説明 対応バージョン
elements_of 子Range要素の生成を示すタグ型 (class template) C++23

Rangeファクトリ

Rangeファクトリは、Rangeではないオブジェクトからviewを生成するものである。 その実体は、引数の無いものは変数テンプレート、引数のあるものは関数テンプレートやカスタマイゼーションポイントオブジェクトとなっている。

empty view

名前 説明 対応バージョン
empty_view 空のRange (class template) C++20
views::empty empty_viewを生成する (variable template) C++20

single view

名前 説明 対応バージョン
single_view 指定した値1つからなるRange (class template) C++20
views::single single_viewを生成する (customization point object) C++20

iota view

名前 説明 対応バージョン
iota_view 単調増加列であるRange (class template) C++20
views::iota iota_viewを生成する (customization point object) C++20

repeat view

名前 説明 対応バージョン
repeat_view 指定した値を指定回数繰り返すRange (class template) C++23
views::repeat repeat_viewを生成する (customization point object) C++23

istream view

名前 説明 対応バージョン
basic_istream_view 入力ストリームから値を読むRange (class template) C++20
istream_view 入力ストリームから値を読むRange (alias template) C++20
wistream_view 入力ストリームから値を読むRange (alias template) C++20
views::istream basic_istream_viewを生成する (customization point object) C++20

Rangeアダプタ

Rangeアダプタは、既存のRangeに作用して新たなRangeを生成するものである。

RangeアダプタをRangeに作用させる方法には、一部の例外を除き、関数記法とパイプライン記法の2つがある。

RをRangeアダプタ、rを元になるRangeとする。このとき、以下の2つの式は同じviewを生成する。

R(r)   // 関数記法
r | R  // パイプライン記法

Rangeアダプタを適用した結果はview、すなわちRangeであることから、Rangeアダプタを次々と繋いでいくことができる。

R3(R2(R1(r)))     // 関数記法
r | R1 | R2 | R3  // パイプライン記法

Rangeアダプタの処理は遅延評価され、要素は必要になるまで生成されない。このような仕組みは実際の仕事の多くをイテレータが担うことで実現している。

for (auto&& item : r | R) {
  // ループ一回ごとに、(r | R)の要素を1つ生成する。このとき、rの要素を必要なだけ取得する。
}

Rangeアダプタオブジェクトは次のように定義される。

  • 第1引数にviewable_rangeを受け取ってviewを返すカスタマイゼーションポイントオブジェクト

また、Rangeアダプタクロージャオブジェクトは次のように定義される。

  • (C++20) viewable_rangeを受け取ってviewを返す単項関数オブジェクト
  • (C++23) Rangeを受け取る単項関数オブジェクト

Rangeアダプタオブジェクトadaptorが2つ以上の引数をとる場合、以下の3つの式は等しい。

adaptor(range, args...)
adaptor(args...)(range)
range | adaptor(args...)

このとき、式adaptor(args...)の値がRangeアダプタクロージャオブジェクトになっている。

なお、元となるRangeを複数とるRangeアダプタは、パイプライン記法を提供しない。

名前 説明 対応バージョン
range_adaptor_closure Rangeアダプタクロージャオブジェクトの基底クラス (class template) C++23

all view

名前 説明 対応バージョン
ref_view Rangeへの参照として振る舞うビュー (class template) C++20
owning_view Rangeの右辺値をムーブして所有するビュー (class template) C++20
views::all Rangeへの参照として振る舞うビューを生成する (customization point object) C++20
views::all_t allの戻り値型 (alias template) C++20

as rvalue view

名前 説明 対応バージョン
as_rvalue_view 各要素をrvalueにするビュー (class template) C++23
views::as_rvalue as_rvalue_viewを生成する (customization point object) C++23

filter view

名前 説明 対応バージョン
filter_view 指定した条件を満たす要素だけを集めるビュー (class template) C++20
views::filter filter_viewを生成する (customization point object) C++20

transform view

名前 説明 対応バージョン
transform_view 指定した関数で各要素を変換するビュー (class template) C++20
views::transform transform_viewを生成する (customization point object) C++20

take view

名前 説明 対応バージョン
take_view 先頭から指定した個数だけ取り出すビュー (class template) C++20
views::take 先頭から指定した個数だけ取り出すビューを生成する (customization point object) C++20

take while view

名前 説明 対応バージョン
take_while_view 先頭から指定した条件を満たす範囲を取り出すビュー (class template) C++20
views::take_while take_while_viewを生成する (customization point object) C++20

drop view

名前 説明 対応バージョン
drop_view 先頭から指定した個数だけ除外するビュー (class template) C++20
views::drop 先頭から指定した個数だけ除外するビューを生成する (customization point object) C++20

drop while view

名前 説明 対応バージョン
drop_while_view 先頭から指定した条件を満たす範囲を除外するビュー (class template) C++20
views::drop_while drop_while_viewを生成する (customization point object) C++20

join view

名前 説明 対応バージョン
join_view ネストされたRangeを平坦にするビュー (class template) C++20
views::join ネストされたRangeを平坦にするビューを生成する (customization point object) C++20

join with view

名前 説明 対応バージョン
join_with_view ネストされたRangeをデリミタで区切りながら平坦にするビュー (class template) C++23
views::join_with ネストされたRangeをデリミタで区切りながら平坦にするビューを生成する (customization point object) C++23

lazy split view

名前 説明 対応バージョン
lazy_split_view Rangeを指定したデリミタで分割するビュー (class template) C++20
views::lazy_split lazy_split_viewを生成する (customization point object) C++20

split view

名前 説明 対応バージョン
split_view 文字列分割に特化したlazy_split_view (class template) C++20
views::split split_viewを生成する (customization point object) C++20

concat view

名前 説明 対応バージョン
concat_view 複数のRangeを連結するビュー (class template) C++26
views::concat concat_viewを生成する (customization point object) C++26

counted view

名前 説明 対応バージョン
views::counted イテレータから指定した数の範囲をRangeとして扱うビューを生成する (customization point object) C++20

common view

名前 説明 対応バージョン
common_view common_rangeにしたビュー (class template) C++20
views::common common_rangeなビューを生成する (customization point object) C++20

reverse view

名前 説明 対応バージョン
reverse_view 逆順のビュー (class template) C++20
views::reverse 逆順のビューを生成する (customization point object) C++20

as const view

名前 説明 対応バージョン
as_const_view 各要素をconstにするビュー (class template) C++23
views::as_const as_const_viewを生成する (customization point object) C++23

elements view

名前 説明 対応バージョン
elements_view タプルの第N要素にアクセスするビュー (class template) C++20
keys_view タプルの第0要素にアクセスするビュー (alias template) C++20
values_view タプルの第1要素にアクセスするビュー (alias template) C++20
views::elements elements_viewを生成する (customization point object) C++20
views::keys keys_viewを生成する (customization point object) C++20
views::values values_viewを生成する (customization point object) C++20

enumerate view

名前 説明 対応バージョン
enumerate_view シーケンスにインデックスを付けるview (class template) C++23
views::enumerate enumerate_viewを生成する (customization point object) C++23

zip view

名前 説明 対応バージョン
zip_view 複数のシーケンスから値を1つずつ取り出したtupleのビュー (class template) C++23
views::zip zip_viewを生成する (customization point object) C++23

zip transform view

名前 説明 対応バージョン
zip_transform_view 複数のシーケンスから値を1つずつ取り出し、関数を適用した結果のビュー (class template) C++23
views::zip_transform zip_transform_viewを生成する (customization point object) C++23

adjacent view

名前 説明 対応バージョン
adjacent_view 各要素とそれに隣接する要素を指定個数ずつ取り出したtupleのビュー (class template) C++23
views::adjacent adjacent_viewを生成する (variable template) C++23
views::pairwise adjacent<2>の別名 (customization point object) C++23

adjacent transform view

名前 説明 対応バージョン
adjacent_transform_view adjacent_viewと同様に取り出し、関数を適用した結果のビュー (class template) C++23
views::adjacent_transform adjacent_transform_viewを生成する (customization point object) C++23

chunk view

名前 説明 対応バージョン
chunk_view シーケンスを指定個数で区切ったviewのシーケンス (class template) C++23
views::chunk chunk_viewを生成する (customization point object) C++23

chunk by view

名前 説明 対応バージョン
chunk_by_view 2項述語が偽となる部分で区切ったviewのシーケンス (class template) C++23
views::chunk_by chunk_by_viewを生成する (customization point object) C++23

slide view

名前 説明 対応バージョン
slide_view 各要素とそれに隣接する要素を指定個数ずつ見るviewのシーケンス (class template) C++23
views::slide slide_viewを生成する (customization point object) C++23

stride view

名前 説明 対応バージョン
stride_view 要素を指定個数飛ばしに見るビュー (class template) C++23
views::stride stride_viewを生成する (customization point object) C++23

cartesian product view

名前 説明 対応バージョン
cartesian_product_view シーケンスの直積集合のビュー (class template) C++23
views::cartesian_product cartesian_product_viewを生成する (customization point object) C++23

Range変換

名前 説明 対応バージョン
to パイプライン記法でRangeからコンテナを構築する (class template) C++23
from_range_t Rangeからコンテナへの変換を示すタグ型 (class) C++23
from_range Rangeからコンテナへの変換を示すタグ値 (variable) C++23

実装例

バージョン

言語

  • C++20

処理系

  • Clang: 13.0.0 [mark verified]
  • GCC: 10.1.0 [mark verified]
  • ICC: ?
  • Visual C++: 2019 Update 10 [mark verified]

関連項目

参照