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

int-set-1.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, 2003
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 #include <sstream>
00035 
00036 namespace Gecode {
00037 
00038   /*
00039    * Integer sets
00040    *
00041    */
00042   forceinline
00043   IntSet::IntSet(void) {}
00044 
00052   template<class I>
00053   class IntSetInit {
00054   public:
00056     static void init(IntSet& s, I& i) {
00057       Region reg;
00058       Support::DynamicArray<IntSet::Range,Region> d(reg);
00059       int n=0;
00060       unsigned int size = 0;
00061       while (i()) {
00062         d[n].min = i.min(); d[n].max = i.max(); size += i.width();
00063         ++n; ++i;
00064       }
00065       if (n > 0) {
00066         IntSet::IntSetObject* o = IntSet::IntSetObject::allocate(n);
00067         for (int j=0; j<n; j++)
00068           o->r[j]=d[j];
00069         o->size = size;
00070         s.object(o);
00071       }
00072     }
00073   };
00074 
00076   template<>
00077   class IntSetInit<IntSet> {
00078   public:
00079     static void init(IntSet& s, const IntSet& i) {
00080       s.object(i.object());
00081     }
00082   };
00083 
00085   template<class I>
00086   IntSet::IntSet(I& i) {
00087     IntSetInit<I>::init(*this,i);
00088   }
00089 
00091   template<class I>
00092   IntSet::IntSet(const I& i) {
00093     IntSetInit<I>::init(*this,i);
00094   }
00095 
00096   forceinline
00097   IntSet::IntSet(const int r[][2], int n) {
00098     if (n > 0)
00099       init(r,n);
00100   }
00101 
00102   forceinline
00103   IntSet::IntSet(const int r[], int n) {
00104     if (n > 0)
00105       init(r,n);
00106   }
00107 
00109   template<>
00110   inline
00111   IntSet::IntSet(const std::vector<int>& r) {
00112     int n = static_cast<int>(r.size());
00113     if (n > 0) {
00114       Region reg;
00115       Range* dr = reg.alloc<Range>(n);
00116       for (int i=0; i<n; i++)
00117         dr[i].min=dr[i].max=r[static_cast<unsigned int>(i)];
00118       normalize(&dr[0],n);
00119     }
00120   }
00121 
00127   template<>
00128   inline
00129   IntSet::IntSet(const std::vector<std::pair<int,int>>& r) {
00130     int n = static_cast<int>(r.size());
00131     if (n > 0) {
00132       Region reg;
00133       Range* dr = reg.alloc<Range>(n);
00134       int j=0;
00135       for (int i=0; i<n; i++) 
00136         if (r[static_cast<unsigned int>(i)].first <= 
00137             r[static_cast<unsigned int>(i)].second) {
00138           dr[j].min=r[static_cast<unsigned int>(i)].first;
00139           dr[j].max=r[static_cast<unsigned int>(i)].second;
00140           j++;
00141         }
00142       normalize(&dr[0],j);
00143     }
00144   }
00145 
00146   forceinline
00147   IntSet::IntSet(int n, int m) {
00148     init(n,m);
00149   }
00150 
00151   forceinline int
00152   IntSet::min(int i) const {
00153     assert(object() != NULL);
00154     return static_cast<IntSetObject*>(object())->r[i].min;
00155   }
00156 
00157   forceinline int
00158   IntSet::max(int i) const {
00159     assert(object() != NULL);
00160     return static_cast<IntSetObject*>(object())->r[i].max;
00161   }
00162 
00163   forceinline unsigned int
00164   IntSet::width(int i) const {
00165     assert(object() != NULL);
00166     IntSetObject* o = static_cast<IntSetObject*>(object());
00167     return static_cast<unsigned int>(o->r[i].max-o->r[i].min)+1;
00168   }
00169 
00170   forceinline int
00171   IntSet::ranges(void) const {
00172     IntSetObject* o = static_cast<IntSetObject*>(object());
00173     return (o == NULL) ? 0 : o->n;
00174   }
00175 
00176   forceinline bool
00177   IntSet::in(int n) const {
00178     IntSetObject* o = static_cast<IntSetObject*>(object());
00179     if ((o == NULL) || (n < o->r[0].min) || (n > o->r[o->n-1].max))
00180       return false;
00181     else
00182       return o->in(n);
00183   }
00184 
00185   forceinline int
00186   IntSet::min(void) const {
00187     IntSetObject* o = static_cast<IntSetObject*>(object());
00188     return (o == NULL) ? Int::Limits::max : o->r[0].min;
00189   }
00190 
00191   forceinline int
00192   IntSet::max(void) const {
00193     IntSetObject* o = static_cast<IntSetObject*>(object());
00194     return (o == NULL) ? Int::Limits::min : o->r[o->n-1].max;
00195   }
00196 
00197   forceinline unsigned int
00198   IntSet::size(void) const {
00199     IntSetObject* o = static_cast<IntSetObject*>(object());
00200     return (o == NULL) ? 0U : o->size;
00201   }
00202 
00203   forceinline unsigned int
00204   IntSet::width(void) const {
00205     IntSetObject* o = static_cast<IntSetObject*>(object());
00206     return (o == NULL) ? 0U : static_cast<unsigned int>(max()-min()+1);
00207   }
00208 
00209   forceinline bool
00210   IntSet::operator ==(const IntSet& s) const {
00211     IntSetObject* o1 = static_cast<IntSetObject*>(object());
00212     IntSetObject* o2 = static_cast<IntSetObject*>(s.object());
00213     if (o1 == o2)
00214       return true;
00215     if ((o1 == nullptr) || (o2 == nullptr))
00216       return false;
00217     if ((o1->size != o2->size) || (o1->n != o2->n))
00218       return false;
00219     return o1->equal(*o2);
00220   }
00221 
00222   forceinline bool
00223   IntSet::operator !=(const IntSet& s) const {
00224     return !(*this == s);
00225   }
00226 
00227 
00228   /*
00229    * Range iterator for integer sets
00230    *
00231    */
00232 
00233   forceinline
00234   IntSetRanges::IntSetRanges(void) {}
00235   forceinline
00236   void
00237   IntSetRanges::init(const IntSet& s) {
00238     int n = s.ranges();
00239     if (n > 0) {
00240       i = &static_cast<IntSet::IntSetObject*>(s.object())->r[0]; e = i+n;
00241     } else {
00242       i = e = NULL;
00243     }
00244   }
00245   forceinline
00246   IntSetRanges::IntSetRanges(const IntSet& s) { init(s); }
00247 
00248 
00249   forceinline void
00250   IntSetRanges::operator ++(void) {
00251     i++;
00252   }
00253   forceinline bool
00254   IntSetRanges::operator ()(void) const {
00255     return i<e;
00256   }
00257 
00258   forceinline int
00259   IntSetRanges::min(void) const {
00260     return i->min;
00261   }
00262   forceinline int
00263   IntSetRanges::max(void) const {
00264     return i->max;
00265   }
00266   forceinline unsigned int
00267   IntSetRanges::width(void) const {
00268     return static_cast<unsigned int>(i->max - i->min) + 1;
00269   }
00270 
00271   /*
00272    * Value iterator for integer sets
00273    *
00274    */
00275   forceinline
00276   IntSetValues::IntSetValues(void) {}
00277 
00278   forceinline
00279   IntSetValues::IntSetValues(const IntSet& s) {
00280     IntSetRanges r(s);
00281     Iter::Ranges::ToValues<IntSetRanges>::init(r);
00282   }
00283 
00284   forceinline void
00285   IntSetValues::init(const IntSet& s) {
00286     IntSetRanges r(s);
00287     Iter::Ranges::ToValues<IntSetRanges>::init(r);
00288   }
00289 
00290   template<class Char, class Traits>
00291   std::basic_ostream<Char,Traits>&
00292   operator <<(std::basic_ostream<Char,Traits>& os, const IntSet& is) {
00293     std::basic_ostringstream<Char,Traits> s;
00294     s.copyfmt(os); s.width(0);
00295     s << '{';
00296     for (int i = 0; i < is.ranges(); ) {
00297       int min = is.min(i);
00298       int max = is.max(i);
00299       if (min == max)
00300         s << min;
00301       else
00302         s << min << ".." << max;
00303       i++;
00304       if (i < is.ranges())
00305         s << ',';
00306     }
00307     s << '}';
00308     return os << s.str();
00309   }
00310 
00311 }
00312 
00313 // STATISTICS: int-var
00314