コンテンツにスキップ

C++/標準ライブラリ/レンジライブラリ

出典: フリー教科書『ウィキブックス(Wikibooks)』

C++20で導入されたレンジライブラリは、範囲 (Range) とビュー (View) という概念を導入し、コンテナやその他のデータ列をより直感的かつ効率的に処理するための仕組みを提供します。

従来のイテレータベースのアプローチと比較して、レンジライブラリは以下の利点があります。

簡潔なコード
範囲ベースの for ループなどの構文を用いることで、ループをより簡潔に記述することができます。
汎用性
レンジライブラリはコンテナの種類に依存せず、様々なデータ列に対して利用することができます。
パイプライン処理
レンジアダプタと呼ばれる関数を連結することで、データ列をパイプラインのように処理することができます。
アルゴリズムとの連携
レンジライブラリはアルゴリズムライブラリと密接に連携しており、アルゴリズムをより汎用的に適用することができます。

ヘッダー一覧[編集]

この章で扱うヘッダーファイルは以下の通りです。

範囲アクセス
<ranges>
範囲ジェネレータ
<generator>

範囲アクセス[編集]

26.3 範囲アクセス(range.access)[編集]

26.3.1 一般的な内容(range.access.general)[編集]

このセクションでは、<ranges>ヘッダを含めることで利用できるカスタマイズポイントオブジェクトについて説明します。また、26.3では、サブ式Eの具現化オブジェクトが、Eがglvalueである場合はEと同じオブジェクトを示し、それ以外の場合は一時具現化変換(7.3.5)をEに適用した結果を示します。

26.3.2 ranges::begin(range.access.begin)[編集]

ranges::beginという名前は、カスタマイズポイントオブジェクトを示します。型Tを持つサブ式Eが与えられた場合、Eの具現化オブジェクトを示すlvalueをtとします。そして:

  • Eがrvalueであり、enable_borrowed_range<remove_cv_t<T>>がfalseの場合、ranges::begin(E)は不正です。
  • そうでない場合、
    • Tが配列型でremove_all_extents_t<T>が不完全型である場合、ranges::begin(E)は診断メッセージがない不正形式です。
    • Tが配列型である場合、ranges::begin(E)は式的にt + 0と等価です。
    • auto(t.begin())が有効な式であり、その型がinput_or_output_iteratorをモデル化する場合、ranges::begin(E)は式的にauto(t.begin())と等価です。
    • Tがクラスまたは列挙型であり、auto(begin(t))が有効な式であり、その型がinput_or_output_iteratorをモデル化する場合、ranges::begin(E)はその式と等価です。
    • それ以外の場合、ranges::begin(E)は不正です。
注釈 1
上記の診断可能な不正形式のケースは、ranges::begin(E)がテンプレートインスタンスの直接的な文脈で現れる場合、置換失敗を引き起こします。
注釈 2
ranges::begin(E)が有効な式である場合、その型はinput_or_output_iteratorをモデル化します。

26.3.3 ranges::end(range.access.end)[編集]

ranges::endという名前は、カスタマイズポイントオブジェクトを示します。型Tを持つサブ式Eが与えられた場合、Eの具現化オブジェクトを示すlvalueをtとします。そして:

  • Eがrvalueであり、enable_borrowed_range<remove_cv_t<T>>がfalseの場合、ranges::end(E)は不正です。
  • そうでない場合、
    • Tが配列型でremove_all_extents_t<T>が不完全型である場合、ranges::end(E)は診断メッセージがない不正形式です。
    • Tが不明なサイズの配列型である場合、ranges::end(E)は不正です。
    • Tが配列型である場合、ranges::end(E)は式的にt + extent_v<T>と等価です。
    • auto(t.end())が有効な式であり、その型がsentinel_for<iterator_t<T>>をモデル化する場合、ranges::end(E)は式的にauto(t.end())と等価です。
    • Tがクラスまたは列挙型であり、auto(end(t))が有効な式であり、その型がsentinel_for<iterator_t<T>>をモデル化する場合、ranges::end(E)はその式と等価です。
    • それ以外の場合、ranges::end(E)は不正です。
