13 bool reset(
int count,
double estimate,
double spacing) {
14 if (count < 0 || ! validExtent(estimate) || ! validExtent(spacing) ||
15 ! std::isfinite((estimate + spacing) * count))
18 m_extents.assign(count, estimate);
21 for (
int i = 0; i < count; ++i) m_positive.insert(m_positive.end(), i);
22 m_tree.assign(
size_t(count) + 1, 0);
23 for (
size_t i = 1; i < m_tree.size(); ++i) {
24 m_tree[i] += estimate + spacing;
25 const size_t parent = i + lowBit(i);
26 if (parent < m_tree.size()) m_tree[parent] += m_tree[i];
31 int count()
const {
return int(m_extents.size()); }
32 double extent(
int index)
const {
return m_extents.at(index); }
33 double spacing()
const {
return m_spacing; }
35 bool setExtent(
int index,
double value) {
36 if (index < 0 || index >= count() || ! validExtent(value))
return false;
37 if (! std::isfinite(offset(count()) - m_extents[index] + value))
return false;
38 const double delta = value - m_extents[index];
39 m_extents[index] = value;
41 m_positive.insert(index);
43 m_positive.erase(index);
44 for (
size_t i =
size_t(index) + 1; i < m_tree.size(); i += lowBit(i)) m_tree[i] += delta;
48 double offset(
int index)
const {
50 for (
size_t i =
size_t(std::clamp(index, 0, count())); i; i -= lowBit(i))
55 double totalExtent()
const {
return count() ? std::max(0.0, offset(count()) - m_spacing) : 0; }
58 int indexAt(
double position)
const {
59 if (! count() || ! std::isfinite(position))
return -1;
60 if (position < 0)
return 0;
63 while (bit <=
size_t(count()) / 2) bit <<= 1;
65 for (; bit; bit >>= 1) {
66 const size_t next = index + bit;
67 if (next < m_tree.size() && prefix + m_tree[next] <= position) {
68 prefix += m_tree[next];
72 return std::min(
int(index), count() - 1);
81 Range visibleRange(
double begin,
double end)
const {
82 if (! std::isfinite(begin) || ! std::isfinite(end) || begin >= end || m_positive.empty())
84 int first = indexAt(begin);
85 if (offset(first) + extent(first) <= begin) ++first;
86 auto it = m_positive.lower_bound(first);
87 if (it == m_positive.end() || offset(*it) >= end)
return {};
89 int last = indexAt(end);
90 if (offset(last) >= end) --last;
91 auto past = m_positive.upper_bound(last);
92 if (past == m_positive.begin())
return {};
94 return { first, *past };
98 static size_t lowBit(
size_t value) {
return value & (~value + 1); }
99 static bool validExtent(
double value) {
return std::isfinite(value) && value >= 0; }
100 double m_spacing { 0 };
101 std::vector<double> m_extents;
102 std::vector<double> m_tree;
103 std::set<int> m_positive;