OXYGENHUB
◆ main openmsx / src / utils / view.hh
1.4 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
#ifndef VIEW_HH
2
#define VIEW_HH
3
4
#include <iterator>
5
#include <ranges>
6
7
namespace view {
8
9
template<std::ranges::view V>
10
	requires std::ranges::sized_range<V>
11
class drop_back_view
12
	: public std::ranges::view_interface<drop_back_view<V>>
13
{
14
private:
15
	V base_;
16
	std::size_t n_;
17
18
public:
19
	drop_back_view() = default;
20
	constexpr drop_back_view(V base, std::size_t n)
21
		: base_(std::move(base)), n_(n) {}
22
23
	[[nodiscard]] constexpr V base() const& noexcept { return base_; }
24
	[[nodiscard]] constexpr V base() && { return std::move(base_); }
25
26
	[[nodiscard]] constexpr auto begin() { return std::ranges::begin(base_); }
27
28
	[[nodiscard]] constexpr auto end() {
29
		auto size = std::ranges::size(base_);
30
		if (n_ >= static_cast<std::size_t>(size)) {
31
			return std::ranges::begin(base_); // skip everything
32
		}
33
		return std::ranges::next(std::ranges::begin(base_), size - n_);
34
	}
35
};
36
37
template<typename R>
38
drop_back_view(R&&, std::size_t) -> drop_back_view<std::views::all_t<R>>;
39
40
struct drop_back_fn /*: public std::ranges::range_adaptor_closure<drop_back_fn>*/
41
{
42
	constexpr auto operator()(std::size_t n) const {
43
		return [n]<typename Range>(Range&& range) {
44
			return drop_back_view{
45
			        std::forward<Range>(range), n};
46
		};
47
	}
48
49
	template<std::ranges::viewable_range R>
50
	constexpr auto operator()(R&& r, std::size_t n) const {
51
		return drop_back_view{std::forward<R>(r), n};
52
	}
53
};
54
55
inline constexpr drop_back_fn drop_back;
56
57
} // namespace view
58
59
#endif