注釈 1
上記の診断可能な不正形式のケースは、ranges::end(E)がテンプレートインスタンスの直接的な文脈で現れる場合、置換失敗を引き起こします。
注釈 2
ranges::end(E)が有効な式である場合、ranges::begin(E)およびranges::end(E)の型SおよびIはsentinel_for<S, I>をモデル化します。

26.3.4 ranges::cbegin(range.access.cbegin)[編集]

ranges::cbeginという名前は、カスタマイズポイントオブジェクトを示します。型Tを持つサブ式Eが与えられた場合、Eの具現化オブジェクトを示すlvalueをtとします。そして:

  • Eがrvalueであり、enable_borrowed_range<remove_cv_t<T>>がfalseの場合、ranges::cbegin(E)は不正です。
  • そうでない場合、possibly-const-range(t)のranges::beginをUとすると、ranges::cbegin(E)は式的にconst_iterator<decltype(U)>(U)と等価です。
注釈 1
ranges::cbegin(E)が有効な式である場合、その型はinput_or_output_iteratorおよびconstant-iteratorをモデル化します。

26.3.5 ranges::cend(range.access.cend)[編集]

ranges::cendという名前は、カスタマイズポイントオブジェクトを示します。型Tを持つサブ式Eが与えられた場合、Eの具現化オブジェクトを示すlvalueをtとします。そして:

  • Eがrvalueであり、enable_borrowed_range<remove_cv_t<T>>がfalseの場合、ranges::cend(E)は不正です。
  • そうでない場合、possibly-const-range(t)のranges::endをUとすると、ranges::cend(E)は式的にconst_sentinel<decltype(U)>(U)と等価です。
注釈 1
ranges::cend(E)が有効な式である場合、ranges::cend(E)およびranges::cbegin(E)の型SおよびIはsentinel_for<S, I>をモデル化します。Sがinput_iteratorをモデル化する場合、Sはconstant-iteratorもモデル化します。

26.3.6 ranges::rbegin(range.access.rbegin)[編集]

ranges::rbeginはカスタマイズポイントオブジェクトを示します。型Tを持つサブ式Eが与えられた場合、Eの具現化オブジェクトを示すlvalueをtとします。そして:

  • Eがrvalueであり、enable_borrowed_range<remove_cv_t<T>>がfalseの場合、ranges::rbegin(E)は不正です。
  • そうでない場合、
    • Tが配列型でremove_all_extents_t<T>が不完全型である場合、ranges::rbegin(E)は診断メッセージがない不正形式です。
    • auto(t.rbegin())が有効な式であり、その型がinput_or_output_iteratorをモデル化する場合、ranges::rbegin(E)は式的にauto(t.rbegin())と等価です。
    • Tがクラスまたは列挙型であり、auto(rbegin(t))が有効な式であり、その型がinput_or_output_iteratorをモデル化する場合、ranges::rbegin(E)はその式と等価です。
    • ranges::begin(t)とranges::end(t)が同じ型であり、かつそれがbidirectional_iteratorをモデル化する場合、ranges::rbegin(E)は式的にmake_reverse_iterator(ranges::end(t))と等価です。
    • それ以外の場合、ranges::rbegin(E)は不正です。
注釈 1
上記の診断可能な不正形式のケースは、ranges::rbegin(E)がテンプレートインスタンスの直接的な文脈で現れる場合、置換失敗を引き起こします。
注釈 2
ranges::rbegin(E)が有効な式である場合、その型はinput_or_output_iteratorをモデル化します。

26.3.7 ranges::rend(range.access.rend)[編集]

