21 using Range = std::pair<T, size_t>;
34 using RangeIt =
typename Ranges::const_iterator;
53 return !(*
this == other);
99 return (*
this) -= (size_t)-n_;
153 else if (
it < other.
it)
155 return -(other - (*this));
163 std::reverse_iterator(
it),
164 std::prev(std::reverse_iterator(other.
it)),
167 return acc + range.second + 1;
169 sum += other.
it->second - other.
offset;
178 template <
typename It>
179 void init_from_iterators(It
begin, It
end)
183 throw std::logic_error(
"Range must be sorted");
188 auto next = std::adjacent_find(
189 begin,
end, [](
const T& a,
const T& b) {
return a + 1 != b; });
192 ranges.emplace_back(*
begin,
size_t(std::distance(
begin,
end)) - 1);
195 ranges.emplace_back(*
begin,
size_t(std::distance(
begin, next)));
196 begin = std::next(next);
200 void init_from_iterators(
201 const ConstIterator&
begin,
const ConstIterator&
end)
211 ranges.insert(ranges.end(), std::next(
begin.
it),
end.
it);
229 void maybe_merge_with_following(
typename Ranges::iterator it)
231 if (it != ranges.end())
233 auto next_it = std::next(it);
234 if (next_it != ranges.end())
236 if (it->first + it->second + 1 == next_it->first)
238 it->second = it->second + 1 + next_it->second;
239 ranges.erase(next_it);
245 void maybe_merge_with_following(
typename Ranges::reverse_iterator it)
247 if (it != ranges.rend())
249 maybe_merge_with_following(std::next(it).base());
253 typename Ranges::const_iterator find_internal(
const T& t)
const
255 Range estimated_range{t, 0};
256 auto it = std::lower_bound(ranges.begin(), ranges.end(), estimated_range);
257 if (it != ranges.end())
268 if (it != ranges.begin())
271 const T& from = it->first;
272 const T additional = it->second;
273 if (from + additional >= t)
285 template <
typename It>
288 init_from_iterators(std::forward<It>(
begin), std::forward<It>(
end));
293 ranges.emplace_back(from, additional);
298 return ranges == other.ranges;
303 return !(*
this == other);
313 return std::accumulate(
314 ranges.begin(), ranges.end(), 0u, [](
size_t n,
const Range& r) {
315 return n + r.second + 1;
321 return ranges.empty();
330 const Range estimated_range(t + 1, 0);
331 auto it = std::lower_bound(
332 ranges.rbegin(), ranges.rend(), estimated_range, std::greater<>());
334 if (it != ranges.rend())
336 const T& from = it->first;
337 const T additional = it->second;
338 if (from <= t && t <= from + additional)
343 else if (from + additional + 1 == t)
347 maybe_merge_with_following(it);
350 else if (t + 1 == from)
355 if (it != ranges.rend())
357 maybe_merge_with_following(std::next(it));
364 auto emplaced_it = ranges.emplace(it.base(), t, 0);
365 maybe_merge_with_following(emplaced_it);
372 Range estimated_range{t, 0};
373 auto it = std::lower_bound(
379 return left.first < right.first;
388 if (it != ranges.begin() && (it == ranges.end() || t != it->first))
393 if (it != ranges.end())
395 const T& from = it->first;
396 const T additional = it->second;
397 if (from <= t && t <= from + additional)
402 if (additional == 0u)
416 else if (t == from + additional)
424 const auto before = t - it->first - 1;
425 const auto after = it->first + it->second - t - 1;
429 auto next_it = std::next(it);
430 ranges.emplace(next_it, t + 1, after);
439 void extend(
const T& from,
size_t additional)
441 for (
auto n = from; n <= from + additional; ++n)
449 return find_internal(t) !=
end();
454 auto it = find_internal(t);
455 if (it != ranges.end())
465 return std::lower_bound(
begin(),
end(), t);
470 return std::upper_bound(
begin(),
end(), t);
480 return ranges.front().first;
485 const auto back = ranges.back();
503struct formatter<
ccf::ds::ContiguousSet<T>>
505 template <
typename ParseContext>
506 constexpr auto parse(ParseContext& ctx)
511 template <
typename FormatContext>
514 std::vector<std::string> ranges;
515 for (
const auto& [from, additional] : v.
get_ranges())
517 ranges.emplace_back(fmt::format(
"[{}->{}]", from, from + additional));
521 "{{{} values in {} ranges: {}}}",
524 fmt::join(ranges,
", "));
Definition contiguous_set.h:17
ConstIterator end() const
Definition contiguous_set.h:494
ContiguousSet(const T &from, size_t additional)
Definition contiguous_set.h:291
T back() const
Definition contiguous_set.h:483
bool erase(const T &t)
Definition contiguous_set.h:370
void extend(const T &from, size_t additional)
Definition contiguous_set.h:439
ContiguousSet(It &&begin, It &&end)
Definition contiguous_set.h:286
ConstIterator find(const T &t) const
Definition contiguous_set.h:452
bool insert(const T &t)
Definition contiguous_set.h:324
bool empty() const
Definition contiguous_set.h:319
T front() const
Definition contiguous_set.h:478
ConstIterator begin() const
Definition contiguous_set.h:489
bool operator==(const ContiguousSet &other) const
Definition contiguous_set.h:296
bool operator!=(const ContiguousSet &other) const
Definition contiguous_set.h:301
size_t size() const
Definition contiguous_set.h:311
bool contains(const T &t) const
Definition contiguous_set.h:447
const Ranges & get_ranges() const
Definition contiguous_set.h:306
std::pair< T, size_t > Range
Definition contiguous_set.h:21
ConstIterator lower_bound(const T &t) const
Definition contiguous_set.h:463
std::vector< Range > Ranges
Definition contiguous_set.h:22
ConstIterator upper_bound(const T &t) const
Definition contiguous_set.h:468
void clear()
Definition contiguous_set.h:473
Definition contiguous_set.h:11
Definition app_interface.h:15
Definition contiguous_set.h:27
ConstIterator & operator-=(size_t n)
Definition contiguous_set.h:127
size_t reference
Definition contiguous_set.h:32
friend ConstIterator operator+(size_t n, const ConstIterator &other)
Definition contiguous_set.h:122
ConstIterator(RangeIt i, size_t o=0)
Definition contiguous_set.h:39
ConstIterator operator+(size_t n) const
Definition contiguous_set.h:115
size_t difference_type
Definition contiguous_set.h:30
RangeIt it
Definition contiguous_set.h:36
ConstIterator operator++(int)
Definition contiguous_set.h:67
size_t value_type
Definition contiguous_set.h:29
const size_t * pointer
Definition contiguous_set.h:31
ConstIterator & operator--()
Definition contiguous_set.h:74
ConstIterator operator--(int)
Definition contiguous_set.h:88
T operator*() const
Definition contiguous_set.h:41
std::random_access_iterator_tag iterator_category
Definition contiguous_set.h:28
ConstIterator operator-(size_t n) const
Definition contiguous_set.h:139
ConstIterator & operator++()
Definition contiguous_set.h:56
size_t offset
Definition contiguous_set.h:37
bool operator==(const ConstIterator &other) const
Definition contiguous_set.h:46
ConstIterator & operator+=(difference_type n_)
Definition contiguous_set.h:95
typename Ranges::const_iterator RangeIt
Definition contiguous_set.h:34
difference_type operator-(const ConstIterator &other) const
Definition contiguous_set.h:146
bool operator!=(const ConstIterator &other) const
Definition contiguous_set.h:51