Concept Subspace :: sus :: ops :: RangeBounds

template <class T, class I>
concept RangeBounds
requires
requires(const T& t, T& v, const I& i) {
  { t.start_bound() } -> std::same_as<::sus::option::Option<const I&>>;
  { t.end_bound() } -> std::same_as<::sus::option::Option<const I&>>;
  // Rvalue overloads must not exist as they would return a reference to a
  // temporary.
  requires !requires { ::sus::move(v).start_bound(); };
  requires !requires { ::sus::move(v).end_bound(); };
  { t.contains(i) } -> std::same_as<bool>;
  // These should return a RangeBounds, but we're unable to check that here as
  // the type may return itself and the concept would be cyclical and thus
  // become false.
  { ::sus::move(v).start_at(i) };
  { ::sus::move(v).end_at(i) };
  // start_at() and end_at() are rvalue methods if T is not Copy.
  requires sus::mem::Copy<T> || !requires { t.start_at(i); };
  requires sus::mem::Copy<T> || !requires { t.end_at(i); };
  requires sus::mem::Copy<T> || !requires { v.start_at(i); };
  requires sus::mem::Copy<T> || !requires { v.end_at(i); };
  // start_at() and end_at() are lvalue methods if T is Copy.
  requires !sus::mem::Copy<T> || requires { t.start_at(i); };
  requires !sus::mem::Copy<T> || requires { t.end_at(i); };
  requires !sus::mem::Copy<T> || requires { v.start_at(i); };
  requires !sus::mem::Copy<T> || requires { v.end_at(i); };
}

RangeBounds is implemented by Subspace's range types, and produced by range syntax like .., a.., ..b, ..=c, d..e, or f..=g.