42 lines
869 B
C++
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
|