Skip to content

Latest commit

 

History

History
72 lines (56 loc) · 3.16 KB

sized_range.md

File metadata and controls

72 lines (56 loc) · 3.16 KB

sized_range

  • ranges[meta header]
  • concept[meta id-type]
  • std::ranges[meta namespace]
  • cpp20[meta cpp]
namespace std::ranges {
  template<class T>
  concept sized_range = range<T> && requires(T& t) { ranges::size(t); };
}
  • range[link range.md]
  • ranges::size[link size.md]

概要

sized_rangeは、大きさを償却定数時間で求めることができるRangeを表すコンセプトである。

sized_rangeなRangeからはranges::sizeで大きさを取得できる。

sized_rangeではないRangeとしては、iota_viewのように無限長のもの、 forward_listのように大きさは決まっているが償却定数時間で求められないもの、 basic_istream_viewのように事前に求められないものなどがある。

モデル

型がremove_reference_t<T>であるようなlvaluetがあるとする。Tsized_rangeのモデルとなるのは、以下の条件をすべて満たす場合である。

  1. ranges::size(t)が償却定数時間で実行でき、ranges::distance(t)と等しく、tを変更しない。
  2. もしiterator_t<T>forward_iteratorのモデルであれば、ranges::size(t)ranges::begin(t)の評価によらず一意に定まる。

構文要件では、ranges::size(t)という呼び出しが可能であることしか要求されない。これは例えばTのメンバ関数size()が整数を返せば満たしてしまうが、その計算量が償却定数でない場合はsized_rangeのモデルとはならないので、disable_sized_rangetrueに特殊化してranges::size(t)を無効化する必要がある。

2番目の要件は、イテレータがinput_iteratorまたはoutput_iteratorであるときは、ranges::beginを呼び出すまでは大きさが定まらない、といった依存関係が許可されることを意味している。

#include <ranges>
#include <list>
#include <forward_list>
#include <vector>

int main()
{
  // vectorはsized_range
  static_assert(std::ranges::sized_range<std::vector<int>>);

  // listもsized_range
  static_assert(std::ranges::sized_range<std::list<int>>);

  // forward_listはsized_rangeではない
  static_assert(!std::ranges::sized_range<std::forward_list<int>>);
}
  • std::ranges::sized_range[color ff0000]

出力

バージョン

言語

  • C++20

処理系

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

参照