23 using Range = std::pair<T, size_t>;
36 using RangeIt =
typename Ranges::const_iterator;
55 return !(*
this == other);
103 return (*
this) -=
static_cast<size_t>(-(n_ + 1)) + 1;
105 auto n =
static_cast<size_t>(n_);
159 return -(other - (*this));
165 size_t sum = std::accumulate(
166 std::reverse_iterator(
it),
167 std::prev(std::reverse_iterator(other.
it)),
169 [](
size_t acc,
const auto& range) { return acc + range.second + 1; });
170 sum += other.
it->second - other.
offset;
178 return it < other.
it;
185 return !(other < *
this);
190 return other < *
this;
195 return !(*
this < other);
202 template <
typename It>
203 void init_from_iterators(It
begin, It
end)
207 throw std::logic_error(
"Range must be sorted");
212 auto next = std::adjacent_find(
213 begin,
end, [](
const T& a,
const T& b) {
return a + 1 != b; });
216 ranges.emplace_back(*
begin,
size_t(std::distance(
begin,
end)) - 1);
219 ranges.emplace_back(*
begin,
size_t(std::distance(
begin, next)));
220 begin = std::next(next);
224 void init_from_iterators(
225 const ConstIterator&
begin,
const ConstIterator&
end)
235 ranges.insert(ranges.end(), std::next(
begin.
it),
end.
it);
253 void maybe_merge_with_following(
typename Ranges::iterator it)
255 if (it != ranges.end())
257 auto next_it = std::next(it);
258 if (next_it != ranges.end())
260 if (it->first + it->second + 1 == next_it->first)
262 it->second = it->second + 1 + next_it->second;
263 ranges.erase(next_it);
269 void maybe_merge_with_following(
typename Ranges::reverse_iterator it)
271 if (it != ranges.rend())
273 maybe_merge_with_following(std::next(it).base());
277 [[nodiscard]]
typename Ranges::const_iterator find_internal(
280 Range estimated_range{t, 0};
281 auto it = std::lower_bound(ranges.begin(), ranges.end(), estimated_range);
282 if (it != ranges.end())
293 if (it != ranges.begin())
296 const T& from = it->first;
297 const T additional = it->second;
298 if (from + additional >= t)
310 template <
typename It>
313 init_from_iterators(std::forward<It>(
begin), std::forward<It>(
end));
318 ranges.emplace_back(from, additional);
323 return ranges == other.ranges;
328 return !(*
this == other);
336 [[nodiscard]]
size_t size()
const
338 return std::accumulate(
339 ranges.begin(), ranges.end(), 0u, [](
size_t n,
const Range& r) {
340 return n + r.second + 1;
346 return ranges.empty();
355 const Range estimated_range(t + 1, 0);
356 auto it = std::lower_bound(
357 ranges.rbegin(), ranges.rend(), estimated_range, std::greater<>());
359 if (it != ranges.rend())
361 const T& from = it->first;
362 const T additional = it->second;
363 if (from <= t && t <= from + additional)
369 if (from + additional + 1 == t)
373 maybe_merge_with_following(it);
382 if (it != ranges.rend())
384 maybe_merge_with_following(std::next(it));
391 auto emplaced_it = ranges.emplace(it.base(), t, 0);
392 maybe_merge_with_following(emplaced_it);
399 Range estimated_range{t, 0};
400 auto it = std::lower_bound(
406 return left.first < right.first;
415 if (it != ranges.begin() && (it == ranges.end() || t != it->first))
420 if (it != ranges.end())
422 const T& from = it->first;
423 const T additional = it->second;
424 if (from <= t && t <= from + additional)
429 if (additional == 0u)
441 if (t == from + additional)
448 const auto before = t - it->first - 1;
449 const auto after = it->first + it->second - t - 1;
453 auto next_it = std::next(it);
454 ranges.emplace(next_it, t + 1, after);
462 void extend(
const T& from,
size_t additional)
464 for (
auto n = from; n <= from + additional; ++n)
472 return find_internal(t) !=
end().
it;
477 auto it = find_internal(t);
478 if (it != ranges.end())
488 return std::lower_bound(
begin(),
end(), t);
493 return std::upper_bound(
begin(),
end(), t);
503 return ranges.front().first;
508 const auto back = ranges.back();
526struct formatter<
ccf::ds::ContiguousSet<T>>
528 template <
typename ParseContext>
529 constexpr auto parse(ParseContext& ctx)
534 template <
typename FormatContext>
537 std::vector<std::string> ranges;
538 for (
const auto& [from, additional] : v.
get_ranges())
540 ranges.emplace_back(fmt::format(
"[{}->{}]", from, from + additional));
544 "{{{} values in {} ranges: {}}}",
547 fmt::join(ranges,
", "));
Definition contiguous_set.h:19
ConstIterator end() const
Definition contiguous_set.h:517
ContiguousSet(const T &from, size_t additional)
Definition contiguous_set.h:316
T back() const
Definition contiguous_set.h:506
bool erase(const T &t)
Definition contiguous_set.h:397
void extend(const T &from, size_t additional)
Definition contiguous_set.h:462
ContiguousSet(It &&begin, It &&end)
Definition contiguous_set.h:311
ConstIterator find(const T &t) const
Definition contiguous_set.h:475
bool insert(const T &t)
Definition contiguous_set.h:349
bool empty() const
Definition contiguous_set.h:344
T front() const
Definition contiguous_set.h:501
ConstIterator begin() const
Definition contiguous_set.h:512
bool operator==(const ContiguousSet &other) const
Definition contiguous_set.h:321
bool operator!=(const ContiguousSet &other) const
Definition contiguous_set.h:326
size_t size() const
Definition contiguous_set.h:336
bool contains(const T &t) const
Definition contiguous_set.h:470
const Ranges & get_ranges() const
Definition contiguous_set.h:331
std::pair< T, size_t > Range
Definition contiguous_set.h:23
ConstIterator lower_bound(const T &t) const
Definition contiguous_set.h:486
std::vector< Range > Ranges
Definition contiguous_set.h:24
ConstIterator upper_bound(const T &t) const
Definition contiguous_set.h:491
void clear()
Definition contiguous_set.h:496
Definition contiguous_set.h:13
Definition app_interface.h:13
Definition contiguous_set.h:29
ConstIterator operator-(difference_type n) const
Definition contiguous_set.h:141
bool operator<=(const ConstIterator &other) const
Definition contiguous_set.h:183
ConstIterator operator+(difference_type n) const
Definition contiguous_set.h:116
ConstIterator & operator-=(size_t n)
Definition contiguous_set.h:129
size_t reference
Definition contiguous_set.h:34
friend ConstIterator operator+(difference_type n, const ConstIterator &other)
Definition contiguous_set.h:123
ConstIterator(RangeIt i, size_t o=0)
Definition contiguous_set.h:41
bool operator<(const ConstIterator &other) const
Definition contiguous_set.h:174
ptrdiff_t difference_type
Definition contiguous_set.h:32
bool operator>=(const ConstIterator &other) const
Definition contiguous_set.h:193
RangeIt it
Definition contiguous_set.h:38
ConstIterator operator++(int)
Definition contiguous_set.h:69
size_t value_type
Definition contiguous_set.h:31
const size_t * pointer
Definition contiguous_set.h:33
ConstIterator & operator--()
Definition contiguous_set.h:76
ConstIterator operator--(int)
Definition contiguous_set.h:90
T operator*() const
Definition contiguous_set.h:43
std::random_access_iterator_tag iterator_category
Definition contiguous_set.h:30
bool operator>(const ConstIterator &other) const
Definition contiguous_set.h:188
ConstIterator & operator++()
Definition contiguous_set.h:58
size_t offset
Definition contiguous_set.h:39
bool operator==(const ConstIterator &other) const
Definition contiguous_set.h:48
ConstIterator & operator+=(difference_type n_)
Definition contiguous_set.h:97
typename Ranges::const_iterator RangeIt
Definition contiguous_set.h:36
difference_type operator-(const ConstIterator &other) const
Definition contiguous_set.h:148
bool operator!=(const ConstIterator &other) const
Definition contiguous_set.h:53