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