dl
dl_discrete_range.h
浏览该文件的文档.
1
12#pragma once
13
14#include <optional>
15
16namespace dl
17{
19template<typename T>
21{
22 using Range = std::array<T, 2>;
23public:
24 void Add(const T& v)
25 {
26 auto iter = _data.begin();
27 while (iter != _data.end())
28 {
29 Range& r = *iter;
30 if (v < r[0])
31 {// 小于区间左侧,必定不在所有区间内
32 if (v + 1 == r[0])
33 {// 刚好在边上
34 --r[0];
35 // 左移后不会连接到上一个区间,因为上一个区间已经判断
36 return;
37 }
38 // 添加新区间
39 break;
40 }
41 if (v > r[1])
42 {// 大于区间右侧,必定不在当前区间内
43 if (v == r[1] + 1)
44 {// 刚好在边上
45 auto iter_next = std::next(iter);
46 if (iter_next != _data.end() && (*iter_next)[0] == v + 1)
47 {
48 // 右移后会连接到下一个区间
49 r[1] = (*iter_next)[1];
50 _data.erase(iter_next);
51 }
52 else
53 ++r[1];
54 return;
55 }
56 ++iter;
57 continue;
58 }
59 // 剩下条件在范围内
60 return;
61 }
62 _data.insert(iter, { v, v });
63 }
64
65 std::string ToString()
66 {
67 std::string ret;
68 for (auto& iter : _data)
69 {
70 ret += fmt::format("[{}] ", to_string(iter));
71 }
72 return ret;
73 }
74
75 std::optional<Range> GetTotalRange()
76 {
77 if (_data.empty())
78 return {};
79 if (_data.size() == 1)
80 return _data.front();
81 return Range{ _data.front()[0], _data.back()[1] };
82 }
83private:
84 std::list<Range> _data;
85};
86}
std::optional< Range > GetTotalRange()
std::string to_string(T v)
to_string包装