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 else if (
it < other.
it)
156 return -(other - (*this));
164 std::reverse_iterator(
it),
165 std::prev(std::reverse_iterator(other.
it)),
168 return acc + range.second + 1;
170 sum += other.
it->second - other.
offset;
179 template <
typename It>
180 void init_from_iterators(It
begin, It
end)
184 throw std::logic_error(
"Range must be sorted");
189 auto next = std::adjacent_find(
190 begin,
end, [](
const T& a,
const T& b) {
return a + 1 != b; });
193 ranges.emplace_back(*
begin,
size_t(std::distance(
begin,
end)) - 1);
196 ranges.emplace_back(*
begin,
size_t(std::distance(
begin, next)));
197 begin = std::next(next);
201 void init_from_iterators(
202 const ConstIterator&
begin,
const ConstIterator&
end)
212 ranges.insert(ranges.end(), std::next(
begin.
it),
end.
it);
230 void maybe_merge_with_following(
typename Ranges::iterator it)
232 if (it != ranges.end())
234 auto next_it = std::next(it);
235 if (next_it != ranges.end())
237 if (it->first + it->second + 1 == next_it->first)
239 it->second = it->second + 1 + next_it->second;
240 ranges.erase(next_it);
246 void maybe_merge_with_following(
typename Ranges::reverse_iterator it)
248 if (it != ranges.rend())
250 maybe_merge_with_following(std::next(it).base());
254 typename Ranges::const_iterator find_internal(
const T& t)
const
256 Range estimated_range{t, 0};
257 auto it = std::lower_bound(ranges.begin(), ranges.end(), estimated_range);
258 if (it != ranges.end())
269 if (it != ranges.begin())
272 const T& from = it->first;
273 const T additional = it->second;
274 if (from + additional >= t)
286 template <
typename It>
289 init_from_iterators(std::forward<It>(
begin), std::forward<It>(
end));
294 ranges.emplace_back(from, additional);
299 return ranges == other.ranges;
304 return !(*
this == other);
314 return std::accumulate(
315 ranges.begin(), ranges.end(), 0u, [](
size_t n,
const Range& r) {
316 return n + r.second + 1;
322 return ranges.empty();
331 const Range estimated_range(t + 1, 0);
332 auto it = std::lower_bound(
333 ranges.rbegin(), ranges.rend(), estimated_range, std::greater<>());
335 if (it != ranges.rend())
337 const T& from = it->first;
338 const T additional = it->second;
339 if (from <= t && t <= from + additional)
344 else if (from + additional + 1 == t)
348 maybe_merge_with_following(it);
351 else if (t + 1 == from)
356 if (it != ranges.rend())
358 maybe_merge_with_following(std::next(it));
365 auto emplaced_it = ranges.emplace(it.base(), t, 0);
366 maybe_merge_with_following(emplaced_it);
373 Range estimated_range{t, 0};
374 auto it = std::lower_bound(
380 return left.first < right.first;
389 if (it != ranges.begin() && (it == ranges.end() || t != it->first))
394 if (it != ranges.end())
396 const T& from = it->first;
397 const T additional = it->second;
398 if (from <= t && t <= from + additional)
403 if (additional == 0u)
417 else if (t == from + additional)
425 const auto before = t - it->first - 1;
426 const auto after = it->first + it->second - t - 1;
430 auto next_it = std::next(it);
431 ranges.emplace(next_it, t + 1, after);
440 void extend(
const T& from,
size_t additional)
442 for (
auto n = from; n <= from + additional; ++n)
450 return find_internal(t) !=
end().
it;
455 auto it = find_internal(t);
456 if (it != ranges.end())
466 return std::lower_bound(
begin(),
end(), t);
471 return std::upper_bound(
begin(),
end(), t);
481 return ranges.front().first;
486 const auto back = ranges.back();
504struct formatter<
ccf::ds::ContiguousSet<T>>
506 template <
typename ParseContext>
507 constexpr auto parse(ParseContext& ctx)
512 template <
typename FormatContext>
515 std::vector<std::string> ranges;
516 for (
const auto& [from, additional] : v.
get_ranges())
518 ranges.emplace_back(fmt::format(
"[{}->{}]", from, from + additional));
522 "{{{} values in {} ranges: {}}}",
525 fmt::join(ranges,
", "));
Definition contiguous_set.h:18
ConstIterator end() const
Definition contiguous_set.h:495
ContiguousSet(const T &from, size_t additional)
Definition contiguous_set.h:292
T back() const
Definition contiguous_set.h:484
bool erase(const T &t)
Definition contiguous_set.h:371
void extend(const T &from, size_t additional)
Definition contiguous_set.h:440
ContiguousSet(It &&begin, It &&end)
Definition contiguous_set.h:287
ConstIterator find(const T &t) const
Definition contiguous_set.h:453
bool insert(const T &t)
Definition contiguous_set.h:325
bool empty() const
Definition contiguous_set.h:320
T front() const
Definition contiguous_set.h:479
ConstIterator begin() const
Definition contiguous_set.h:490
bool operator==(const ContiguousSet &other) const
Definition contiguous_set.h:297
bool operator!=(const ContiguousSet &other) const
Definition contiguous_set.h:302
size_t size() const
Definition contiguous_set.h:312
bool contains(const T &t) const
Definition contiguous_set.h:448
const Ranges & get_ranges() const
Definition contiguous_set.h:307
std::pair< T, size_t > Range
Definition contiguous_set.h:22
ConstIterator lower_bound(const T &t) const
Definition contiguous_set.h:464
std::vector< Range > Ranges
Definition contiguous_set.h:23
ConstIterator upper_bound(const T &t) const
Definition contiguous_set.h:469
void clear()
Definition contiguous_set.h:474
Definition contiguous_set.h:12
Definition app_interface.h:14
Definition contiguous_set.h:28
ConstIterator & operator-=(size_t n)
Definition contiguous_set.h:128
size_t reference
Definition contiguous_set.h:33
friend ConstIterator operator+(size_t n, const ConstIterator &other)
Definition contiguous_set.h:123
ConstIterator(RangeIt i, size_t o=0)
Definition contiguous_set.h:40
ConstIterator operator+(size_t n) const
Definition contiguous_set.h:116
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:140
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:147
bool operator!=(const ConstIterator &other) const
Definition contiguous_set.h:52