this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2/* 3 * Main authors: 4 * Christian Schulte <schulte@gecode.org> 5 * 6 * Contributing authors: 7 * Guido Tack <tack@gecode.org> 8 * 9 * Copyright: 10 * Christian Schulte, 2004 11 * Guido Tack, 2004 12 * 13 * This file is part of Gecode, the generic constraint 14 * development environment: 15 * http://www.gecode.org 16 * 17 * Permission is hereby granted, free of charge, to any person obtaining 18 * a copy of this software and associated documentation files (the 19 * "Software"), to deal in the Software without restriction, including 20 * without limitation the rights to use, copy, modify, merge, publish, 21 * distribute, sublicense, and/or sell copies of the Software, and to 22 * permit persons to whom the Software is furnished to do so, subject to 23 * the following conditions: 24 * 25 * The above copyright notice and this permission notice shall be 26 * included in all copies or substantial portions of the Software. 27 * 28 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 29 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 31 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 32 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 33 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 34 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 35 * 36 */ 37 38namespace Gecode { 39 40 /** 41 * \brief Lists of ranges (intervals) 42 * 43 * This class implements a simple datastructure for storing sets of 44 * integers as lists of ranges (intervals). Memory is managed as 45 * space-allocated free lists. 46 * 47 * \ingroup FuncMemSpace 48 */ 49 class RangeList : public FreeList { 50 protected: 51 /// Minimum of range 52 int _min; 53 /// Maximum of range 54 int _max; 55 public: 56 /// \name Constructors 57 //@{ 58 /// Default constructor (noop) 59 RangeList(void); 60 /// Initialize with minimum \a min and maximum \a max 61 RangeList(int min, int max); 62 /// Initialize with minimum \a min and maximum \a max and successor \a n 63 RangeList(int min, int max, RangeList* n); 64 //@} 65 66 /// \name Access 67 //@{ 68 /// Return minimum 69 int min(void) const; 70 /// Return maximum 71 int max(void) const; 72 /// Return width (distance between maximum and minimum) 73 unsigned int width(void) const; 74 75 /// Return next element 76 RangeList* next(void) const; 77 /// Return pointer to next element 78 RangeList** nextRef(void); 79 //@} 80 81 /// \name Update 82 //@{ 83 /// Set minimum to \a n 84 void min(int n); 85 /// Set maximum to \a n 86 void max(int n); 87 /// Set next range to \a n 88 void next(RangeList* n); 89 //@} 90 91 /// \name Iterator operations 92 //@{ 93 /// Create rangelist \a r from range iterator \a i 94 template<class Iter> 95 static void copy(Space& home, RangeList*& r, Iter& i); 96 /// Overwrite rangelist \a r with ranges from range iterator \a i 97 template<class Iter> 98 static void overwrite(Space& home, RangeList*& r, Iter& i); 99 /// Insert (as union) ranges from iterator \a i into \a r 100 template<class I> 101 static void insert(Space& home, RangeList*& r, I& i); 102 //@} 103 104 /// \name Memory management 105 //@{ 106 /// Free memory for all elements between this and \a l (inclusive) 107 void dispose(Space& home, RangeList* l); 108 /// Free memory for all elements reachable from this 109 void dispose(Space& home); 110 111 /// Allocate memory from space 112 static void* operator new(size_t s, Space& home); 113 /// Placement-new operator (noop) 114 static void* operator new(size_t s, void* p); 115 /// No-op (for exceptions) 116 static void operator delete(void*); 117 /// No-op (use dispose instead) 118 static void operator delete(void*, Space& home); 119 /// No-op (use dispose instead) 120 static void operator delete(void*, void*); 121 //@} 122 }; 123 124 /* 125 * Range lists 126 * 127 */ 128 129 forceinline 130 RangeList::RangeList(void) {} 131 132 forceinline 133 RangeList::RangeList(int min, int max, RangeList* n) 134 : FreeList(n), _min(min), _max(max) {} 135 136 forceinline 137 RangeList::RangeList(int min, int max) 138 : _min(min), _max(max) {} 139 140 forceinline RangeList* 141 RangeList::next(void) const { 142 return static_cast<RangeList*>(FreeList::next()); 143 } 144 145 forceinline RangeList** 146 RangeList::nextRef(void) { 147 return reinterpret_cast<RangeList**>(FreeList::nextRef()); 148 } 149 150 forceinline void 151 RangeList::min(int n) { 152 _min = n; 153 } 154 forceinline void 155 RangeList::max(int n) { 156 _max = n; 157 } 158 forceinline void 159 RangeList::next(RangeList* n) { 160 FreeList::next(n); 161 } 162 163 forceinline int 164 RangeList::min(void) const { 165 return _min; 166 } 167 forceinline int 168 RangeList::max(void) const { 169 return _max; 170 } 171 forceinline unsigned int 172 RangeList::width(void) const { 173 return static_cast<unsigned int>(_max - _min + 1); 174 } 175 176 177 forceinline void 178 RangeList::operator delete(void*) {} 179 180 forceinline void 181 RangeList::operator delete(void*, Space&) { 182 GECODE_NEVER; 183 } 184 185 forceinline void 186 RangeList::operator delete(void*, void*) { 187 GECODE_NEVER; 188 } 189 190 forceinline void* 191 RangeList::operator new(size_t, Space& home) { 192 return home.fl_alloc<sizeof(RangeList)>(); 193 } 194 195 forceinline void* 196 RangeList::operator new(size_t, void* p) { 197 return p; 198 } 199 200 forceinline void 201 RangeList::dispose(Space& home, RangeList* l) { 202 home.fl_dispose<sizeof(RangeList)>(this,l); 203 } 204 205 forceinline void 206 RangeList::dispose(Space& home) { 207 RangeList* l = this; 208 while (l->next() != nullptr) 209 l=l->next(); 210 dispose(home,l); 211 } 212 213 template<class Iter> 214 forceinline void 215 RangeList::copy(Space& home, RangeList*& r, Iter& i) { 216 RangeList sentinel; sentinel.next(r); 217 RangeList* p = &sentinel; 218 while (i()) { 219 RangeList* n = new (home) RangeList(i.min(),i.max()); 220 p->next(n); p=n; ++i; 221 } 222 p->next(nullptr); 223 r = sentinel.next(); 224 } 225 226 template<class Iter> 227 forceinline void 228 RangeList::overwrite(Space& home, RangeList*& r, Iter& i) { 229 RangeList sentinel; sentinel.next(r); 230 RangeList* p = &sentinel; 231 RangeList* c = p->next(); 232 while ((c != nullptr) && i()) { 233 c->min(i.min()); c->max(i.max()); 234 p=c; c=c->next(); ++i; 235 } 236 if ((c == nullptr) && !i()) 237 return; 238 if (c == nullptr) { 239 assert(i()); 240 // New elements needed 241 do { 242 RangeList* n = new (home) RangeList(i.min(),i.max()); 243 p->next(n); p=n; ++i; 244 } while (i()); 245 } else { 246 // Dispose excess elements 247 while (c->next() != nullptr) 248 c=c->next(); 249 p->next()->dispose(home,c); 250 } 251 p->next(nullptr); 252 r = sentinel.next(); 253 } 254 255 template<class I> 256 forceinline void 257 RangeList::insert(Space& home, RangeList*& r, I& i) { 258 RangeList sentinel; 259 sentinel.next(r); 260 RangeList* p = &sentinel; 261 RangeList* c = p->next(); 262 while ((c != nullptr) && i()) { 263 if ((c->max()+1 < i.min())) { 264 p=c; c=c->next(); 265 } else if (i.max()+1 < c->min()) { 266 RangeList* n = new (home) RangeList(i.min(),i.max(),c); 267 p->next(n); p=n; ++i; 268 } else { 269 int min = std::min(c->min(),i.min()); 270 int max = std::max(c->max(),i.max()); 271 RangeList* f=c; 272 p=c; c=c->next(); ++i; 273 next: 274 if ((c != nullptr) && (c->min() <= max+1)) { 275 max = std::max(max,c->max()); 276 p=c; c=c->next(); 277 goto next; 278 } 279 if (i() && (i.min() <= max+1)) { 280 max = std::max(max,i.max()); 281 ++i; 282 goto next; 283 } 284 // Dispose now unused elements 285 if (f->next() != p) 286 f->next()->dispose(home,p); 287 f->min(min); f->max(max); f->next(c); 288 } 289 } 290 if (c == nullptr) { 291 while (i()) { 292 RangeList* n = new (home) RangeList(i.min(),i.max()); 293 p->next(n); p=n; 294 ++i; 295 } 296 p->next(nullptr); 297 } 298 r = sentinel.next(); 299 } 300 301} 302// STATISTICS: kernel-other