00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 namespace Gecode { namespace Set {
00027
00028
00029
00030
00031
00032
00033 #define GECODE_SET_RL2PD(r) reinterpret_cast<ptrdiff_t>(r)
00034 #define GECODE_SET_PD2RL(p) reinterpret_cast<RangeList*>(p)
00035
00036 forceinline
00037 RangeList::RangeList(void) {}
00038
00039 forceinline
00040 RangeList::RangeList(int min, int max, RangeList* p, RangeList* n)
00041 : _min(min), _max(max) {
00042 _next = GECODE_SET_PD2RL(GECODE_SET_RL2PD(p)^GECODE_SET_RL2PD(n));
00043 }
00044
00045 forceinline RangeList*
00046 RangeList::next(const RangeList* p) const {
00047 return GECODE_SET_PD2RL(GECODE_SET_RL2PD(_next)^GECODE_SET_RL2PD(p));
00048 }
00049 forceinline RangeList*
00050 RangeList::prev(const RangeList* n) const {
00051 return GECODE_SET_PD2RL(GECODE_SET_RL2PD(_next)^GECODE_SET_RL2PD(n));
00052 }
00053 forceinline void
00054 RangeList::prevnext(RangeList* p, RangeList* n) {
00055 _next = GECODE_SET_PD2RL(GECODE_SET_RL2PD(p)^GECODE_SET_RL2PD(n));
00056 }
00057 forceinline void
00058 RangeList::next(RangeList* o, RangeList* n) {
00059 _next = GECODE_SET_PD2RL(GECODE_SET_RL2PD(_next)^
00060 (GECODE_SET_RL2PD(o)^GECODE_SET_RL2PD(n)));
00061 }
00062 forceinline void
00063 RangeList::prev(RangeList* o, RangeList* n) {
00064 _next = GECODE_SET_PD2RL(GECODE_SET_RL2PD(_next)^
00065 (GECODE_SET_RL2PD(o)^GECODE_SET_RL2PD(n)));
00066 }
00067 forceinline void
00068 RangeList::fix(RangeList* n) {
00069 _next = n;
00070 }
00071
00072 forceinline void
00073 RangeList::min(int n) {
00074 _min = n;
00075 }
00076 forceinline void
00077 RangeList::max(int n) {
00078 _max = n;
00079 }
00080
00081 forceinline int
00082 RangeList::min(void) const {
00083 return _min;
00084 }
00085 forceinline int
00086 RangeList::max(void) const {
00087 return _max;
00088 }
00089 forceinline unsigned int
00090 RangeList::width(void) const {
00091 return _max - _min + 1;
00092 }
00093
00094
00095 forceinline void
00096 RangeList::operator delete(void*) {}
00097
00098 forceinline void
00099 RangeList::operator delete(void*, Space* home) {
00100 GECODE_NEVER;
00101 }
00102
00103 forceinline void*
00104 RangeList::operator new(size_t s, Space* home) {
00105 assert(s == sizeof(RangeList));
00106 return home->fl_alloc<sizeof(RangeList)>();
00107 }
00108
00109 forceinline void
00110 RangeList::dispose(Space* home, RangeList* p, RangeList* l) {
00111 RangeList* c = this;
00112 while (c != l) {
00113 RangeList* n = c->next(p);
00114 c->fix(n);
00115 p=c; c=n;
00116 }
00117 home->fl_dispose<sizeof(RangeList)>(this,l);
00118 }
00119
00120 #undef GECODE_SET_RL2PD
00121 #undef GECODE_SET_PD2RL
00122
00123
00124
00125
00126
00127
00128
00129 forceinline
00130 BndSet::BndSet(void) :
00131 first(NULL), last(NULL), _size(0) {}
00132
00133 forceinline RangeList*
00134 BndSet::fst(void) const {
00135 return first;
00136 }
00137
00138 forceinline RangeList*
00139 BndSet::lst(void) const {
00140 return last;
00141 }
00142
00143 forceinline void
00144 BndSet::dispose(Space* home) {
00145 if (fst()!=NULL)
00146 fst()->dispose(home,NULL,lst());
00147 }
00148
00149 forceinline void
00150 BndSet::fst(RangeList* f) {
00151 first = f;
00152 }
00153
00154 forceinline void
00155 BndSet::lst(RangeList* l) {
00156 last = l;
00157 }
00158
00159 forceinline
00160 BndSet::BndSet(Space* home, int mn, int mx) {
00161 RangeList* p =
00162 new (home) RangeList(mn,mx,NULL,NULL);
00163 fst(p); lst(p);
00164 _size = mx-mn+1;
00165 }
00166
00167 forceinline RangeList*
00168 BndSet::ranges(void) const {
00169 return fst();
00170 }
00171
00172 forceinline unsigned int
00173 BndSet::size(void) const {
00174 return _size;
00175 }
00176
00177 forceinline bool
00178 BndSet::empty(void) const {
00179 return (_size==0);
00180 }
00181
00182 forceinline int
00183 BndSet::min(void) const {
00184 if (fst()==NULL) { return MIN_OF_EMPTY; }
00185 else { return fst()->min(); }
00186 }
00187
00188 forceinline int
00189 BndSet::max(void) const {
00190 if (lst()==NULL) { return MAX_OF_EMPTY; }
00191 else { return lst()->max(); }
00192 }
00193
00194
00195 forceinline int
00196 BndSet::minN(unsigned int n) const {
00197 RangeList* p=NULL;
00198 RangeList* c=fst();
00199 while (c!=NULL){
00200 if (c->width() > n){
00201 return(c->min()+n);
00202 } else {
00203 n-=c->width();
00204 RangeList* nc=c->next(p);
00205 p=c; c=nc;
00206 }
00207 }
00208 return MIN_OF_EMPTY;
00209 }
00210
00211
00212 forceinline int
00213 BndSet::maxN(unsigned int n) const {
00214 RangeList* p=NULL;
00215 RangeList* c=lst();
00216 while (c!=NULL){
00217 if (c->width() > n){
00218 return(c->max()-n);
00219 } else {
00220 n-=c->width();
00221 RangeList* nc=c->next(p);
00222 p=c; c=nc;
00223 }
00224 }
00225 return MAX_OF_EMPTY;
00226 }
00227
00228 forceinline void
00229 BndSet::update(Space* home, BndSet& d) {
00230 if ( d.fst() == fst()) { return; }
00231 if (fst()!=NULL) { fst()->dispose(home,NULL,lst()); }
00232 _size = d.size();
00233 if (_size==0) { fst(NULL); lst(NULL); return ; }
00234
00235 int n=0;
00236 {
00237 RangeList* p = NULL;
00238 RangeList* c = d.fst();
00239 while (c!=NULL) {
00240 RangeList* nc=c->next(p);
00241 p=c; c=nc; n++;
00242 }
00243 }
00244
00245 RangeList* r = reinterpret_cast<RangeList*>
00246 (home->alloc(sizeof(RangeList)*n));
00247 fst(r); lst(r+n-1);
00248
00249 {
00250 RangeList* p = NULL;
00251 RangeList* c = d.lst();
00252 for (int i=n; i--; ) {
00253 r[i].min(c->min());
00254 r[i].max(c->max());
00255 r[i].prevnext(&r[i-1],&r[i+1]);
00256
00257 RangeList* nc=c->next(p);
00258 p=c; c=nc;
00259 }
00260 r[0].prev(&r[-1],NULL);
00261 r[n-1].next(&r[n],NULL);
00262 }
00263
00264 }
00265
00266 template <class I> forceinline bool
00267 BndSet::overwrite(Space* home, I& ri) {
00268
00269 if (!ri()) {
00270
00271 if (fst()==NULL)
00272 return false;
00273 fst()->dispose(home,NULL,lst());
00274 _size=0; fst(NULL); lst(NULL);
00275 return true;
00276 }
00277
00278 RangeList* f =
00279 new (home) RangeList(ri.min(),ri.max(),NULL,NULL);
00280 RangeList* l = f;
00281 unsigned int s = ri.width();
00282
00283 ++ri;
00284
00285 while (ri()){
00286 RangeList *n = new (home) RangeList(ri.min(),ri.max(),l,NULL);
00287 l->next(NULL,n);
00288 l=n;
00289 s += ri.width();
00290 ++ri;
00291 }
00292
00293 if (fst() != NULL)
00294 fst()->dispose(home,NULL,lst());
00295 fst(f); lst(l);
00296
00297
00298
00299 if (size() == s)
00300 return false;
00301
00302 _size = s;
00303 return true;
00304 }
00305
00306 forceinline void
00307 BndSet::linkTo(Space* home, const BndSet& that){
00308 if (fst()!=NULL){
00309 assert(lst()!=NULL);
00310 assert(fst()!= that.fst());
00311 fst()->dispose(home,NULL,lst());
00312 }
00313 fst(that.fst());
00314 lst(that.lst());
00315 _size = that.size();
00316 assert(isConsistent());
00317 }
00318
00319 forceinline bool
00320 BndSet::in(int i) const {
00321 RangeList *p = NULL;
00322 RangeList *c = fst();
00323 while (c) {
00324 if (c->min() <= i && c->max() >= i)
00325 return true;
00326 if (c->min() > i)
00327 return false;
00328 RangeList* nc = c->next(p);
00329 p=c; c=nc;
00330 }
00331 return false;
00332 }
00333
00334
00335
00336
00337
00338
00339 forceinline
00340 BndSetRanges::BndSetRanges(void) {}
00341
00342 forceinline
00343 BndSetRanges::BndSetRanges(const BndSet& s) :
00344 p(NULL), c(s.ranges()) {}
00345
00346 forceinline void
00347 BndSetRanges::init(const BndSet& s) {
00348 p = NULL;
00349 c = s.ranges();
00350 }
00351
00352 forceinline bool
00353 BndSetRanges::operator()(void) const {
00354 return c != NULL;
00355 }
00356 forceinline void
00357 BndSetRanges::operator++(void) {
00358 const RangeList* n=c->next(p); p=c; c=n;
00359 }
00360
00361 forceinline int
00362 BndSetRanges::min(void) const {
00363 return c->min();
00364 }
00365 forceinline int
00366 BndSetRanges::max(void) const {
00367 return c->max();
00368 }
00369 forceinline unsigned int
00370 BndSetRanges::width(void) const {
00371 return c->width();
00372 }
00373
00374
00375
00376
00377
00378
00379 forceinline
00380 GLBndSet::GLBndSet(Space* home) {}
00381
00382 forceinline
00383 GLBndSet::GLBndSet(Space* home, int mi, int ma)
00384 : BndSet(home,mi,ma) { assert(mi<=ma); }
00385
00386 forceinline
00387 GLBndSet::GLBndSet(Space* home, const IntSet& s)
00388 : BndSet(home,s) {}
00389
00390 forceinline void
00391 GLBndSet::init(Space* home) { fst(NULL); lst(NULL); _size = 0; }
00392
00393 forceinline bool
00394 GLBndSet::include(Space* home, int mi, int ma) {
00395 assert(ma >= mi);
00396 if (fst()==NULL) {
00397 RangeList* p = new (home) RangeList(mi,ma,NULL,NULL);
00398 fst(p);
00399 lst(p);
00400 _size=ma-mi+1;
00401 return true;
00402 }
00403 bool ret = include_full(home, mi, ma);
00404 assert(isConsistent());
00405 return ret;
00406 }
00407
00408 template <class I> bool
00409 GLBndSet::includeI(Space* home, I& i) {
00410 if (!i())
00411 return false;
00412 BndSetRanges j(*this);
00413 Iter::Ranges::Union<BndSetRanges,I> ij(j,i);
00414 bool me = overwrite(home, ij);
00415 assert(isConsistent());
00416 return me;
00417 }
00418
00419
00420
00421
00422
00423
00424
00425 forceinline
00426 LUBndSet::LUBndSet(void) {}
00427
00428 forceinline
00429 LUBndSet::LUBndSet(Space* home)
00430 : BndSet(home,Limits::Set::int_min,Limits::Set::int_max) {}
00431
00432 forceinline
00433 LUBndSet::LUBndSet(Space* home, int mi, int ma)
00434 : BndSet(home,mi,ma) { assert(mi<=ma); }
00435
00436 forceinline
00437 LUBndSet::LUBndSet(Space* home, const IntSet& s)
00438 : BndSet(home,s) {}
00439
00440 forceinline void
00441 LUBndSet::init(Space* home) {
00442 RangeList *p =
00443 new (home) RangeList(Limits::Set::int_min,
00444 Limits::Set::int_max,
00445 NULL,NULL);
00446 fst(p);
00447 lst(p);
00448 _size = Limits::Set::card_max;
00449 }
00450
00451 forceinline bool
00452 LUBndSet::exclude(Space* home, int mi, int ma) {
00453 assert(ma >= mi);
00454 if ((mi > max()) || (ma < min())) { return false; }
00455 if (mi <= min() && ma >= max() ) {
00456 fst()->dispose(home,NULL,lst()); fst(NULL); lst(NULL);
00457 _size=0;
00458 return true;
00459 }
00460 bool ret = exclude_full(home, mi, ma);
00461 assert(isConsistent());
00462 return ret;
00463 }
00464
00465 template <class I> bool
00466 LUBndSet::intersectI(Space* home, I& i) {
00467 if (fst()==NULL) { return false; }
00468 if (!i()) {
00469 fst()->dispose(home,NULL,lst()); fst(NULL); lst(NULL);
00470 _size=0;
00471 return true;
00472 }
00473 BndSetRanges j(*this);
00474 Iter::Ranges::Inter<BndSetRanges,I> ij(j,i);
00475 bool ret = overwrite(home, ij);
00476 assert(isConsistent());
00477 return ret;
00478 }
00479
00480 template <class I> bool
00481 LUBndSet::excludeI(Space* home, I& i) {
00482 if (!i()) { return false; }
00483 BndSetRanges j(*this);
00484 Iter::Ranges::Diff<BndSetRanges,I> ij(j,i);
00485 bool ret = overwrite(home, ij);
00486 assert(isConsistent());
00487 return ret;
00488 }
00489
00490
00491
00492
00493
00494 template <class I>
00495 RangesCompl<I>::RangesCompl(void) {}
00496
00497 template <class I>
00498 RangesCompl<I>::RangesCompl(I& i)
00499 : Iter::Ranges::Compl<Limits::Set::int_min,
00500 Limits::Set::int_max,
00501 I>(i) {}
00502
00503 template <class I> void
00504 RangesCompl<I>::init(I& i) {
00505 Iter::Ranges::Compl<Limits::Set::int_min,
00506 Limits::Set::int_max,I>::init(i);
00507 }
00508
00509 }}
00510
00511
00512