ranges::rendはカスタマイズポイントオブジェクトを示します。型Tを持つサブ式Eが与えられた場合、Eの具現化オブジェクトを示すlvalueをtとします。そして:

  • Eがrvalueであり、enable_borrowed_range<remove_cv_t<T>>がfalseの場合、ranges::rend(E)は不正です。
  • そうでない場合、
    • Tが配列型でremove_all_extents_t<T>が不完全型である場合、ranges::rend(E)は診断メッセージがない不正形式です。
    • auto(t.rend())が有効な式であり、その型がsentinel_for<decltype(ranges::rbegin(E))>をモデル化する場合、ranges::rend(E)は式的にauto(t.rend())と等価です。
    • Tがクラスまたは列挙型であり、auto(rend(t))が有効な式であり、その型がsentinel_for<decltype(ranges::rbegin(E))>をモデル化する場合、ranges::rend(E)はその式と等価です。
    • ranges::begin(t)とranges::end(t)が同じ型であり、かつそれがbidirectional_iteratorをモデル化する場合、ranges::rend(E)は式的にmake_reverse_iterator(ranges::begin(t))と等価です。
    • それ以外の場合、ranges::rend(E)は不正です。
注釈 1
上記の診断可能な不正形式のケースは、ranges::rend(E)がテンプレートインスタンスの直接的な文脈で現れる場合、置換失敗を引き起こします。
注釈 2
ranges::rend(E)が有効な式である場合、ranges::rend(E)およびranges::rbegin(E)の型SおよびIはsentinel_for<S, I>をモデル化します。

26.3.8 ranges::crbegin(range.access.crbegin)[編集]

ranges::crbeginという名前は、カスタマイズポイントオブジェクトを示します。型Tを持つサブ式Eが与えられた場合、Eの具現化オブジェクトを示すlvalueをtとします。そして:

  • Eがrvalueであり、enable_borrowed_range<remove_cv_t<T>>がfalseの場合、ranges::crbegin(E)は不正です。
  • そうでない場合、possibly-const-range(t)のranges::rbeginをUとすると、ranges::crbegin(E)は式的にconst_iterator<decltype(U)>(U)と等価です。
注釈 1
ranges::crbegin(E)が有効な式である場合、その型はinput_or_output_iteratorおよびconstant-iteratorをモデル化します。

26.3.9 ranges::crend(range.access.crend)[編集]

ranges::crendという名前は、カスタマイズポイントオブジェクトを示します。型Tを持つサブ式Eが与えられた場合、Eの具現化オブジェクトを示すlvalueをtとします。そして:

  • Eがrvalueであり、enable_borrowed_range<remove_cv_t<T>>がfalseの場合、ranges::crend(E)は不正です。
  • そうでない場合、possibly-const-range(t)のranges::rendをUとすると、ranges::crend(E)は式的にconst_sentinel<decltype(U)>(U)と等価です。
注釈 1
ranges::crend(E)が有効な式である場合、ranges::crend(E)およびranges::crbegin(E)の型SおよびIはsentinel_for<S, I>をモデル化します。Sがinput_iteratorをモデル化する場合、Sはconstant-iteratorもモデル化します。

26.3.10 ranges::size(range.prim.size)[編集]

ranges::sizeという名前は、カスタマイズポイントオブジェクトを示します。型Tを持つサブ式Eが与えられた場合、Eの具現化オブジェクトを示すlvalueをtとします。そして:

  • Tが不明なサイズの配列型である場合、ranges::size(E)は不正です。
  • そうでない場合、
    • Tが配列型である場合、ranges::size(E)は式的にauto(extent_v<T>)と等価です。
    • disable_sized_range<remove_cv_t<T>>がfalseであり、auto(t.size())が整数のような型で有効な式である場合、ranges::size(E)は式的にauto(t.size())と等価です。
    • Tがクラスまたは列挙型であり、disable_sized_range<remove_cv_t<T>>がfalseであり、auto(size(t))が整数のような型で有効な式である場合、ranges::size(E)はその式と等価です。
    • ranges::begin(t)とranges::end(t)の型IおよびSがともにsized_sentinel_for<S, I>およびforward_iteratorをモデル化する場合、ranges::size(E)は式的にto-unsigned-like(ranges::end(t) - ranges::begin(t))と等価です。
    • それ以外の場合、ranges::size(E)は不正です。
