Generated on Thu Apr 11 13:59:12 2019 for Gecode by doxygen 1.6.3

val-set.hpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Christian Schulte, 2011
00008  *
00009  *  This file is part of Gecode, the generic constraint
00010  *  development environment:
00011  *     http://www.gecode.org
00012  *
00013  *  Permission is hereby granted, free of charge, to any person obtaining
00014  *  a copy of this software and associated documentation files (the
00015  *  "Software"), to deal in the Software without restriction, including
00016  *  without limitation the rights to use, copy, modify, merge, publish,
00017  *  distribute, sublicense, and/or sell copies of the Software, and to
00018  *  permit persons to whom the Software is furnished to do so, subject to
00019  *  the following conditions:
00020  *
00021  *  The above copyright notice and this permission notice shall be
00022  *  included in all copies or substantial portions of the Software.
00023  *
00024  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00025  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00026  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00027  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00028  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00029  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00030  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00031  *
00032  */
00033 
00034 namespace Gecode { namespace Int {
00035 
00036   /*
00037    * Value sets
00038    *
00039    */
00040   forceinline
00041   ValSet::ValSet(void)
00042     : fst(NULL), lst(NULL), n(0) {}
00043 
00044   forceinline void
00045   ValSet::add(Space& home, int v) {
00046     RangeList*  c = fst;
00047     RangeList** p = &fst;
00048     while (c != NULL) {
00049       if (v < c->min()) {
00050         if (v+1 == c->min()) {
00051           c->min(v); n++;
00052           return;
00053         } else {
00054           *p = new (home) RangeList(v,v,c); n++;
00055           return;
00056         }
00057       } else if (v <= c->max()) {
00058         // Value already included
00059         return;
00060       } else if (v == c->max()+1) {
00061         if ((c->next() != NULL) && (v+1 == c->next()->min())) {
00062           c->next()->min(c->min());
00063           *p = c->next();
00064           c->dispose(home,c);
00065         } else {
00066           c->max(v);
00067         }
00068         n++;
00069         return;
00070       } else {
00071         // FIXME: HOW TO CAST HERE?
00072         p = reinterpret_cast<RangeList**>(c->nextRef());
00073         c = *p;
00074       }
00075     }
00076     *p = new (home) RangeList(v,v,NULL); n++;
00077     lst = *p;
00078   }
00079 
00080   forceinline int
00081   ValSet::size(void) const {
00082     return n;
00083   }
00084 
00085   forceinline bool
00086   ValSet::empty(void) const {
00087     return n == 0;
00088   }
00089 
00090   forceinline int
00091   ValSet::min(void) const {
00092     return fst->min();
00093   }
00094 
00095   forceinline int
00096   ValSet::max(void) const {
00097     return lst->max();
00098   }
00099 
00100   forceinline void
00101   ValSet::update(Space& home, ValSet& vs) {
00102     if (vs.n > 0) {
00103       n = vs.n;
00104       // Count number of ranges
00105       int m = 0;
00106       for (RangeList* c = vs.fst; c != NULL; c = c->next())
00107         m++;
00108       fst = home.alloc<RangeList>(m);
00109       lst = fst + (m-1);
00110       int i=0;
00111       for (RangeList* c = vs.fst; c != NULL; c = c->next()) {
00112         fst[i].min(c->min()); fst[i].max(c->max());
00113         fst[i].next(fst+i+1);
00114         i++;
00115       }
00116       lst->next(NULL);
00117     }
00118   }
00119 
00120   forceinline void
00121   ValSet::flush(void) {
00122     fst = lst = NULL;
00123   }
00124 
00125   forceinline void
00126   ValSet::dispose(Space& home) {
00127     if (fst != NULL)
00128       fst->dispose(home,lst);
00129   }
00130 
00131   forceinline
00132   ValSet::Ranges::Ranges(const ValSet& vs)
00133     : c(vs.fst) {}
00134 
00135   forceinline bool
00136   ValSet::Ranges::operator ()(void) const {
00137     return c != NULL;
00138   }
00139 
00140   forceinline void
00141   ValSet::Ranges::operator ++(void) {
00142     c = c->next();
00143   }
00144 
00145   forceinline int
00146   ValSet::Ranges::min(void) const {
00147     return c->min();
00148   }
00149   forceinline int
00150   ValSet::Ranges::max(void) const {
00151     return c->max();
00152   }
00153 
00154   forceinline unsigned int
00155   ValSet::Ranges::width(void) const {
00156     return c->width();
00157   }
00158 
00159   template<class View>
00160   forceinline Iter::Ranges::CompareStatus
00161   ValSet::compare(View x) const {
00162     if (empty() || (x.max() < min()) || (x.min() > max()))
00163       return Iter::Ranges::CS_DISJOINT;
00164     ValSet::Ranges vsr(*this);
00165     ViewRanges<View> xr(x);
00166     return Iter::Ranges::compare(xr,vsr);
00167   }
00168 
00169   template<class View>
00170   forceinline bool
00171   ValSet::subset(View x) const {
00172     if (empty() || (x.min() < min()) || (x.max() > max()))
00173       return false;
00174     ValSet::Ranges vsr(*this);
00175     ViewRanges<View> xr(x);
00176     return Iter::Ranges::subset(xr,vsr);
00177   }
00178 
00179 }}
00180 
00181 // STATISTICS: int-other