60 using size_type =
typename std::vector<value_type>::size_type;
61 using difference_type =
typename std::vector<value_type>::difference_type;
64 using allocator_type =
typename std::vector<value_type>::allocator_type;
65 using reference =
typename std::vector<value_type>::reference;
66 using const_reference =
typename std::vector<value_type>::const_reference;
67 using pointer =
typename std::vector<value_type>::pointer;
68 using const_pointer =
typename std::vector<value_type>::const_pointer;
69 using iterator =
typename std::vector<value_type>::const_iterator;
70 using const_iterator =
typename std::vector<value_type>::const_iterator;
71 using reverse_iterator =
typename std::vector<value_type>::const_reverse_iterator;
72 using const_reverse_iterator =
typename std::vector<value_type>::const_reverse_iterator;
82 template <
class InputIt,
83 typename = std::enable_if_t<std::is_base_of_v<
84 std::input_iterator_tag,
85 typename std::iterator_traits<InputIt>::iterator_category>>>
86 RangeSet(InputIt first, InputIt last)
97 template <
typename Key2>
101 insert(std::cbegin(other), std::cend(other));
106 RangeSet(std::initializer_list<value_type> init) { insert(init); }
108 RangeSet(std::initializer_list<Key> init) { insert(init); }
122 ranges_ = other.ranges_;
126 template <
typename Key2>
131 insert(std::cbegin(other), std::cend(other));
136 std::allocator_traits<allocator_type>::is_always_equal::value &&
137 std::is_nothrow_move_assignable<value_compare>::value)
140 ranges_ = std::move(other.ranges_);
144 RangeSet& operator=(std::initializer_list<value_type> ilist)
155 allocator_type get_allocator()
const noexcept {
return ranges_.get_allocator(); }
161 iterator begin()
noexcept {
return std::begin(ranges_); }
163 const_iterator begin()
const noexcept {
return std::begin(ranges_); }
165 const_iterator cbegin()
const noexcept {
return std::cbegin(ranges_); }
167 iterator end()
noexcept {
return std::end(ranges_); }
169 const_iterator end()
const noexcept {
return std::end(ranges_); }
171 const_iterator cend()
const noexcept {
return std::cend(ranges_); }
173 reverse_iterator rbegin()
noexcept {
return std::rbegin(ranges_); }
175 const_reverse_iterator rbegin()
const noexcept {
return std::rbegin(ranges_); }
177 const_reverse_iterator crbegin()
const noexcept {
return std::crbegin(ranges_); }
179 reverse_iterator rend()
noexcept {
return std::rend(ranges_); }
181 const_reverse_iterator rend()
const noexcept {
return std::rend(ranges_); }
183 const_reverse_iterator crend()
const noexcept {
return std::crend(ranges_); }
189 [[nodiscard]]
bool empty()
const noexcept {
return ranges_.empty(); }
191 [[nodiscard]] size_type size()
const noexcept {
return ranges_.size(); }
193 [[nodiscard]] size_type max_size()
const noexcept {
return ranges_.max_size(); }
195 [[nodiscard]] size_type numRanges()
const noexcept {
return size(); }
197 template <
typename Key2 = Key>
198 [[nodiscard]] std::enable_if_t<std::is_integral_v<Key2>, size_type> numValues()
const
200 return std::accumulate(begin(), end(), numRanges(), [](
auto cur,
auto range) {
209 void clear()
noexcept { ranges_.clear(); }
211 std::pair<iterator, bool> insert(
value_type value)
216 Key
const lower_up = decrement(value.lower());
221 Key
const upper_op = increment(value.upper());
223 auto [lower, upper] = equal_range(lower_up, value.upper());
225 auto dist = std::distance(begin(), lower);
226 bool inserted =
false;
228 if (end() == lower) {
234 ranges_.push_back(value);
235 }
else if (lower == upper && upper_op < upper->lower()) {
241 ranges_.insert(lower, value);
246 auto nc_lower = std::next(std::begin(ranges_), dist);
248 inserted = value.lower() < lower->lower();
250 nc_lower->setRange(std::min(lower->lower(), value.lower()), lower->upper());
251 if (end() == upper || upper_op < upper->lower()) {
252 inserted = inserted || lower->upper() < value.upper();
257 nc_lower->setRange(lower->lower(), std::max(lower->upper(), value.upper()));
258 erase(std::next(lower), upper);
260 inserted = inserted || lower != upper;
265 nc_lower->setRange(lower->lower(), upper->upper());
266 erase(std::next(lower), std::next(upper));
270 return {std::next(begin(), dist), inserted};
273 iterator insert(const_iterator hint,
value_type value)
276 return insert(value).first;
279 template <
class InputIt,
280 typename = std::enable_if_t<std::is_base_of_v<
281 std::input_iterator_tag,
282 typename std::iterator_traits<InputIt>::iterator_category>>>
283 void insert(InputIt first, InputIt last)
286 std::for_each(first, last, [
this](
auto&&... args) { this->insert(args...); });
289 void insert(std::initializer_list<value_type> ilist)
291 insert(std::cbegin(ilist), std::cend(ilist));
298 template <
class... Args>
299 std::pair<iterator, bool> emplace(Args&&... args)
301 return insert(
value_type(std::forward<Args>(args)...));
304 template <
class... Args>
305 iterator emplace_hint(const_iterator hint, Args&&... args)
307 return insert(hint,
value_type(std::forward<Args>(args)...));
310 iterator erase(const_iterator pos) {
return ranges_.erase(pos); }
312 iterator erase(const_iterator first, const_iterator last)
314 return ranges_.erase(first, last);
321 auto [lower, upper] = equal_range(key);
323 auto nc_lower = std::next(std::begin(ranges_), std::distance(begin(), lower));
324 auto nc_upper = std::next(std::begin(ranges_), std::distance(begin(), upper));
326 Key
const lower_up = decrement(key.
lower());
327 Key
const upper_op = increment(key.
upper());
329 size_type num_removed = 0;
331 if (end() == lower || (lower == upper && key.
upper() < lower->
lower())) {
333 }
else if (lower == upper) {
338 nc_lower->setRange(upper_op, lower->upper());
341 auto cur_upper = lower->upper();
342 nc_lower->setRange(lower->lower(), lower_up);
343 ranges_.emplace(std::next(lower), upper_op, cur_upper);
346 if (end() != upper) {
347 num_removed = upper->lower() < upper_op ? 1 : 0;
348 nc_upper->setRange(std::max(upper->lower(), upper_op), upper->upper());
351 num_removed += std::distance(lower, upper);
355 ranges_.erase(lower, upper);
358 nc_lower->setRange(lower->lower(), lower_up);
359 ranges_.erase(std::next(lower), upper);
366 template <
typename Key2>
372 template <
typename K,
typename = std::enable_if_t<std::is_arithmetic_v<K>>>
373 size_type erase(K key)
378 template <
typename K,
typename = std::enable_if_t<std::is_arithmetic_v<K>>>
379 size_type erase(K lower, K upper)
381 return erase(
key_type(lower, upper));
384 void swap(
RangeSet& other)
noexcept(
385 std::allocator_traits<allocator_type>::is_always_equal::value &&
386 std::is_nothrow_move_assignable<value_compare>::value)
389 ranges_.swap(other.ranges_);
409 [[nodiscard]] size_type count(
key_type key)
const {
return contains(key) ? 1 : 0; }
411 template <
typename Key2>
417 template <
typename K,
typename = std::enable_if_t<std::is_arithmetic_v<K>>>
418 [[nodiscard]] size_type count(K key)
423 template <
typename K,
typename = std::enable_if_t<std::is_arithmetic_v<K>>>
424 [[nodiscard]] size_type count(K lower, K upper)
426 return count(
key_type(lower, upper));
431 auto lower = lower_bound(key);
433 return end() != lower && lower->lower() <= key.
lower() &&
439 template <
typename Key2>
445 template <
typename K,
typename = std::enable_if_t<std::is_arithmetic_v<K>>>
451 template <
typename K,
typename = std::enable_if_t<std::is_arithmetic_v<K>>>
452 iterator find(K lower, K upper)
454 return find(
key_type(lower, upper));
457 const_iterator find(
key_type key)
const
459 auto lower = lower_bound(key);
461 return end() != lower && lower->lower() <= key.
lower() &&
467 template <
typename Key2>
473 template <
typename K,
typename = std::enable_if_t<std::is_arithmetic_v<K>>>
474 const_iterator find(K key)
const
479 template <
typename K,
typename = std::enable_if_t<std::is_arithmetic_v<K>>>
480 const_iterator find(K lower, K upper)
const
482 return find(
key_type(lower, upper));
485 [[nodiscard]]
bool contains(
key_type key)
const
487 auto lower = lower_bound(key);
488 return end() != lower && lower->lower() <= key.
lower() &&
492 template <
typename Key2>
498 template <
typename K,
typename = std::enable_if_t<std::is_arithmetic_v<K>>>
499 [[nodiscard]]
bool contains(K key)
const
504 template <
typename K,
typename = std::enable_if_t<std::is_arithmetic_v<K>>>
505 [[nodiscard]]
bool contains(K lower, K upper)
const
507 return contains(
key_type(lower, upper));
510 [[nodiscard]] std::pair<iterator, iterator> equal_range(
key_type key)
512 typename value_compare::range_t
const s_range{key.
lower(), key.
upper()};
513 return std::equal_range(begin(), end(), s_range, comp_);
516 template <
typename Key2>
517 [[nodiscard]] std::pair<iterator, iterator> equal_range(
Range<Key2> key)
522 template <
typename K,
typename = std::enable_if_t<std::is_arithmetic_v<K>>>
523 [[nodiscard]] std::pair<iterator, iterator> equal_range(K key)
528 template <
typename K,
typename = std::enable_if_t<std::is_arithmetic_v<K>>>
529 [[nodiscard]] std::pair<iterator, iterator> equal_range(K lower, K upper)
531 return equal_range(
key_type(lower, upper));
534 [[nodiscard]] std::pair<const_iterator, const_iterator> equal_range(
key_type key)
const
536 typename value_compare::range_t
const s_range{key.
lower(), key.
upper()};
537 return std::equal_range(begin(), end(), s_range, comp_);
540 template <
typename Key2>
541 [[nodiscard]] std::pair<const_iterator, const_iterator> equal_range(
547 template <
typename K,
typename = std::enable_if_t<std::is_arithmetic_v<K>>>
548 [[nodiscard]] std::pair<const_iterator, const_iterator> equal_range(K key)
const
553 template <
typename K,
typename = std::enable_if_t<std::is_arithmetic_v<K>>>
554 [[nodiscard]] std::pair<const_iterator, const_iterator> equal_range(K lower,
557 return equal_range(
key_type(lower, upper));
560 [[nodiscard]] iterator lower_bound(
key_type key)
562 typename key_compare::range_t
const s_range{key.
lower(), key.
upper()};
563 return std::lower_bound(begin(), end(), s_range, comp_);
566 template <
typename Key2>
567 [[nodiscard]] iterator lower_bound(
Range<Key2> key)
572 template <
typename K,
typename = std::enable_if_t<std::is_arithmetic_v<K>>>
573 [[nodiscard]] iterator lower_bound(K key)
578 template <
typename K,
typename = std::enable_if_t<std::is_arithmetic_v<K>>>
579 [[nodiscard]] iterator lower_bound(K lower, K upper)
581 return lower_bound(
key_type(lower, upper));
584 [[nodiscard]] const_iterator lower_bound(
key_type key)
const
586 typename key_compare::range_t
const s_range{key.
lower(), key.
upper()};
587 return std::lower_bound(begin(), end(), s_range, comp_);
590 template <
typename Key2>
591 [[nodiscard]] const_iterator lower_bound(
Range<Key2> key)
const
596 template <
typename K,
typename = std::enable_if_t<std::is_arithmetic_v<K>>>
597 [[nodiscard]] const_iterator lower_bound(K key)
const
602 template <
typename K,
typename = std::enable_if_t<std::is_arithmetic_v<K>>>
603 [[nodiscard]] const_iterator lower_bound(K lower, K upper)
const
605 return lower_bound(
key_type(lower, upper));
608 [[nodiscard]] iterator upper_bound(
key_type key)
610 typename key_compare::range_t
const s_range{key.
lower(), key.
upper()};
611 return std::upper_bound(begin(), end(), s_range, comp_);
614 template <
typename Key2>
615 [[nodiscard]] iterator upper_bound(
Range<Key2> key)
620 template <
typename K,
typename = std::enable_if_t<std::is_arithmetic_v<K>>>
621 [[nodiscard]] iterator upper_bound(K key)
626 template <
typename K,
typename = std::enable_if_t<std::is_arithmetic_v<K>>>
627 [[nodiscard]] iterator upper_bound(K lower, K upper)
629 return upper_bound(
key_type(lower, upper));
632 [[nodiscard]] const_iterator upper_bound(
key_type key)
const
634 typename key_compare::range_t
const s_range{key.
lower(), key.
upper()};
635 return std::upper_bound(begin(), end(), s_range, comp_);
638 template <
typename Key2>
639 [[nodiscard]] const_iterator upper_bound(
Range<Key2> key)
const
644 template <
typename K,
typename = std::enable_if_t<std::is_arithmetic_v<K>>>
645 [[nodiscard]] const_iterator upper_bound(K key)
const
650 template <
typename K,
typename = std::enable_if_t<std::is_arithmetic_v<K>>>
651 [[nodiscard]] const_iterator upper_bound(K lower, K upper)
const
653 return upper_bound(
key_type(lower, upper));
660 std::ostream& writeData(std::ostream& out_stream)
const
662 size_type num = numRanges();
663 out_stream.write(
reinterpret_cast<char*
>(&num),
sizeof(size_type));
666 return out_stream.write(
reinterpret_cast<char*
>(ranges_.data()),
670 std::istream& readData(std::istream& in_stream)
673 in_stream.read(
reinterpret_cast<char*
>(&num),
sizeof(size_type));
681 return in_stream.read(
reinterpret_cast<char*
>(ranges_.data()),
689 key_compare key_comp()
const {
return comp_; }
691 value_compare value_comp()
const {
return comp_; }
697 template <
typename K>
699 template <
typename K>
701 template <
typename K>
703 template <
typename K>
705 template <
typename K>
707 template <
typename K>
710 template <
typename K>
713 template <
typename K,
class Pred>
714 friend size_type erase_if(
RangeSet<K>& range_set, Pred pred);
716 template <
typename K>
717 friend std::ostream& operator<<(std::ostream& os,
RangeSet<K> const& range_set);
720 static constexpr Key increment(Key value)
722 if constexpr (std::is_floating_point_v<Key>) {
723 return std::nextafter(value, std::numeric_limits<Key>::max());
725 return std::max(value, value + 1);
729 static constexpr Key decrement(Key value)
731 if constexpr (std::is_floating_point_v<Key>) {
732 return std::nextafter(value, std::numeric_limits<Key>::lowest());
734 return std::min(value, value - 1);
739 std::vector<value_type> ranges_;