注釈 1
上記の診断可能な不正形式のケースは、ranges::size(E)がテンプレートインスタンスの直接的な文脈で現れる場合、置換失敗を引き起こします。
注釈 2
ranges::size(E)が有効な式である場合、その型は整数のような型です。

26.3.11 ranges::ssize(range.prim.ssize)[編集]

ranges::ssizeという名前は、カスタマイズポイントオブジェクトを示します。型Tを持つサブ式Eが与えられた場合、Eの具現化オブジェクトを示すlvalueをtとします。もしranges::size(t)が不正である場合、ranges::ssize(E)も不正です。それ以外の場合、Dをmake-signed-like-t <decltype(ranges::size(t))>、またはそれがその型より広い場合はptrdiff_tとします。ranges::ssize(E)は式的にstatic_cast<D>(ranges::size(t))と等価です。

26.3.12 ranges::empty(range.prim.empty)[編集]

ranges::emptyという名前は、カスタマイズポイントオブジェクトを示します。型Tを持つサブ式Eが与えられた場合、Eの具現化オブジェクトを示すlvalueをtとします。そして:

  • Tが不明なサイズの配列型である場合、ranges::empty(E)は不正です。
  • そうでない場合、
    • bool(t.empty())が有効な式である場合、ranges::empty(E)は式的にbool(t.empty())と等価です。
    • (ranges::size(t) == 0)が有効な式である場合、ranges::empty(E)は式的に(ranges::size(t) == 0)と等価です。
    • bool(ranges::begin(t) == ranges::end(t))が有効な式であり、ranges::begin(t)の型がforward_iteratorをモデル化する場合、ranges::empty(E)は式的にbool(ranges::begin(t) == ranges::end(t))と等価です。
    • それ以外の場合、ranges::empty(E)は不正です。
注釈 1
上記の診断可能な不正形式のケースは、ranges::empty(E)がテンプレートインスタンスの直接的な文脈で現れる場合、置換失敗を引き起こします。
注釈 2
ranges::empty(E)が有効な式である場合、その型はbool型です。

26.3.13 ranges::data(range.prim.data)[編集]

ranges::dataという名前は、カスタマイズポイントオブジェクトを示します。型Tを持つサブ式Eが与えられた場合、Eの具現化オブジェクトを示すlvalueをtとします。そして:

  • Eがrvalueであり、enable_borrowed_range<remove_cv_t<T>>がfalseの場合、ranges::data(E)は不正です。
  • そうでない場合、
    • Tが配列型でremove_all_extents_t<T>が不完全型である場合、ranges::data(E)は診断メッセージがない不正形式です。
    • auto(t.data())がオブジェクト型へのポインターの有効な式である場合、ranges::data(E)は式的にauto(t.data())と等価です。
    • ranges::begin(t)がcontiguous_iteratorをモデル化する有効な式である場合、ranges::data(E)は式的にto_address(ranges::begin(t))と等価です。
    • それ以外の場合、ranges::data(E)は不正です。
注釈 1
上記の診断可能な不正形式のケースは、ranges::data(E)がテンプレートインスタンスの直接的な文脈で現れる場合、置換失敗を引き起こします。
注釈 2
ranges::data(E)が有効な式である場合、その型はオブジェクト型へのポインターです。

26.3.14 ranges::cdata(range.prim.cdata)[編集]

ranges::cdataという名前は、カスタマイズポイントオブジェクトを示します。型Tを持つサブ式Eが与えられた場合、Eの具現化オブジェクトを示すlvalueをtとします。そして:

  • Eがrvalueであり、enable_borrowed_range<remove_cv_t<T>>がfalseの場合、ranges::cdata(E)は不正です。
  • そうでない場合、ranges::cdata(E)は式的にas-const-pointer(ranges::data(possibly-const-range(t)))と等価です。
注釈 1
ranges::cdata(E)が有効な式である場合、その型は定数オブジェクト型へのポインターです。

要件[編集]

範囲ユーティリティ[編集]

範囲ファクトリ[編集]

範囲アダプタ[編集]

範囲ジェネレータ[編集]