namespace std::ranges {
template<class F, class Tuple>
constexpr auto tuple-transform(F&& f, Tuple&& t) {
return apply([&]<class... Ts>(Ts&&... elements) {
return tuple<invoke_result_t<F&, Ts>...>(invoke(f, std::forward<Ts>(elements))...);
}, std::forward<Tuple>(t));
}
template<class F, class Tuple>
constexpr void tuple-for-each(F&& f, Tuple&& t) {
apply([&]<class... Ts>(Ts&&... elements) {
(static_cast<void>(invoke(f, std::forward<Ts>(elements))), ...);
}, std::forward<Tuple>(t));
}
template<class T>
constexpr T& as-lvalue(T&& t) {
return static_cast<T&>(t);
}
template<bool Const, class... Views>
concept all-random-access =
(random_access_range<maybe-const<Const, Views>> && ...);
template<bool Const, class... Views>
concept all-bidirectional =
(bidirectional_range<maybe-const<Const, Views>> && ...);
template<bool Const, class... Views>
concept all-forward =
(forward_range<maybe-const<Const, Views>> && ...);
}