| 500 | */ |
| 501 | template<class I> |
| 502 | forceinline ModEvent |
| 503 | IntVarImp::narrow_r(Space& home, I& ri, bool depends) { |
| 504 | // Is new domain empty? |
| 505 | if (!ri()) |
| 506 | return fail(home); |
| 507 | |
| 508 | int min0 = ri.min(); |
| 509 | int max0 = ri.max(); |
| 510 | ++ri; |
| 511 | |
| 512 | ModEvent me; |
| 513 | |
| 514 | // Is new domain range? |
| 515 | if (!ri()) { |
| 516 | // Remove possible rangelist (if it was not a range, the domain |
| 517 | // must have been narrowed!) |
| 518 | if (fst()) { |
| 519 | fst()->dispose(home,nullptr,lst()); |
| 520 | fst(nullptr); holes = 0; |
| 521 | } |
| 522 | const int min1 = dom.min(); dom.min(min0); |
| 523 | const int max1 = dom.max(); dom.max(max0); |
| 524 | if ((min0 == min1) && (max0 == max1)) |
| 525 | return ME_INT_NONE; |
| 526 | me = (min0 == max0) ? ME_INT_VAL : ME_INT_BND; |
| 527 | goto notify; |
| 528 | } |
| 529 | |
| 530 | if (depends || range()) { |
| 531 | // Construct new rangelist |
| 532 | RangeList* f = new (home) RangeList(min0,max0,nullptr,nullptr); |
| 533 | RangeList* l = f; |
| 534 | unsigned int s = static_cast<unsigned int>(max0-min0+1); |
| 535 | do { |
| 536 | RangeList* n = new (home) RangeList(ri.min(),ri.max(),l,nullptr); |
| 537 | l->next(nullptr,n); |
| 538 | l = n; |
| 539 | s += ri.width(); |
| 540 | ++ri; |
| 541 | } while (ri()); |
| 542 | if (fst() != nullptr) |
| 543 | fst()->dispose(home,nullptr,lst()); |
| 544 | fst(f); lst(l); |
| 545 | |
| 546 | // Check for modification |
| 547 | if (size() == s) |
| 548 | return ME_INT_NONE; |
| 549 | |
| 550 | const int min1 = dom.min(); min0 = f->min(); dom.min(min0); |
| 551 | const int max1 = dom.max(); max0 = l->max(); dom.max(max0); |
| 552 | holes = width() - s; |
| 553 | |
| 554 | me = ((min0 == min1) && (max0 == max1)) ? ME_INT_DOM : ME_INT_BND; |
| 555 | goto notify; |
| 556 | } else { |
| 557 | // Set up two sentinel elements |
| 558 | RangeList f, l; |
| 559 | // Put all ranges between sentinels |