MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
range_helper.h
Go to the documentation of this file.
1#pragma once
2
3#include <cstdint>
4
5#include <format>
6#include <optional>
7#include <string_view>
8#include <vector>
9
10namespace automaton {
11
12using Range = std::pair<std::uint64_t, std::uint64_t>;
13
15 inline bool operator()(const Range& a, const Range& b) const noexcept { return a.first < b.first; }
16};
17
18inline std::optional<Range> merge_ranges(Range a, Range b) noexcept {
19 if (!(a.second + 1 < b.first || b.second + 1 < a.first)) {
20 return {
21 {std::min(a.first, b.first), std::max(a.second, b.second)}
22 };
23 }
24 return {};
25}
26
27// precondition: ranges are sorted by increasing lower bound
28template<class Vec, class LogF>
29Vec merge_ranges(const Vec& old_ranges, LogF&& log) {
30 Vec new_ranges;
31 for (auto it = old_ranges.begin(); it != old_ranges.end(); ++it) {
32 auto current_range = *it;
33 log(std::format("old range: {}-{}", current_range.first, current_range.second));
34 for (auto inner = it + 1; inner != old_ranges.end(); ++inner)
35 if (auto merged = merge_ranges(current_range, *inner)) current_range = *merged;
36
37 std::vector<typename Vec::iterator> de_duplicate;
38 for (auto inner = new_ranges.begin(); inner != new_ranges.end(); ++inner) {
39 if (auto merged = merge_ranges(current_range, *inner)) {
40 current_range = *merged;
41 de_duplicate.push_back(inner);
42 }
43 }
44 for (auto dedup : de_duplicate) {
45 log(std::format("dedup {}-{}", current_range.first, current_range.second));
46 new_ranges.erase(dedup);
47 }
48 log(std::format("new range: {}-{}", current_range.first, current_range.second));
49 new_ranges.push_back(std::move(current_range));
50 }
51 return new_ranges;
52}
53
54// precondition: ranges are sorted by increasing lower bound
55template<class Vec>
56auto merge_ranges(const Vec& old_ranges) {
57 return merge_ranges(old_ranges, [](std::string_view) {});
58}
59
60} // namespace automaton
std::pair< std::uint64_t, std::uint64_t > Range
std::optional< Range > merge_ranges(Range a, Range b) noexcept
bool operator()(const Range &a, const Range &b) const noexcept