22 using Range = std::pair<T, size_t>;
35 using RangeIt =
typename Ranges::const_iterator;
54 return !(*
this == other);
100 return (*
this) -= (size_t)-n_;
154 return -(other - (*this));
161 std::reverse_iterator(
it),
162 std::prev(std::reverse_iterator(other.
it)),
165 return acc + range.second + 1;
167 sum += other.
it->second - other.
offset;
175 template <
typename It>
176 void init_from_iterators(It
begin, It
end)
180 throw std::logic_error(
"Range must be sorted");
185 auto next = std::adjacent_find(
186 begin,
end, [](
const T& a,
const T& b) {
return a + 1 != b; });
189 ranges.emplace_back(*
begin,
size_t(std::distance(
begin,
end)) - 1);
192 ranges.emplace_back(*
begin,
size_t(std::distance(
begin, next)));
193 begin = std::next(next);
197 void init_from_iterators(
198 const ConstIterator&
begin,
const ConstIterator&
end)
208 ranges.insert(ranges.end(), std::next(
begin.
it),
end.
it);
226 void maybe_merge_with_following(
typename Ranges::iterator it)
228 if (it != ranges.end())
230 auto next_it = std::next(it);
231 if (next_it != ranges.end())
233 if (it->first + it->second + 1 == next_it->first)
235 it->second = it->second + 1 + next_it->second;
236 ranges.erase(next_it);
242 void maybe_merge_with_following(
typename Ranges::reverse_iterator it)
244 if (it != ranges.rend())
246 maybe_merge_with_following(std::next(it).base());
250 [[nodiscard]]
typename Ranges::const_iterator find_internal(
253 Range estimated_range{t, 0};
254 auto it = std::lower_bound(ranges.begin(), ranges.end(), estimated_range);
255 if (it != ranges.end())
266 if (it != ranges.begin())
269 const T& from = it->first;
270 const T additional = it->second;
271 if (from + additional >= t)
283 template <
typename It>
286 init_from_iterators(std::forward<It>(
begin), std::forward<It>(
end));
291 ranges.emplace_back(from, additional);
296 return ranges == other.ranges;
301 return !(*
this == other);
309 [[nodiscard]]
size_t size()
const
311 return std::accumulate(
312 ranges.begin(), ranges.end(), 0u, [](
size_t n,
const Range& r) {
313 return n + r.second + 1;
319 return ranges.empty();
328 const Range estimated_range(t + 1, 0);
329 auto it = std::lower_bound(
330 ranges.rbegin(), ranges.rend(), estimated_range, std::greater<>());
332 if (it != ranges.rend())
334 const T& from = it->first;
335 const T additional = it->second;
336 if (from <= t && t <= from + additional)
342 if (from + additional + 1 == t)
346 maybe_merge_with_following(it);
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)
414 if (t == from + additional)
421 const auto before = t - it->first - 1;
422 const auto after = it->first + it->second - t - 1;
426 auto next_it = std::next(it);
427 ranges.emplace(next_it, t + 1, after);
435 void extend(
const T& from,
size_t additional)
437 for (
auto n = from; n <= from + additional; ++n)
445 return find_internal(t) !=
end().
it;
450 auto it = find_internal(t);
451 if (it != ranges.end())
461 return std::lower_bound(
begin(),
end(), t);
466 return std::upper_bound(
begin(),
end(), t);
476 return ranges.front().first;
481 const auto back = ranges.back();
499struct formatter<
ccf::ds::ContiguousSet<T>>
501 template <
typename ParseContext>
502 constexpr auto parse(ParseContext& ctx)
507 template <
typename FormatContext>
510 std::vector<std::string> ranges;
511 for (
const auto& [from, additional] : v.
get_ranges())
513 ranges.emplace_back(fmt::format(
"[{}->{}]", from, from + additional));
517 "{{{} values in {} ranges: {}}}",
520 fmt::join(ranges,
", "));
Definition contiguous_set.h:18
ConstIterator end() const
Definition contiguous_set.h:490
ContiguousSet(const T &from, size_t additional)
Definition contiguous_set.h:289
T back() const
Definition contiguous_set.h:479
bool erase(const T &t)
Definition contiguous_set.h:370
void extend(const T &from, size_t additional)
Definition contiguous_set.h:435
ContiguousSet(It &&begin, It &&end)
Definition contiguous_set.h:284
ConstIterator find(const T &t) const
Definition contiguous_set.h:448
bool insert(const T &t)
Definition contiguous_set.h:322
bool empty() const
Definition contiguous_set.h:317
T front() const
Definition contiguous_set.h:474
ConstIterator begin() const
Definition contiguous_set.h:485
bool operator==(const ContiguousSet &other) const
Definition contiguous_set.h:294
bool operator!=(const ContiguousSet &other) const
Definition contiguous_set.h:299
size_t size() const
Definition contiguous_set.h:309
bool contains(const T &t) const
Definition contiguous_set.h:443
const Ranges & get_ranges() const
Definition contiguous_set.h:304
std::pair< T, size_t > Range
Definition contiguous_set.h:22
ConstIterator lower_bound(const T &t) const
Definition contiguous_set.h:459
std::vector< Range > Ranges
Definition contiguous_set.h:23
ConstIterator upper_bound(const T &t) const
Definition contiguous_set.h:464
void clear()
Definition contiguous_set.h:469
Definition contiguous_set.h:12
Definition app_interface.h:14
Definition contiguous_set.h:28
ConstIterator & operator-=(size_t n)
Definition contiguous_set.h:125
size_t reference
Definition contiguous_set.h:33
friend ConstIterator operator+(size_t n, const ConstIterator &other)
Definition contiguous_set.h:120
ConstIterator(RangeIt i, size_t o=0)
Definition contiguous_set.h:40
ConstIterator operator+(size_t n) const
Definition contiguous_set.h:113
size_t difference_type
Definition contiguous_set.h:31
RangeIt it
Definition contiguous_set.h:37
ConstIterator operator++(int)
Definition contiguous_set.h:68
size_t value_type
Definition contiguous_set.h:30
const size_t * pointer
Definition contiguous_set.h:32
ConstIterator & operator--()
Definition contiguous_set.h:75
ConstIterator operator--(int)
Definition contiguous_set.h:89
T operator*() const
Definition contiguous_set.h:42
std::random_access_iterator_tag iterator_category
Definition contiguous_set.h:29
ConstIterator operator-(size_t n) const
Definition contiguous_set.h:137
ConstIterator & operator++()
Definition contiguous_set.h:57
size_t offset
Definition contiguous_set.h:38
bool operator==(const ConstIterator &other) const
Definition contiguous_set.h:47
ConstIterator & operator+=(difference_type n_)
Definition contiguous_set.h:96
typename Ranges::const_iterator RangeIt
Definition contiguous_set.h:35
difference_type operator-(const ConstIterator &other) const
Definition contiguous_set.h:144
bool operator!=(const ConstIterator &other) const
Definition contiguous_set.h:52