00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef __CONSECUTIVE_SET__H__
00017 #define __CONSECUTIVE_SET__H__
00018
00019 #include <iostream>
00020 #include <set>
00021 #include <assert.h>
00022
00025
00026 template<typename T>
00027 class consecutive_set {
00028 private:
00029
00032 class subset_t {
00033 private:
00034 T start;
00035 T end;
00036 public:
00037 subset_t(T _start, T _end);
00038
00039 bool operator<(const subset_t& cmp) const;
00040 T size() const;
00041 const T& get_start() const;
00042 const T& get_end() const;
00043 void set_start(T _start);
00044 void set_end(T _end);
00045 void clear();
00046 };
00047
00048 typedef typename std::set<subset_t>::iterator iter_t;
00049 typedef typename std::set<subset_t>::const_iterator const_iter_t;
00050 std::set<subset_t> subsets;
00051 T num_elements;
00052
00053 iter_t prev_iter(iter_t iter) const;
00054 iter_t next_iter(iter_t iter) const;
00055 void subset_erase(iter_t subset);
00056 void subset_insert(const subset_t& subset);
00057 void subset_insert_at(iter_t pos, const subset_t& subset);
00058 void subset_insert_at_end(const subset_t& subset);
00059 void subset_change(iter_t subset, T start, T end);
00060 void subset_symdiff(iter_t subset, T start, T end);
00061
00062 public:
00065 consecutive_set();
00066
00070 consecutive_set(T start, T end);
00071
00074 void swap(consecutive_set& set);
00075
00079 std::ostream& print(std::ostream& os) const;
00080
00083 bool is_consistent() const;
00084
00089 consecutive_set sum(const consecutive_set& set) const;
00090
00094 void sum_update(const consecutive_set& set);
00095
00100 consecutive_set intersection(const consecutive_set& set) const;
00101
00105 void intersection_update(const consecutive_set& set);
00106
00111 consecutive_set diff(const consecutive_set& set) const;
00112
00117 void diff_update(const consecutive_set& set);
00118
00123 consecutive_set symdiff(const consecutive_set& set) const;
00124
00129 void symdiff_update(const consecutive_set& set);
00130
00136 bool is_subset(const consecutive_set& set) const;
00137
00143 bool is_superset(const consecutive_set& set) const;
00144
00149 void add(T value);
00150
00155 void remove(T value);
00156
00160 bool contains(T value) const;
00161
00165 class empty_set_exception : public std::exception {
00166 public:
00169 virtual const char *what() const throw() {
00170 return "Set is empty";
00171 }
00172 };
00173
00178 T pop();
00179
00186 T pop(const consecutive_set& constraints);
00187
00193 consecutive_set pop(T num_values);
00194
00201 consecutive_set pop(T num_values, const consecutive_set& constraints);
00202
00207 T pop_back();
00208
00215 T pop_back(const consecutive_set& constraints);
00216
00222 consecutive_set pop_back(T num_values);
00223
00230 consecutive_set pop_back(T num_values, const consecutive_set& constraints);
00231
00234 void clear();
00235
00238 T size() const;
00239
00242 bool operator<=(const consecutive_set& set) const;
00245 bool operator>=(const consecutive_set& set) const;
00248 consecutive_set& operator|=(const consecutive_set& set);
00251 consecutive_set& operator|=(T value);
00254 consecutive_set operator|(const consecutive_set& set) const;
00257 consecutive_set& operator&=(const consecutive_set& set);
00260 consecutive_set operator&(const consecutive_set& set) const;
00263 consecutive_set& operator-=(const consecutive_set& set);
00266 consecutive_set& operator-=(T value);
00269 consecutive_set operator-(const consecutive_set& set) const;
00272 consecutive_set& operator^=(const consecutive_set& set);
00275 consecutive_set operator^(const consecutive_set& set) const;
00276 };
00277
00278 template<typename T>
00279 consecutive_set<T>::subset_t::subset_t(T _start, T _end) : start(_start), end(_end) {
00280 assert(end >= start);
00281 }
00282
00283 template<typename T>
00284 inline bool consecutive_set<T>::subset_t::operator<(const subset_t& cmp) const {
00285 return start < cmp.start;
00286 }
00287
00288 template<typename T>
00289 inline T consecutive_set<T>::subset_t::size() const {
00290 return end - start;
00291 }
00292
00293 template<typename T>
00294 inline const T& consecutive_set<T>::subset_t::get_start() const {
00295 return start;
00296 }
00297
00298 template<typename T>
00299 inline const T& consecutive_set<T>::subset_t::get_end() const {
00300 return end;
00301 }
00302
00303 template<typename T>
00304 inline void consecutive_set<T>::subset_t::set_start(T _start) {
00305 start = _start;
00306 }
00307
00308 template<typename T>
00309 inline void consecutive_set<T>::subset_t::set_end(T _end) {
00310 end = _end;
00311 }
00312
00313 template<typename T>
00314 inline void consecutive_set<T>::subset_t::clear() {
00315 start = end = 0;
00316 }
00317
00318 template<typename T>
00319 inline typename consecutive_set<T>::iter_t consecutive_set<T>::prev_iter(iter_t iter) const {
00320 return --iter;
00321 }
00322
00323 template<typename T>
00324 inline typename consecutive_set<T>::iter_t consecutive_set<T>::next_iter(iter_t iter) const {
00325 return ++iter;
00326 }
00327
00328 template<typename T>
00329 void consecutive_set<T>::subset_erase(iter_t subset) {
00330 num_elements -= subset->size();
00331 subsets.erase(subset);
00332 }
00333
00334 template<typename T>
00335 void consecutive_set<T>::subset_insert(const subset_t& subset) {
00336 num_elements += subset.size();
00337 subsets.insert(subset);
00338 }
00339
00340 template<typename T>
00341 void consecutive_set<T>::subset_insert_at(iter_t pos, const subset_t& subset) {
00342 num_elements += subset.size();
00343 subsets.insert(pos, subset);
00344 }
00345
00346 template<typename T>
00347 inline void consecutive_set<T>::subset_insert_at_end(const subset_t& subset) {
00348 subset_insert_at(subsets.end(), subset);
00349 }
00350
00351 template<typename T>
00352 void consecutive_set<T>::subset_change(iter_t subset, T start, T end) {
00353 subset_t new_subset(start, end);
00354 num_elements += new_subset.size() - subset->size();
00355 subsets.erase(subset++);
00356 subsets.insert(subset, new_subset);
00357 }
00358
00359 template<typename T>
00360 void consecutive_set<T>::subset_symdiff(iter_t subset, T start, T end) {
00361 subset_t first_new_subset(start < subset->get_start() ? start : subset->get_start(),
00362 start > subset->get_start() ? start : subset->get_start());
00363 subset_t second_new_subset(end < subset->get_end() ? end : subset->get_end(),
00364 end > subset->get_end() ? end : subset->get_end());
00365 num_elements += first_new_subset.size() + second_new_subset.size() - subset->size();
00366 subsets.erase(subset++);
00367 subsets.insert(subset, first_new_subset);
00368 subsets.insert(subset, second_new_subset);
00369 }
00370
00371 template<typename T>
00372 consecutive_set<T>::consecutive_set() : num_elements(0) {
00373 }
00374
00375 template<typename T>
00376 consecutive_set<T>::consecutive_set(T start, T end) : num_elements(0) {
00377 assert(start <= end);
00378 subset_insert(subset_t(start, end + 1));
00379 }
00380
00381 template<typename T>
00382 void consecutive_set<T>::swap(consecutive_set& set) {
00383 T tmp_num_elements = num_elements;
00384 num_elements = set.num_elements;
00385 set.num_elements = tmp_num_elements;
00386 subsets.swap(set.subsets);
00387 }
00388
00389 template<typename T>
00390 std::ostream& consecutive_set<T>::print(std::ostream& os) const {
00391 os << "Size: " << num_elements << std::endl;
00392 os << "Subsets: ";
00393 iter_t iter(subsets.begin());
00394 const char* separator = "";
00395 while(iter != subsets.end()) {
00396 os << separator << "[" << iter->get_start();
00397 if(iter->get_start() != iter->get_end() - 1)
00398 os << "-" << iter->get_end() - 1;
00399 os << "]";
00400 separator = ", ";
00401 ++iter;
00402 }
00403 os << std::endl;
00404 return os;
00405 }
00406
00407 template<typename T>
00408 bool consecutive_set<T>::is_consistent() const {
00409 T element_count(0);
00410 T last_end = 0;
00411 iter_t iter = subsets.begin();
00412 while(iter != subsets.end()) {
00413 if(iter != subsets.begin() && last_end >= iter->get_start())
00414 return false;
00415 last_end = iter->get_end();
00416 if(iter->get_start() >= iter->get_end())
00417 return false;
00418 element_count += iter->size();
00419 ++iter;
00420 }
00421 if(element_count != size())
00422 return false;
00423
00424 return true;
00425 }
00426
00427 template<typename T>
00428 consecutive_set<T> consecutive_set<T>::sum(const consecutive_set& set) const {
00429 consecutive_set res;
00430 if(&set == this) return (res = *this);
00431 iter_t self_iter(subsets.begin());
00432 iter_t set_iter(set.subsets.begin());
00433 subset_t remainder(0,0);
00434 while(self_iter != subsets.end() || set_iter != set.subsets.end()) {
00435 iter_t& iter =
00436 self_iter == subsets.end() ? set_iter :
00437 set_iter == set.subsets.end() ? self_iter :
00438 self_iter->get_start() < set_iter->get_start() ? self_iter : set_iter;
00439 if(remainder.size() > 0) {
00440 if(iter->get_start() <= remainder.get_end()) {
00441
00442 if(iter->get_end() > remainder.get_end()) {
00443 remainder.set_end(iter->get_end());
00444 }
00445 ++iter;
00446 continue;
00447 }
00448 res.subset_insert_at_end(remainder);
00449 }
00450 remainder = *iter;
00451 ++iter;
00452 };
00453
00454 if(remainder.size())
00455 res.subset_insert_at_end(remainder);
00456
00457 return res;
00458 }
00459
00460 template<typename T>
00461 void consecutive_set<T>::sum_update(const consecutive_set& set) {
00462 if(&set == this) return;
00463 iter_t set_iter(set.subsets.begin());
00464 while(set_iter != set.subsets.end()) {
00465 iter_t iter(subsets.upper_bound(*set_iter));
00466 if(iter != subsets.begin() && prev_iter(iter)->get_end() >= set_iter->get_start()) {
00467
00468 --iter;
00469 } else if(iter == subsets.end() || iter->get_start() > set_iter->get_end()) {
00470
00471 subset_insert_at(iter, *set_iter);
00472 ++set_iter;
00473 continue;
00474 }
00475
00476 T start = iter->get_start() < set_iter->get_start() ? iter->get_start() : set_iter->get_start();
00477 T end = iter->get_end() > set_iter->get_end() ? iter->get_end() : set_iter->get_end();
00478 while(iter != subsets.end() && iter->get_start() <= end) {
00479
00480 if(iter->get_end() > end) {
00481 end = iter->get_end();
00482 }
00483 subset_erase(iter++);
00484 }
00485 subset_insert_at(iter, subset_t(start, end));
00486 ++set_iter;
00487 }
00488 }
00489
00490 template<typename T>
00491 consecutive_set<T> consecutive_set<T>::intersection(const consecutive_set& set) const {
00492 consecutive_set res;
00493 if(&set == this) return (res = *this);
00494 iter_t iter(subsets.begin());
00495 iter_t set_iter(set.subsets.begin());
00496 while(iter != subsets.end() && set_iter != set.subsets.end()) {
00497 if(iter->get_end() <= set_iter->get_start()) {
00498
00499 ++iter;
00500 } else if(set_iter->get_end() <= iter->get_start()) {
00501
00502 ++set_iter;
00503 } else {
00504
00505 T start = iter->get_start() > set_iter->get_start() ? iter->get_start() : set_iter->get_start();
00506 T end = iter->get_end() < set_iter->get_end() ? iter->get_end() : set_iter->get_end();
00507 res.subset_insert_at_end(subset_t(start, end));
00508 if(iter->get_end() <= set_iter->get_end()) {
00509 ++iter;
00510 } else {
00511 ++set_iter;
00512 }
00513 }
00514 }
00515 return res;
00516 }
00517
00518 template<typename T>
00519 void consecutive_set<T>::intersection_update(const consecutive_set& set) {
00520 if(&set == this) return;
00521 iter_t iter(subsets.begin());
00522 while(iter != subsets.end()) {
00523 iter_t set_iter(set.subsets.upper_bound(*iter));
00524 if(set_iter != set.subsets.begin() && prev_iter(set_iter)->get_end() > iter->get_start()) {
00525
00526 --set_iter;
00527 } else if(set_iter == set.subsets.end() || set_iter->get_start() >= iter->get_end()) {
00528
00529 subset_erase(iter++);
00530 continue;
00531 }
00532
00533 T start = iter->get_start();
00534 T end = iter->get_end();
00535 subset_erase(iter++);
00536 while(set_iter != set.subsets.end() && set_iter->get_start() < end) {
00537 subset_t new_subset(start >= set_iter->get_start() ? start : set_iter->get_start(),
00538 end <= set_iter->get_end() ? end : set_iter->get_end());
00539 subset_insert_at(iter, new_subset);
00540 ++set_iter;
00541 }
00542 }
00543 }
00544
00545 template<typename T>
00546 consecutive_set<T> consecutive_set<T>::diff(const consecutive_set& set) const {
00547 consecutive_set res;
00548 if(&set == this) return res;
00549 iter_t iter(subsets.begin());
00550 while(iter != subsets.end()) {
00551 iter_t set_iter(set.subsets.upper_bound(*iter));
00552 if(set_iter != set.subsets.begin() && prev_iter(set_iter)->get_end() > iter->get_start()) {
00553
00554 --set_iter;
00555 } else if(set_iter == set.subsets.end() || set_iter->get_start() >= iter->get_end()) {
00556
00557 res.subset_insert_at_end(*iter);
00558 ++iter;
00559 continue;
00560 }
00561
00562 T start = iter->get_start() < set_iter->get_start() ? iter->get_start() : set_iter->get_end();
00563 T end = iter->get_end();
00564 while(set_iter != set.subsets.end() && set_iter->get_start() < end) {
00565 if(start < set_iter->get_start()) {
00566 res.subset_insert_at_end(subset_t(start, set_iter->get_start()));
00567 start = set_iter->get_end();
00568 }
00569 ++set_iter;
00570 }
00571 if(start < end) {
00572 res.subset_insert_at_end(subset_t(start, end));
00573 }
00574 ++iter;
00575 }
00576 return res;
00577 }
00578
00579 template<typename T>
00580 void consecutive_set<T>::diff_update(const consecutive_set& set) {
00581 if(&set == this) {
00582 clear();
00583 return;
00584 }
00585 iter_t set_iter(set.subsets.begin());
00586 while(set_iter != set.subsets.end()) {
00587 iter_t iter(subsets.upper_bound(*set_iter));
00588 if(iter != subsets.begin() && prev_iter(iter)->get_end() > set_iter->get_start()) {
00589
00590 --iter;
00591 } else if(iter == subsets.end() || iter->get_start() >= set_iter->get_end()) {
00592
00593 ++set_iter;
00594 continue;
00595 }
00596
00597
00598 while(iter != subsets.end() && iter->get_start() < set_iter->get_end()) {
00599
00600 if(iter->get_start() < set_iter->get_start()) {
00601 if(iter->get_end() > set_iter->get_end()) {
00602 subset_symdiff(iter++, set_iter->get_start(), set_iter->get_end());
00603 } else {
00604 subset_change(iter++, iter->get_start(), set_iter->get_start());
00605 }
00606 } else {
00607 if(iter->get_end() > set_iter->get_end()) {
00608 subset_change(iter++, set_iter->get_end(), iter->get_end());
00609 } else {
00610 subset_erase(iter++);
00611 }
00612 }
00613 }
00614 ++set_iter;
00615 }
00616 }
00617
00618 template<typename T>
00619 consecutive_set<T> consecutive_set<T>::symdiff(const consecutive_set& set) const {
00620 consecutive_set res;
00621 if(&set == this) return res;
00622 iter_t self_iter(subsets.begin());
00623 iter_t set_iter(set.subsets.begin());
00624 if(self_iter == subsets.end())
00625 return (res = set);
00626 if(set_iter == set.subsets.end())
00627 return (res = *this);
00628
00629 subset_t remainder(0, 0);
00630 while(self_iter != subsets.end() || set_iter != set.subsets.end()) {
00631 iter_t& iter =
00632 self_iter == subsets.end() ? set_iter :
00633 set_iter == set.subsets.end() ? self_iter :
00634 self_iter->get_start() < set_iter->get_start() ? self_iter : set_iter;
00635
00636 if(remainder.size() > 0) {
00637 if(remainder.get_start() == iter->get_start()) {
00638 if(remainder.get_end() < iter->get_end()) {
00639 remainder = subset_t(remainder.get_end(), iter->get_end());
00640 } else if(remainder.get_end() == iter->get_end()) {
00641 remainder.clear();
00642 } else {
00643 remainder.set_start(iter->get_end());
00644 }
00645 } else {
00646 assert(remainder.get_start() < iter->get_start());
00647 if(remainder.get_end() < iter->get_start()) {
00648 res.subset_insert_at_end(remainder);
00649 remainder = *iter;
00650 } else if(remainder.get_end() == iter->get_start()) {
00651 remainder.set_end(iter->get_end());
00652 } else {
00653 res.subset_insert_at_end(subset_t(remainder.get_start(), iter->get_start()));
00654 remainder.set_start(iter->get_end() < remainder.get_end() ? iter->get_end() : remainder.get_end());
00655 remainder.set_end(iter->get_end() > remainder.get_end() ? iter->get_end() : remainder.get_end());
00656 }
00657 }
00658 } else{
00659 remainder = *iter;
00660 }
00661
00662 ++iter;
00663 }
00664
00665 if (remainder.size() > 0) {
00666 res.subset_insert_at_end(remainder);
00667 }
00668
00669 return res;
00670 }
00671
00672 template<typename T>
00673 void consecutive_set<T>::symdiff_update(const consecutive_set& set) {
00674 if(&set == this) {
00675 clear();
00676 return;
00677 }
00678 iter_t set_iter(set.subsets.begin());
00679 while(set_iter != set.subsets.end()) {
00680 iter_t iter(subsets.upper_bound(*set_iter));
00681 if(iter != subsets.begin() && prev_iter(iter)->get_end() >= set_iter->get_start()) {
00682
00683 --iter;
00684 } else if(iter == subsets.end() || iter->get_start() > set_iter->get_end()) {
00685
00686 subset_insert_at(iter, *(set_iter++));
00687 continue;
00688 }
00689
00690 subset_t remainder(*set_iter);
00691 while(iter != subsets.end() && iter->get_start() <= remainder.get_end()) {
00692 if(iter->get_start() < remainder.get_start()) {
00693 if(iter->get_end() == remainder.get_start()) {
00694 remainder.set_start(iter->get_start());
00695 subset_erase(iter++);
00696 } else if (iter->get_end() < remainder.get_end()) {
00697 T iter_start = iter->get_start();
00698 T iter_end = iter->get_end();
00699 subset_change(iter++, iter_start, remainder.get_start());
00700 remainder.set_start(iter_end);
00701 } else if(iter->get_end() == remainder.get_end()) {
00702 subset_change(iter, iter->get_start(), remainder.get_start());
00703 remainder.clear();
00704 break;
00705 } else {
00706 subset_symdiff(iter, remainder.get_start(), remainder.get_end());
00707 remainder.clear();
00708 break;
00709 }
00710 } else if(iter->get_start() == remainder.get_start()) {
00711 if(iter->get_end() < remainder.get_end()) {
00712 remainder.set_start(iter->get_end());
00713 subset_erase(iter++);
00714 } else if(iter->get_end() == remainder.get_end()) {
00715 subset_erase(iter);
00716 remainder.clear();
00717 break;
00718 } else {
00719 subset_change(iter, remainder.get_end(), iter->get_end());
00720 remainder.clear();
00721 break;
00722 }
00723 } else if(iter->get_start() < remainder.get_end()) {
00724 if(iter->get_end() < remainder.get_end()) {
00725 T iter_end = iter->get_end();
00726 subset_change(iter++, remainder.get_start(), iter->get_start());
00727 remainder.set_start(iter_end);
00728 } else if(iter->get_end() == remainder.get_end()) {
00729 subset_change(iter, remainder.get_start(), iter->get_start());
00730 remainder.clear();
00731 break;
00732 } else {
00733 subset_symdiff(iter, remainder.get_start(), remainder.get_end());
00734 remainder.clear();
00735 break;
00736 }
00737 } else if(iter->get_start() == remainder.get_end()) {
00738 subset_change(iter, remainder.get_start(), iter->get_end());
00739 remainder.clear();
00740 break;
00741 }
00742 }
00743 if(remainder.size() > 0) {
00744 subset_insert_at(iter, remainder);
00745 }
00746 ++set_iter;
00747 }
00748 }
00749
00750 template<typename T>
00751 bool consecutive_set<T>::is_subset(const consecutive_set& set) const {
00752 iter_t iter(subsets.begin());
00753 while(iter != subsets.end()) {
00754 iter_t set_iter(set.subsets.upper_bound(*iter));
00755 if(set_iter != set.subsets.begin() && prev_iter(set_iter)->get_end() > iter->get_start()) {
00756
00757 --set_iter;
00758 } else if(set_iter == set.subsets.end()) {
00759 return false;
00760 }
00761 if (iter->get_start() < set_iter->get_start() || iter->get_end() > set_iter->get_end()) {
00762 return false;
00763 }
00764 ++iter;
00765 }
00766 return true;
00767 }
00768
00769 template<typename T>
00770 bool consecutive_set<T>::is_superset(const consecutive_set& set) const {
00771 iter_t set_iter(set.subsets.begin());
00772 while(set_iter != set.subsets.end()) {
00773 iter_t iter(subsets.upper_bound(*set_iter));
00774 if(iter != subsets.begin() && prev_iter(iter)->get_end() > set_iter->get_start()) {
00775
00776 --iter;
00777 } else if(iter == subsets.end()) {
00778 return false;
00779 }
00780 if(set_iter->get_start() < iter->get_start() || set_iter->get_end() > iter->get_end()) {
00781 return false;
00782 }
00783 ++set_iter;
00784 }
00785 return true;
00786 }
00787
00788 template<typename T>
00789 void consecutive_set<T>::add(T value) {
00790 iter_t iter(subsets.upper_bound(subset_t(value, value)));
00791 if(iter != subsets.begin() && prev_iter(iter)->get_end() >= value) {
00792
00793 --iter;
00794 } else if(iter == subsets.end() || iter->get_start() > (value + 1)) {
00795
00796 subset_insert_at(iter, subset_t(value, value + 1));
00797 return;
00798 }
00799 T start = iter->get_start();
00800 T end = iter->get_end();
00801 if(value == end) {
00802 if(next_iter(iter) != subsets.end() && next_iter(iter)->get_start() == value + 1) {
00803 end = next_iter(iter)->get_end();
00804 subset_erase(next_iter(iter));
00805 subset_change(iter, start, end);
00806 return;
00807 }
00808
00809 ++end;
00810 subset_change(iter, start, end);
00811 return;
00812 }
00813 if(value == (start - 1)) {
00814 subset_change(iter, start - 1, end);
00815 return;
00816 }
00817 assert(value >= iter->get_start() && value < iter->get_end());
00818 }
00819
00820 template<typename T>
00821 void consecutive_set<T>::remove(T value) {
00822 assert(subsets.size() > 0);
00823 iter_t iter(subsets.upper_bound(subset_t(value, value)));
00824 if(iter != subsets.begin() && prev_iter(iter)->get_end() > value) {
00825
00826 --iter;
00827 if(value == iter->get_start()) {
00828 subset_change(iter, value + 1, iter->get_end());
00829 } else if(value == (iter->get_end() - 1)) {
00830 subset_change(iter, iter->get_start(), iter->get_end() - 1);
00831 } else {
00832 subset_symdiff(iter, value, value + 1);
00833 }
00834 return;
00835 }
00836 assert(0 && "Attempting to remove value that doesn't exist in set");
00837 }
00838
00839 template<typename T>
00840 bool consecutive_set<T>::contains(T value) const {
00841 iter_t iter(subsets.upper_bound(subset_t(value, value)));
00842 return iter != subsets.begin() && prev_iter(iter)->get_end() > value;
00843 }
00844
00845 template<typename T>
00846 T consecutive_set<T>::pop() {
00847 if(!num_elements) throw empty_set_exception();
00848 iter_t iter(subsets.begin());
00849 T value = iter->get_start();
00850 assert(iter->size() >= 1);
00851 if(iter->size() > 1) {
00852 T start = value + 1;
00853 T end = iter->get_end();
00854 subset_change(iter, start, end);
00855 } else {
00856 subset_erase(iter);
00857 }
00858 return value;
00859 }
00860
00861 template<typename T>
00862 T consecutive_set<T>::pop(const consecutive_set& constraints) {
00863 iter_t constraints_iter(constraints.subsets.begin());
00864 while(constraints_iter != constraints.subsets.end()) {
00865 iter_t iter(subsets.upper_bound(*constraints_iter));
00866 if(iter != subsets.begin() && prev_iter(iter)->get_end() > constraints_iter->get_start()) {
00867
00868 --iter;
00869 } else if(iter == subsets.end() || iter->get_start() >= constraints_iter->get_end()) {
00870
00871 ++constraints_iter;
00872 continue;
00873 }
00874
00875
00876 if(iter->get_start() < constraints_iter->get_start()) {
00877 T value = constraints_iter->get_start();
00878 if(iter->get_end() > (constraints_iter->get_start() + 1)) {
00879 subset_symdiff(iter, value, value + 1);
00880 } else if(iter->get_end() == (constraints_iter->get_start() + 1)) {
00881 subset_change(iter, iter->get_start(), value);
00882 }
00883 return value;
00884 } else {
00885 T value = iter->get_start();
00886 if(iter->size() > 1) {
00887 subset_change(iter, value + 1, iter->get_end());
00888 } else {
00889 subset_erase(iter);
00890 }
00891 return value;
00892 }
00893 assert(0);
00894 }
00895 throw empty_set_exception();
00896 }
00897
00898 template<typename T>
00899 consecutive_set<T> consecutive_set<T>::pop(T num_values) {
00900 consecutive_set res;
00901 iter_t iter(subsets.begin());
00902 while(num_values > 0 && iter != subsets.end()) {
00903 if(iter->size() > num_values) {
00904 res.subset_insert_at_end(subset_t(iter->get_start(), iter->get_start() + num_values));
00905 subset_change(iter, iter->get_start() + num_values, iter->get_end());
00906 break;
00907 } else if(iter->size() == num_values) {
00908 res.subset_insert_at_end(*iter);
00909 subset_erase(iter);
00910 break;
00911 } else {
00912 res.subset_insert_at_end(*iter);
00913 num_values -= iter->size();
00914 subset_erase(iter++);
00915 }
00916 }
00917 return res;
00918 }
00919
00920 template<typename T>
00921 consecutive_set<T> consecutive_set<T>::pop(T num_values, const consecutive_set& constraints) {
00922 consecutive_set res;
00923 iter_t constraints_iter(constraints.subsets.begin());
00924 while(num_values > 0 && constraints_iter != constraints.subsets.end()) {
00925 iter_t iter(subsets.upper_bound(*constraints_iter));
00926 if(iter != subsets.begin() && prev_iter(iter)->get_end() > constraints_iter->get_start()) {
00927
00928 --iter;
00929 } else if(iter == subsets.end() || iter->get_start() >= constraints_iter->get_end()) {
00930
00931 ++constraints_iter;
00932 continue;
00933 }
00934
00935 while(num_values > 0 && iter!= subsets.end() && iter->get_start() < constraints_iter->get_end()) {
00936
00937 subset_t values(iter->get_start() > constraints_iter->get_start() ? iter->get_start() : constraints_iter->get_start(),
00938 iter->get_end() < constraints_iter->get_end() ? iter->get_end() : constraints_iter->get_end());
00939 if(values.size() > num_values) {
00940 values.set_end(values.get_start() + num_values);
00941 }
00942 num_values -= values.size();
00943 res.subset_insert_at_end(values);
00944 if(iter->get_start() < values.get_start()) {
00945 assert(iter->get_end() >= values.get_end());
00946 if(iter->get_end() > values.get_end()) {
00947 subset_symdiff(iter++, values.get_start(), values.get_end());
00948 } else if(iter->get_end() == values.get_end()) {
00949 subset_change(iter++, iter->get_start(), values.get_start());
00950 }
00951 } else {
00952 if(iter->get_end() > values.get_end()) {
00953 subset_change(iter++, values.get_end(), iter->get_end());
00954 } else {
00955 subset_erase(iter++);
00956 }
00957 }
00958 }
00959 ++constraints_iter;
00960 }
00961 return res;
00962 }
00963
00964 template<typename T>
00965 T consecutive_set<T>::pop_back() {
00966 if(!num_elements) throw empty_set_exception();
00967 iter_t iter(subsets.end());
00968 --iter;
00969 T value(iter->get_end() - 1);
00970 if(iter->size() == 1) {
00971 subset_erase(iter);
00972 } else {
00973 T start = iter->get_start();
00974 T end = value;
00975 subset_change(iter, start, end);
00976 }
00977 return value;
00978 }
00979
00980 template<typename T>
00981 T consecutive_set<T>::pop_back(const consecutive_set& constraints) {
00982 if(constraints.size() == 0)
00983 throw empty_set_exception();
00984 iter_t constraints_iter(constraints.subsets.end());
00985 do {
00986 --constraints_iter;
00987 iter_t iter(subsets.upper_bound(subset_t(constraints_iter->get_end() - 1, constraints_iter->get_end())));
00988 if(iter != subsets.begin() && prev_iter(iter)->get_end() > constraints_iter->get_start()) {
00989
00990 --iter;
00991 } else if(iter == subsets.end() || iter->get_start() >= constraints_iter->get_end()) {
00992
00993 if(constraints_iter != constraints.subsets.begin()) {
00994 continue;
00995 } else {
00996 break;
00997 }
00998 }
00999
01000
01001 assert(iter->size() >= 1);
01002 if(iter->get_end() <= constraints_iter->get_end()) {
01003 T value = iter->get_end() - 1;
01004 if(iter->size() > 1) {
01005 subset_change(iter, iter->get_start(), value);
01006 } else {
01007 subset_erase(iter);
01008 }
01009 return value;
01010 } else {
01011 T value = constraints_iter->get_end() - 1;
01012 assert(iter->size() > 1);
01013 if(value > iter->get_start()) {
01014 subset_symdiff(iter, value, value + 1);
01015 } else {
01016 subset_change(iter, value + 1, iter->get_end());
01017 }
01018 return value;
01019 }
01020 } while(constraints_iter != constraints.subsets.begin());
01021 throw empty_set_exception();
01022 }
01023
01024 template<typename T>
01025 consecutive_set<T> consecutive_set<T>::pop_back(T num_values) {
01026 consecutive_set res;
01027 iter_t iter(subsets.end());
01028 while(num_values > 0 && subsets.begin() != subsets.end()) {
01029 iter_t iter(subsets.end());
01030 --iter;
01031 if(iter->size() > num_values) {
01032 res.subset_insert_at(subsets.begin(), subset_t(iter->get_end() - num_values, iter->get_end()));
01033 subset_change(iter, iter->get_start(), iter->get_end() - num_values);
01034 break;
01035 } else if(iter->size() == num_values) {
01036 res.subset_insert_at(subsets.begin(), *iter);
01037 subset_erase(iter);
01038 break;
01039 } else {
01040 res.subset_insert_at(subsets.begin(), *iter);
01041 num_values -= iter->size();
01042 subset_erase(iter);
01043 }
01044 }
01045
01046 return res;
01047 }
01048
01049 template<typename T>
01050 consecutive_set<T> consecutive_set<T>::pop_back(T num_values, const consecutive_set& constraints) {
01051 consecutive_set res;
01052 if(num_values == 0 || constraints.size() == 0)
01053 return res;
01054 iter_t constraints_iter(constraints.subsets.end());
01055 do {
01056 --constraints_iter;
01057 iter_t iter(subsets.upper_bound(subset_t(constraints_iter->get_end() - 1, constraints_iter->get_end())));
01058 if(iter != subsets.begin() && prev_iter(iter)->get_end() > constraints_iter->get_start()) {
01059
01060 --iter;
01061 } else if(iter == subsets.end() || iter->get_start() >= constraints_iter->get_end()) {
01062
01063 if(constraints_iter != constraints.subsets.begin()) {
01064 continue;
01065 } else {
01066 break;
01067 }
01068 }
01069
01070 do {
01071
01072 assert(iter->size() >= 1);
01073 subset_t values(iter->get_start() > constraints_iter->get_start() ? iter->get_start() : constraints_iter->get_start(),
01074 iter->get_end() < constraints_iter->get_end() ? iter->get_end() : constraints_iter->get_end());
01075 if(values.size() > num_values) {
01076 values.set_start(values.get_end() - num_values);
01077 }
01078 num_values -= values.size();
01079 res.subset_insert_at_end(values);
01080 if(iter->get_start() < values.get_start()) {
01081 assert(iter->get_end() >= values.get_end());
01082 if(iter->get_end() > values.get_end()) {
01083 subset_symdiff(iter++, values.get_start(), values.get_end());
01084 --iter;
01085 } else if(iter->get_end() == values.get_end()) {
01086 subset_change(iter++, iter->get_start(), values.get_start());
01087 }
01088 } else {
01089 if(iter->get_end() > values.get_end()) {
01090 subset_change(iter++, values.get_end(), iter->get_end());
01091 } else {
01092 subset_erase(iter++);
01093 }
01094 }
01095 --iter;
01096 } while(num_values > 0 && iter != subsets.begin() && (--iter)->get_end() > constraints_iter->get_start());
01097 } while(num_values > 0 && constraints_iter != constraints.subsets.begin());
01098
01099 return res;
01100 }
01101
01102 template<typename T>
01103 void consecutive_set<T>::clear() {
01104 subsets.clear();
01105 num_elements = 0;
01106 }
01107
01108 template<typename T>
01109 inline T consecutive_set<T>::size() const {
01110 return num_elements;
01111 }
01112
01113 template<typename T>
01114 inline bool consecutive_set<T>::operator<=(const consecutive_set& set) const {
01115 return is_subset(set);
01116 }
01117
01118 template<typename T>
01119 inline bool consecutive_set<T>::operator>=(const consecutive_set& set) const {
01120 return is_superset(set);
01121 }
01122
01123 template<typename T>
01124 inline consecutive_set<T>& consecutive_set<T>::operator|=(const consecutive_set& set) {
01125 sum_update(set);
01126 return *this;
01127 }
01128
01129 template<typename T>
01130 inline consecutive_set<T>& consecutive_set<T>::operator|=(T value) {
01131 add(value);
01132 return *this;
01133 }
01134
01135 template<typename T>
01136 inline consecutive_set<T> consecutive_set<T>::operator|(const consecutive_set& set) const {
01137 return sum(set);
01138 }
01139
01140 template<typename T>
01141 inline consecutive_set<T>& consecutive_set<T>::operator&=(const consecutive_set& set) {
01142 intersection_update(set);
01143 return *this;
01144 }
01145
01146 template<typename T>
01147 inline consecutive_set<T> consecutive_set<T>::operator&(const consecutive_set& set) const {
01148 return intersection(set);
01149 }
01150
01151 template<typename T>
01152 inline consecutive_set<T>& consecutive_set<T>::operator-=(const consecutive_set& set) {
01153 diff_update(set);
01154 return *this;
01155 }
01156
01157 template<typename T>
01158 inline consecutive_set<T>& consecutive_set<T>::operator-=(T value) {
01159 remove(value);
01160 return *this;
01161 }
01162
01163 template<typename T>
01164 inline consecutive_set<T> consecutive_set<T>::operator-(const consecutive_set& set) const {
01165 return diff(set);
01166 }
01167
01168 template<typename T>
01169 inline consecutive_set<T>& consecutive_set<T>::operator^=(const consecutive_set& set) {
01170 symdiff_update(set);
01171 return *this;
01172 }
01173
01174 template<typename T>
01175 inline consecutive_set<T> consecutive_set<T>::operator^(const consecutive_set& set) const {
01176 return symdiff(set);
01177 }
01178
01179 template<typename T>
01180 inline std::ostream& operator<<(std::ostream& os, const consecutive_set<T>& set) {
01181 return set.print(os);
01182 }
01183
01184 #endif // __CONSECUTIVE_SET__H__