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
00035
00036
00037
00038 #include <sstream>
00039
00040 namespace Gecode {
00041
00042
00043
00044
00045
00046 forceinline
00047 IntSet::IntSet(void) {}
00048
00056 template<class I>
00057 class IntSetInit {
00058 public:
00060 static void init(IntSet& s, I& i) {
00061 Support::DynamicArray<IntSet::Range,Heap> d(heap);
00062 int n=0;
00063 unsigned int size = 0;
00064 while (i()) {
00065 d[n].min = i.min(); d[n].max = i.max(); size += i.width();
00066 ++n; ++i;
00067 }
00068 if (n > 0) {
00069 IntSet::IntSetObject* o = IntSet::IntSetObject::allocate(n);
00070 for (int j=n; j--; )
00071 o->r[j]=d[j];
00072 o->size = size;
00073 s.object(o);
00074 }
00075 }
00076 };
00077
00079 template<>
00080 class IntSetInit<IntSet> {
00081 public:
00082 static void init(IntSet& s, const IntSet& i) {
00083 s.object(i.object());
00084 }
00085 };
00086
00088 template<class I>
00089 IntSet::IntSet(I& i) {
00090 IntSetInit<I>::init(*this,i);
00091 }
00092
00094 template<class I>
00095 IntSet::IntSet(const I& i) {
00096 IntSetInit<I>::init(*this,i);
00097 }
00098
00099 forceinline
00100 IntSet::IntSet(const int r[][2], int n) {
00101 init(r,n);
00102 }
00103
00104 forceinline
00105 IntSet::IntSet(const int r[], int n) {
00106 init(r,n);
00107 }
00108
00109 forceinline
00110 IntSet::IntSet(int n, int m) {
00111 init(n,m);
00112 }
00113
00114 forceinline int
00115 IntSet::min(int i) const {
00116 assert(object() != NULL);
00117 return static_cast<IntSetObject*>(object())->r[i].min;
00118 }
00119
00120 forceinline int
00121 IntSet::max(int i) const {
00122 assert(object() != NULL);
00123 return static_cast<IntSetObject*>(object())->r[i].max;
00124 }
00125
00126 forceinline unsigned int
00127 IntSet::width(int i) const {
00128 assert(object() != NULL);
00129 IntSetObject* o = static_cast<IntSetObject*>(object());
00130 return static_cast<unsigned int>(o->r[i].max-o->r[i].min)+1;
00131 }
00132
00133 forceinline int
00134 IntSet::ranges(void) const {
00135 IntSetObject* o = static_cast<IntSetObject*>(object());
00136 return (o == NULL) ? 0 : o->n;
00137 }
00138
00139 forceinline bool
00140 IntSet::in(int n) const {
00141 IntSetObject* o = static_cast<IntSetObject*>(object());
00142 if ((o == NULL) || (n < o->r[0].min) || (n > o->r[o->n-1].max))
00143 return false;
00144 else
00145 return o->in(n);
00146 }
00147
00148 forceinline int
00149 IntSet::min(void) const {
00150 IntSetObject* o = static_cast<IntSetObject*>(object());
00151 return (o == NULL) ? Int::Limits::max : o->r[0].min;
00152 }
00153
00154 forceinline int
00155 IntSet::max(void) const {
00156 IntSetObject* o = static_cast<IntSetObject*>(object());
00157 return (o == NULL) ? Int::Limits::min : o->r[o->n-1].max;
00158 }
00159
00160 forceinline unsigned int
00161 IntSet::size(void) const {
00162 IntSetObject* o = static_cast<IntSetObject*>(object());
00163 return (o == NULL) ? 0 : o->size;
00164 }
00165
00166 forceinline unsigned int
00167 IntSet::width(void) const {
00168 return static_cast<unsigned int>(max()-min()+1);
00169 }
00170
00171
00172
00173
00174
00175
00176
00177 forceinline
00178 IntSetRanges::IntSetRanges(void) {}
00179 forceinline
00180 void
00181 IntSetRanges::init(const IntSet& s) {
00182 int n = s.ranges();
00183 if (n > 0) {
00184 i = &static_cast<IntSet::IntSetObject*>(s.object())->r[0]; e = i+n;
00185 } else {
00186 i = e = NULL;
00187 }
00188 }
00189 forceinline
00190 IntSetRanges::IntSetRanges(const IntSet& s) { init(s); }
00191
00192
00193 forceinline void
00194 IntSetRanges::operator ++(void) {
00195 i++;
00196 }
00197 forceinline bool
00198 IntSetRanges::operator ()(void) const {
00199 return i<e;
00200 }
00201
00202 forceinline int
00203 IntSetRanges::min(void) const {
00204 return i->min;
00205 }
00206 forceinline int
00207 IntSetRanges::max(void) const {
00208 return i->max;
00209 }
00210 forceinline unsigned int
00211 IntSetRanges::width(void) const {
00212 return static_cast<unsigned int>(i->max - i->min) + 1;
00213 }
00214
00215
00216
00217
00218
00219 forceinline
00220 IntSetValues::IntSetValues(void) {}
00221
00222 forceinline
00223 IntSetValues::IntSetValues(const IntSet& s) {
00224 IntSetRanges r(s);
00225 Iter::Ranges::ToValues<IntSetRanges>::init(r);
00226 }
00227
00228 forceinline void
00229 IntSetValues::init(const IntSet& s) {
00230 IntSetRanges r(s);
00231 Iter::Ranges::ToValues<IntSetRanges>::init(r);
00232 }
00233
00234 template<class Char, class Traits>
00235 std::basic_ostream<Char,Traits>&
00236 operator <<(std::basic_ostream<Char,Traits>& os, const IntSet& is) {
00237 std::basic_ostringstream<Char,Traits> s;
00238 s.copyfmt(os); s.width(0);
00239 s << '{';
00240 for (int i = 0; i < is.ranges(); ) {
00241 int min = is.min(i);
00242 int max = is.max(i);
00243 if (min == max)
00244 s << min;
00245 else
00246 s << min << ".." << max;
00247 i++;
00248 if (i < is.ranges())
00249 s << ',';
00250 }
00251 s << '}';
00252 return os << s.str();
00253 }
00254
00255 }
00256
00257
00258