int-set-1.hpp
Go to the documentation of this file.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
00027
00028
00029
00030
00031
00032
00033
00034 #include <sstream>
00035
00036 namespace Gecode {
00037
00038
00039
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
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
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
00314