最終更新日時(UTC):
が更新

履歴 編集

class template
<ranges>

std::ranges::iota_view::iterator(C++20)

概要

iota_viewのイテレータ。

iota_viewの要素型の値を1つ記憶していて、イテレータに対するインクリメントなどの演算は、そのまま内部の値への演算となる。

このクラスの名前は規定されておらず、振る舞いのみが規定されている。

このクラスの型を取得したい場合、iterator_tを使用できる。

実装例

namespace std::ranges {

  inline namespace details {
    template<class I>
    concept decrementable =
      incrementable<I> && requires(I i) {
        { --i } -> same_as<I&>;
        { i-- } -> same_as<I>;
      };

    template<class I>
    concept advanceable =
      decrementable<I> && totally_ordered<I> &&
      requires(I i, const I j, const iota_diff_t<I> n) {
        { i += n } -> same_as<I&>;
        { i -= n } -> same_as<I&>;
        I(j + n);
        I(n + j);
        I(j - n);
        { j - j } -> convertible_to<iota_diff_t<I>>;
      };

    template<class W>
    constexpr auto get_iota_view_iterator_concept() {
      if constexpr (advanceable<W>) {
        return random_access_iterator_tag{};
      } else if constexpr (decrementable<W>) {
        return bidirectional_iterator_tag{};
      } else if constexpr (incrementable<W>) {
        return forward_iterator_tag{};
      } else {
        return input_iterator_tag{};
      }
    }
  }

  template<weakly_incrementable W, semiregular Bound>
    requires weakly-equality-comparable-with<W, Bound>
  struct iota_view<W, Bound>::iterator {
  private:
    W value_ = W();
  public:
    using iterator_concept = decltype(get_iota_view_iterator_concept());
    using iterator_category = input_iterator_tag;
    using value_type = W;
    using difference_type = iota_diff_t<W>;

    iterator() = default;
    constexpr explicit iterator(W value) : value_(value) {
    }

    constexpr W operator*() const noexcept(is_nothrow_copy_constructible_v<W>) {
      return value_;
    }

    constexpr iterator& operator++() {
      ++value_;
      return *this;
    }

    constexpr void operator++(int) {
      ++*this;
    }

    constexpr iterator operator++(int) requires incrementable<W> {
      auto tmp = *this;
      ++*this;
      return tmp;
    }

    constexpr iterator& operator--() requires decrementable<W> {
      --value_;
      return *this;
    }

    constexpr iterator operator--(int) requires decrementable<W> {
      auto tmp = *this;
      --*this;
      return tmp;
    }

    constexpr iterator& operator+=(difference_type n) requires advanceable<W> {
      if constexpr (is-integer-like<W> && !is-signed-integer-like<W>) {
        if (n >= difference_type(0))
          value_ += static_cast<W>(n);
        else
          value_ -= static_cast<W>(-n);
      } else {
        value_ += n;
      }
      return *this;
    }

    constexpr iterator& operator-=(difference_type n) requires advanceable<W> {
      if constexpr (is-integer-like<W> && !is-signed-integer-like<W>) {
        if (n >= difference_type(0))
          value_ -= static_cast<W>(n);
        else
          value_ += static_cast<W>(-n);
      } else {
        value_ -= n;
      }
      return *this;
    }

    constexpr W operator[](difference_type n) const requires advanceable<W> {
      return W(value_ + n);
    }

    friend constexpr bool operator==(const iterator& x, const iterator& y) requires equality_comparable<W> {
      return x.value_ == y.value_;
    }

    friend constexpr bool operator<(const iterator& x, const iterator& y) requires totally_ordered<W> {
      return x.value_ < y.value_;
    }

    friend constexpr bool operator>(const iterator& x, const iterator& y) requires totally_ordered<W> {
      return return y < x;
    }

    friend constexpr bool operator<=(const iterator& x, const iterator& y) requires totally_ordered<W> {
      return !(y < x);
    }

    friend constexpr bool operator>=(const iterator& x, const iterator& y) requires totally_ordered<W> {
      return !(x < y);
    }

    friend constexpr auto operator<=>(const iterator& x, const iterator& y) requires totally_ordered<W> && three_way_comparable<W> {
      return x.value_ <=> y.value_;
    }

    friend constexpr iterator operator+(iterator i, difference_type n) requires advanceable<W> {
      return i += n;
    }

    friend constexpr iterator operator+(difference_type n, iterator i) requires advanceable<W> {
      return i + n;
    }

    friend constexpr iterator operator-(iterator i, difference_type n) requires advanceable<W> {
      return i -= n;
    }

    friend constexpr difference_type operator-(const iterator& x, const iterator& y) requires advanceable<W> {
      using D = difference_type;
      if constexpr (is-integer-like<W>) {
        if constexpr (is-signed-integer-like<W>) {
          return D(D(x.value_) - D(y.value_));
        } else {
          return (y.value_ > x.value_)
            ? D(-D(y.value_ - x.value_))
            : D(x.value_ - y.value_);
        }
      } else {
        return x.value_ - y.value_;
      }
    }
  };
}

バージョン

言語

  • C++20

処理系

参照