cpp-utils/include/ranges/first.hpp
2022-06-23 17:26:19 +01:00

42 lines
869 B
C++

#pragma once
#include <optional>
#include <ranges>
#include <xutility>
namespace util {
namespace rg = std::ranges;
namespace detail {
template <rg::input_range R>
constexpr auto get_first(R &&r) -> std::optional<rg::range_value_t<R>> {
if (rg::begin(r) == rg::end(r)) {
return std::nullopt;
} else {
return *rg::begin(r);
}
}
struct first_range_adaptor {
template <rg::input_range R> constexpr auto operator()(R &&r) const {
return get_first(std::forward<R>(r));
}
};
template <rg::viewable_range R>
constexpr auto operator|(R &&r, const first_range_adaptor &adaptor) {
return adaptor(std::forward<R>(r));
}
} // namespace detail
namespace views {
inline detail::first_range_adaptor first;
}
template <rg::range R>
constexpr auto get_first(R &&r) -> std::optional<rg::range_value_t<R>>{
return r | views::first;
}
} // namespace util