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
00039
00040 #include "scv/scv_util.h"
00041 #include "scv/scv_introspection.h"
00042 #include "scv/scv_report.h"
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #define _SCV_INTERVAL_FC_I(TypeId, EltT, SizeT, Discrete) \
00063 _scv_interval_ ## TypeId& _scv_interval_ ## TypeId::operator=(const _scv_interval_ ## TypeId& rhs) { \
00064 _empty = rhs._empty; \
00065 _lowerbound = rhs._lowerbound; \
00066 _upperbound = rhs._upperbound; \
00067 \
00068 return *this; \
00069 } \
00070 bool operator==(const _scv_interval_ ## TypeId& a, \
00071 const _scv_interval_ ## TypeId& b) { \
00072 if (a._empty && b._empty) return true; \
00073 if (!a._empty && !b._empty \
00074 && a._lowerbound == b._lowerbound \
00075 && a._upperbound == b._upperbound) return true; \
00076 return false; \
00077 } \
00078 bool operator<(const _scv_interval_ ## TypeId& a, \
00079 const _scv_interval_ ## TypeId& b) { \
00080 if (b._empty) return false; \
00081 if (a._empty) return true; \
00082 if (a._lowerbound < b._lowerbound \
00083 || (a._lowerbound == b._lowerbound \
00084 && a._upperbound < b._upperbound)) return true; \
00085 return false; \
00086 } \
00087 void _scv_interval_ ## TypeId::print(ostream& os) const { \
00088 if (_empty) os << "()"; \
00089 else if (Discrete) { \
00090 if (_lowerbound != _upperbound) \
00091 os << "[" << _lowerbound << "," << _upperbound << "]"; \
00092 else \
00093 os << "[" << _lowerbound << "]"; \
00094 } else \
00095 os << "[" << _lowerbound << "," << _upperbound << ")"; \
00096 } \
00097 ostream& operator<<(ostream& os, const _scv_interval_ ## TypeId& a) { \
00098 if (a._empty) os << "()"; \
00099 else if (Discrete) { \
00100 if (a._lowerbound != a._upperbound) \
00101 os << "[" << a._lowerbound << "," << a._upperbound << "]"; \
00102 else \
00103 os << "[" << a._lowerbound << "]"; \
00104 } else \
00105 os << "[" << a._lowerbound << "," << a._upperbound << ")"; \
00106 return os; \
00107 } \
00108 SizeT _scv_interval_ ## TypeId::size() const { \
00109 if (_empty) { \
00110 _tmp = 0; \
00111 } else { \
00112 _tmp = _upperbound - _lowerbound; \
00113 if (Discrete) _tmp += 1; \
00114 } \
00115 return _tmp; \
00116 } \
00117 int _scv_interval_ ## TypeId::position(const EltT& v) const { \
00118 if (_empty) return 1; \
00119 if (v<_lowerbound) return -1; \
00120 if (v>_upperbound) return 1; \
00121 if (!Discrete && v== _upperbound) return 1; \
00122 return 0; \
00123 } \
00124 bool _scv_interval_ ## TypeId::contain(const _scv_interval_ ## TypeId& i) const { \
00125 if (_empty) return false; \
00126 if (i._empty) return true; \
00127 return i._upperbound <= _upperbound && i._lowerbound >= _lowerbound; \
00128 } \
00129 bool overlap(const _scv_interval_ ## TypeId& a, \
00130 const _scv_interval_ ## TypeId& b) { \
00131 if (a._empty || b._empty) return false; \
00132 if (Discrete) { \
00133 if (a._lowerbound > b._upperbound) return false; \
00134 if (a._upperbound < b._lowerbound) return false; \
00135 } else { \
00136 if (a._lowerbound >= b._upperbound) return false; \
00137 if (a._upperbound <= b._lowerbound) return false; \
00138 } \
00139 return true; \
00140 } \
00141 void _scv_interval_ ## TypeId::intersect(const _scv_interval_ ## TypeId& rhs) { \
00142 if (!overlap(*this,rhs)) { _empty = true; return ; } \
00143 if (_lowerbound < rhs._lowerbound) _lowerbound = rhs._lowerbound; \
00144 if (_upperbound > rhs._upperbound) _upperbound = rhs._upperbound; \
00145 } \
00146 bool _scv_interval_ ## TypeId::subtractable(const _scv_interval_ ## TypeId& rhs) const { \
00147 return _empty || rhs._empty \
00148 || !( rhs._lowerbound > _lowerbound \
00149 && rhs._upperbound < _upperbound); \
00150 } \
00151 void _scv_interval_ ## TypeId::subtract(const _scv_interval_ ## TypeId& rhs) { \
00152 if (_empty || rhs._empty) return; \
00153 if (!subtractable(rhs)) { \
00154 _scv_message::message(_scv_message::CONSTRAINT_ERROR_INTERNAL,"interval subtraction"); \
00155 } \
00156 if (Discrete) { \
00157 if (rhs._lowerbound <= _lowerbound && _lowerbound <= rhs._upperbound) { \
00158 _lowerbound = rhs._upperbound+1; \
00159 if (_lowerbound < rhs._upperbound) _empty = true; \
00160 } \
00161 if (rhs._lowerbound <= _upperbound && _upperbound <= rhs._upperbound) { \
00162 _upperbound = rhs._lowerbound-1; \
00163 if (rhs._lowerbound < _upperbound) _empty = true; \
00164 } \
00165 } else { \
00166 if (rhs._lowerbound <= _lowerbound && _lowerbound <= rhs._upperbound) \
00167 _lowerbound = rhs._upperbound; \
00168 if (rhs._lowerbound <= _upperbound && _upperbound <= rhs._upperbound) \
00169 _upperbound = rhs._lowerbound; \
00170 } \
00171 if (Discrete) { \
00172 if (_upperbound < _lowerbound) _empty = true; \
00173 } else { \
00174 if (_upperbound <= _lowerbound) _empty = true; \
00175 } \
00176 } \
00177 bool mergeable(const _scv_interval_ ## TypeId& a, \
00178 const _scv_interval_ ## TypeId& b) { \
00179 if (a._empty || b._empty) return true; \
00180 if (Discrete) { \
00181 if ((a._upperbound < b._lowerbound && a._upperbound+1 < b._lowerbound) \
00182 || (b._upperbound < a._lowerbound && b._upperbound+1 < a._lowerbound)) \
00183 return false; \
00184 } else { \
00185 if (a._upperbound < b._lowerbound \
00186 || b._upperbound < a._lowerbound) return false; \
00187 } \
00188 return true; \
00189 } \
00190 void _scv_interval_ ## TypeId::merge(const _scv_interval_ ## TypeId& rhs) { \
00191 if (rhs._empty) return; \
00192 if (_empty) { operator=(rhs); return; } \
00193 if (!mergeable(*this,rhs)) { \
00194 _scv_message::message(_scv_message::CONSTRAINT_ERROR_INTERNAL,"interval merging"); \
00195 } \
00196 if (_lowerbound > rhs._lowerbound) _lowerbound = rhs._lowerbound; \
00197 if (_upperbound < rhs._upperbound) _upperbound = rhs._upperbound; \
00198 } \
00199
00200
00201
00202 _SCV_INTERVAL_FC_I(int,int,unsigned,true);
00203 _SCV_INTERVAL_FC_I(unsigned,unsigned,unsigned,true);
00204 _SCV_INTERVAL_FC_I(double,double,double,false);
00205
00206 _SCV_INTERVAL_FC_I(long_long,long long,unsigned long long,true);
00207 _SCV_INTERVAL_FC_I(unsigned_long_long,unsigned long long,unsigned long long,true);
00208
00209 _SCV_INTERVAL_FC_I(sc_unsigned,sc_unsigned ,sc_unsigned,true);
00210 _SCV_INTERVAL_FC_I(sc_signed ,sc_signed ,sc_unsigned,true);
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 #define _SCV_CONSTRAINT_RANGE_FC_I(TypeId, EltT, SizeT, Discrete, FlexRandomT) \
00227 ostream& operator<<(ostream& os, const _scv_constraint_range_ ## TypeId& a) { \
00228 if (a.isEmpty()) os << "()"; \
00229 else { \
00230 if (a._explicits.empty()) { \
00231 if (a.getSize() == 0) \
00232 os << "(size:<unconstrainted>) "; \
00233 else \
00234 os << "(size:" << a.getSize() << ") "; \
00235 list<_scv_interval_ ## TypeId >::const_iterator i; \
00236 i = a._intervals.begin(); \
00237 \
00238 i->print(os); \
00239 while (++i != a._intervals.end()) { \
00240 os << ","; i->print(os); \
00241 } \
00242 } else { \
00243 list<EltT>::const_iterator i; \
00244 i = a._explicits.begin(); \
00245 os << "[" << *i << "]"; \
00246 while (++i != a._explicits.end()) \
00247 os << ",[" << *i << "]"; \
00248 } \
00249 } \
00250 return os; \
00251 } \
00252 \
00253 SizeT _scv_constraint_range_ ## TypeId::getSize() const { \
00254 if (!_explicits.empty()) { \
00255 _scv_message::message(_scv_message::CONSTRAINT_ERROR_INTERNAL,"interval size"); \
00256 } \
00257 if (!_sizeValid) \
00258 setSize(); \
00259 return _size; \
00260 } \
00261 void _scv_constraint_range_ ## TypeId::setSize() const { \
00262 _sizeValid = true; _size = 0; \
00263 list<_scv_interval_ ## TypeId >::const_iterator i; \
00264 for (i = _intervals.begin(); i != _intervals.end(); ++i) { \
00265 _size += i->size(); \
00266 } \
00267 } \
00268 \
00269 void _scv_constraint_range_ ## TypeId::checkExplicits() { \
00270 if (_explicits.empty()) { \
00271 _intervals.clear(); \
00272 _mode = EMPTY; \
00273 _sizeValid = false; \
00274 _size = 0; \
00275 _intervals.push_front(_scv_interval_ ## TypeId(_size,_size)); \
00276 emptyMessage(); \
00277 } \
00278 else { \
00279 _intervals.push_front(_scv_interval_ ## TypeId(_explicits.front(), \
00280 _explicits.back())); \
00281 } \
00282 } \
00283 void _scv_constraint_range_ ## TypeId::checkIntervals() { \
00284 if (_intervals.empty()) { \
00285 _mode = EMPTY; \
00286 _sizeValid = false; \
00287 _size = 0; \
00288 _intervals.push_front(_scv_interval_ ## TypeId(_size,_size)); \
00289 emptyMessage(); \
00290 } \
00291 } \
00292 \
00293 void _scv_constraint_range_ ## TypeId::emptyMessage() { \
00294 if (_nameP !="" ) { \
00295 _scv_message::message(_scv_message::CONSTRAINT_ERROR_OVER_CONSTRAINED,_nameP.c_str()); \
00296 } \
00297 } \
00298 EltT \
00299 _scv_constraint_range_ ## TypeId:: \
00300 getRandomValue(scv_shared_ptr<scv_random> random) const { \
00301 \
00302 if (!isEmpty()) { \
00303 if (isUnconstrainted()) { \
00304 return _flexRandom.next(random); \
00305 } \
00306 if (_explicits.empty()) { \
00307 SizeT remain = _flexRandom.next(random,getSize()); \
00308 list<_scv_interval_ ## TypeId >::const_iterator i; \
00309 for (i = _intervals.begin(); i != _intervals.end(); ++i) { \
00310 if (remain < i->size()) { \
00311 return i->lowerbound() + remain; \
00312 } \
00313 remain -= i->size(); \
00314 } \
00315 } else { \
00316 unsigned int index = random->next() % _explicits.size(); \
00317 list<EltT>::const_iterator i = _explicits.begin(); \
00318 while (index != 0) { \
00319 --index; \
00320 ++i; \
00321 } \
00322 return *i; \
00323 } \
00324 } \
00325 \
00326 \
00327 _sizeValid = false; _size = 0; return _size; \
00328 } \
00329 \
00330 EltT \
00331 _scv_constraint_range_ ## TypeId:: \
00332 getScanValue(const EltT& base, const SizeT& increment) const { \
00333 \
00334 if (!isEmpty()) { \
00335 EltT nextValue = base + increment; \
00336 if (nextValue < base) return base; \
00337 if (isUnconstrainted()) { return nextValue; } \
00338 if (_explicits.empty()) { \
00339 list<_scv_interval_ ## TypeId >::const_iterator i; \
00340 for (i = _intervals.begin(); i != _intervals.end(); ++i) { \
00341 int position = i->position(nextValue); \
00342 if (position == 0) \
00343 return nextValue; \
00344 else if (position < 0) { \
00345 if (Discrete) { \
00346 SizeT d = i->lowerbound() - nextValue; \
00347 if (_flexRandom.mod(d,increment) == 0) \
00348 return i->lowerbound(); \
00349 nextValue = nextValue + (d / increment) * increment + increment; \
00350 if (nextValue < base) return base; \
00351 if (nextValue <= i->upperbound()) \
00352 return nextValue; \
00353 } else { \
00354 \
00355 \
00356 \
00357 SizeT d = (i->lowerbound() - nextValue)/increment; \
00358 if (d < 1) { \
00359 nextValue += increment; \
00360 if (i->position(nextValue)==0) return nextValue; \
00361 } else { \
00362 nextValue += _flexRandom.floor((i->lowerbound() - nextValue)/increment) * increment; \
00363 if (i->position(nextValue)==0) return nextValue; \
00364 nextValue += increment; \
00365 if (i->position(nextValue)==0) return nextValue; \
00366 } \
00367 } \
00368 } \
00369 } \
00370 return base; \
00371 } else { \
00372 list<EltT>::const_iterator i; \
00373 for (i = _explicits.begin(); i != _explicits.end(); ++i) { \
00374 if (nextValue == *i) return *i; \
00375 if (nextValue < *i && _flexRandom.mod(*i-nextValue,increment) == 0) return *i; \
00376 } \
00377 return base; \
00378 } \
00379 } \
00380 \
00381 \
00382 _sizeValid = false; _size = 0; return _size; \
00383 } \
00384 \
00385 _scv_constraint_range_ ## TypeId::_scv_constraint_range_ ## TypeId() \
00386 : _mode(EMPTY), _nameP(""), _intervals(), _explicits(), \
00387 _flexRandom(), _tmpUb(0), _tmpLb(0), _sizeValid(false), _size(0) { \
00388 _intervals.push_front(_scv_interval_ ## TypeId((EltT) 0, (EltT) 0)); \
00389 } \
00390 \
00391 _scv_constraint_range_ ## TypeId:: \
00392 _scv_constraint_range_ ## TypeId(const EltT& sampleElt) \
00393 : _mode(EMPTY), _nameP(""), _intervals(), _explicits(), \
00394 _flexRandom(sampleElt), _tmpUb(sampleElt), _tmpLb(sampleElt), _sizeValid(false), _size(sampleElt) { \
00395 } \
00396 \
00397 _scv_constraint_range_ ## TypeId:: \
00398 _scv_constraint_range_ ## TypeId(const EltT& lb, const EltT& ub) \
00399 : _mode(INTERVAL_LIST), _nameP(""), _intervals(), _explicits(), \
00400 _flexRandom(lb), _tmpUb(lb), _tmpLb(lb), _sizeValid(false), _size(lb) { \
00401 _intervals.push_front(_scv_interval_ ## TypeId(lb,ub)); \
00402 } \
00403 \
00404 _scv_constraint_range_ ## TypeId:: \
00405 _scv_constraint_range_ ## TypeId(const _scv_constraint_range_ ## TypeId& rhs) \
00406 : _mode(rhs._mode), \
00407 _nameP(rhs._nameP), \
00408 _intervals(rhs._intervals), \
00409 _explicits(rhs._explicits), \
00410 _flexRandom(rhs._flexRandom), \
00411 _tmpUb(rhs._tmpUb), \
00412 _tmpLb(rhs._tmpLb), \
00413 _sizeValid(rhs._sizeValid), \
00414 _size(rhs._size) \
00415 {} \
00416 \
00417 _scv_constraint_range_ ## TypeId& \
00418 _scv_constraint_range_ ## TypeId:: \
00419 operator=(const _scv_constraint_range_ ## TypeId& rhs) { \
00420 _mode = rhs._mode; \
00421 _nameP = rhs._nameP; \
00422 _intervals = rhs._intervals; \
00423 _explicits = rhs._explicits; \
00424 \
00425 _sizeValid = rhs._sizeValid; \
00426 _size = rhs._size; \
00427 return *this; \
00428 } \
00429 \
00430 _scv_constraint_range_ ## TypeId \
00431 _scv_constraint_range_ ## TypeId:: \
00432 merge(const _scv_constraint_range_ ## TypeId& a, \
00433 const _scv_constraint_range_ ## TypeId& b) { \
00434 \
00435 if (a.isUnconstrainted()) return b; \
00436 if (b.isUnconstrainted()) return a; \
00437 if (a.isEmpty()) return a; \
00438 if (b.isEmpty()) return b; \
00439 \
00440 \
00441 if (!a._explicits.empty()) { \
00442 list<EltT> common; \
00443 list<EltT>::const_iterator i = a._explicits.begin(); \
00444 while (i != a._explicits.end()) { \
00445 if (b.satisfy(*i)) common.push_back(*i); \
00446 ++i; \
00447 } \
00448 _scv_constraint_range_ ## TypeId c(a.getLowerBound()); \
00449 if (!common.empty()) { \
00450 c._mode = INTERVAL_LIST; \
00451 c._explicits = common; \
00452 c._intervals.push_front \
00453 (_scv_interval_ ## TypeId(c._explicits.front(), \
00454 c._explicits.back())); \
00455 } \
00456 \
00457 return c; \
00458 } \
00459 if (!b._explicits.empty()) return merge(b,a); \
00460 \
00461 \
00462 _scv_constraint_range_ ## TypeId m(a.getLowerBound()); \
00463 m._mode = INTERVAL_LIST; \
00464 list<_scv_interval_ ## TypeId >::const_iterator i,j; \
00465 i = a._intervals.begin(); \
00466 j = b._intervals.begin(); \
00467 while (i != a._intervals.end() && j != b._intervals.end()) { \
00468 if (overlap(*i,*j)) { \
00469 _scv_interval_ ## TypeId tmp = *i; \
00470 tmp.intersect(*j); \
00471 m._intervals.push_back(tmp); \
00472 } \
00473 if (i->upperbound() < j->upperbound()) ++i; \
00474 else ++j; \
00475 } \
00476 m.checkIntervals(); \
00477 return m; \
00478 } \
00479 \
00480 void _scv_constraint_range_ ## TypeId:: \
00481 keepOnly(const EltT& lb, const EltT& ub) { \
00482 _tmpLb = lb; \
00483 _tmpUb = ub; \
00484 \
00485 if (isEmpty()) return; \
00486 if (isUnconstrainted()) { \
00487 _sizeValid = false; \
00488 _intervals.clear(); \
00489 _intervals.push_front(_scv_interval_ ## TypeId(_tmpLb,_tmpUb)); \
00490 return; \
00491 } \
00492 \
00493 \
00494 _sizeValid = false; \
00495 _scv_interval_ ## TypeId interval(_tmpLb,_tmpUb); \
00496 \
00497 \
00498 if (!_explicits.empty()) { \
00499 list<EltT>::iterator i = _explicits.begin(); \
00500 while (i != _explicits.end()) { \
00501 int position = interval.position(*i); \
00502 if (position != 0) \
00503 i = _explicits.erase(i); \
00504 else \
00505 ++i; \
00506 } \
00507 checkExplicits(); \
00508 return; \
00509 } \
00510 \
00511 list<_scv_interval_ ## TypeId >::iterator i; \
00512 i = _intervals.begin(); \
00513 while (i != _intervals.end()) { \
00514 if (overlap(*i,interval)) { \
00515 _scv_interval_ ## TypeId tmp = *i; \
00516 tmp.intersect(interval); \
00517 _intervals.insert(i,tmp); \
00518 i = _intervals.erase(i); \
00519 } else { \
00520 i = _intervals.erase(i); \
00521 } \
00522 } \
00523 checkIntervals(); \
00524 return; \
00525 } \
00526 \
00527 void _scv_constraint_range_ ## TypeId::keepOnly(const EltT& v) { \
00528 if (Discrete) \
00529 keepOnly(v,v); \
00530 else { \
00531 if (satisfy(v)) { \
00532 _intervals.clear(); \
00533 _explicits.clear(); \
00534 _explicits.push_front(v); \
00535 _intervals.push_front(_scv_interval_ ## TypeId(v,v)); \
00536 } else { \
00537 _intervals.clear(); \
00538 _explicits.clear(); \
00539 _mode = EMPTY; \
00540 emptyMessage(); \
00541 } \
00542 } \
00543 } \
00544 \
00545 void _scv_constraint_range_ ## TypeId::keepOnly(const list<EltT>& l) { \
00546 \
00547 if (isEmpty()) return; \
00548 \
00549 \
00550 list<EltT> l2; \
00551 for (list<EltT>::const_iterator i = l.begin(); \
00552 i != l.end(); \
00553 ++i) { \
00554 if (satisfy(*i)) \
00555 l2.push_back(*i); \
00556 } \
00557 if (l2.empty()) { \
00558 _intervals.clear(); \
00559 checkIntervals(); \
00560 return; \
00561 } \
00562 \
00563 _intervals.clear(); \
00564 _sizeValid = false; \
00565 if (Discrete) { \
00566 for (list<EltT>::iterator j = l2.begin(); \
00567 j != l2.end(); \
00568 ++j) { \
00569 list< _scv_interval_ ## TypeId >::iterator k; \
00570 for (k = _intervals.begin(); k != _intervals.end(); ++k) { \
00571 if (k->lowerbound() > *j) { \
00572 _tmpLb = *j; \
00573 _intervals.insert(k,_scv_interval_ ## TypeId(_tmpLb,_tmpLb)); \
00574 break; \
00575 } \
00576 } \
00577 if (k == _intervals.end()) { \
00578 _tmpLb = *j; \
00579 _intervals.push_back(_scv_interval_ ## TypeId(_tmpLb,_tmpLb)); \
00580 } \
00581 } \
00582 checkIntervals(); \
00583 } else { \
00584 _explicits.clear(); \
00585 for (list<EltT>::iterator j = l2.begin(); \
00586 j != l2.end(); \
00587 ++j) { \
00588 list<EltT>::iterator k; \
00589 for (k = _explicits.begin(); k != _explicits.end(); ++k) { \
00590 if (*j < *k) { \
00591 _explicits.insert(k,*j); \
00592 break; \
00593 } \
00594 if (*j == *k) \
00595 break; \
00596 } \
00597 if (k == _explicits.end()) \
00598 _explicits.push_back(*j); \
00599 } \
00600 checkExplicits(); \
00601 } \
00602 } \
00603 \
00604 void _scv_constraint_range_ ## TypeId:: \
00605 keepOut(const EltT& lb, const EltT& ub) { \
00606 _tmpLb = lb; \
00607 _tmpUb = ub; \
00608 \
00609 \
00610 if (isEmpty()) return; \
00611 \
00612 \
00613 _sizeValid = false; \
00614 _scv_interval_ ## TypeId interval(_tmpLb,_tmpUb); \
00615 \
00616 \
00617 if (!_explicits.empty()) { \
00618 list<EltT>::iterator i = _explicits.begin(); \
00619 while (i != _explicits.end()) { \
00620 int position = interval.position(*i); \
00621 if (position == 0) \
00622 i = _explicits.erase(i); \
00623 else \
00624 ++i; \
00625 } \
00626 checkExplicits(); \
00627 return; \
00628 } \
00629 \
00630 \
00631 list<_scv_interval_ ## TypeId >::iterator i; \
00632 i = _intervals.begin(); \
00633 while (i != _intervals.end()) { \
00634 if (i->contain(interval)) { \
00635 if (Discrete) { \
00636 if (i->lowerbound() < interval.lowerbound()) { \
00637 _tmpUb = interval.lowerbound()-1; \
00638 _intervals.insert \
00639 (i, _scv_interval_ ## TypeId(i->lowerbound(),_tmpUb)); \
00640 } \
00641 if (i->upperbound() > interval.upperbound()) { \
00642 _tmpLb = interval.upperbound()+1; \
00643 _intervals.insert \
00644 (i,_scv_interval_ ## TypeId(_tmpLb,i->upperbound())); \
00645 } \
00646 } else { \
00647 if (i->lowerbound() < interval.lowerbound()) \
00648 _intervals.insert \
00649 (i,_scv_interval_ ## TypeId(i->lowerbound(), \
00650 interval.lowerbound())); \
00651 if (i->upperbound() > interval.upperbound()) \
00652 _intervals.insert \
00653 (i,_scv_interval_ ## TypeId(interval.upperbound(), \
00654 i->upperbound())); \
00655 } \
00656 i = _intervals.erase(i); \
00657 } else { \
00658 if (i->subtractable(interval)) \
00659 i->subtract(interval); \
00660 if (i->empty()) \
00661 i = _intervals.erase(i); \
00662 else \
00663 ++i; \
00664 } \
00665 } \
00666 checkIntervals(); \
00667 } \
00668 \
00669 void _scv_constraint_range_ ## TypeId::keepOut(const EltT& v) { \
00670 if (!Discrete) { \
00671 _scv_message::message(_scv_message::CONSTRAINT_ERROR_INTERNAL,"non-discrete keepOut"); \
00672 } \
00673 keepOut(v,v); \
00674 } \
00675 \
00676 void _scv_constraint_range_ ## TypeId:: \
00677 keepOut(const list<EltT>& l) { \
00678 if (!Discrete) { \
00679 _scv_message::message(_scv_message::CONSTRAINT_ERROR_INTERNAL,"non-discrete keepOut"); \
00680 } \
00681 for (list<EltT>::const_iterator i = l.begin(); i != l.end(); ++i) \
00682 keepOut(*i); \
00683 } \
00684 \
00685 bool _scv_constraint_range_ ## TypeId:: \
00686 satisfy(const EltT& v) const { \
00687 \
00688 if (isEmpty()) return false; \
00689 if (_explicits.empty()) { \
00690 list<_scv_interval_ ## TypeId >::const_iterator i; \
00691 for (i = _intervals.begin(); i != _intervals.end(); ++i) { \
00692 int j = i->position(v); \
00693 if (j== 0) return true; \
00694 if (j < 0) return false; \
00695 } \
00696 } else { \
00697 list<EltT>::const_iterator i; \
00698 for (i = _explicits.begin(); i != _explicits.end(); ++i) { \
00699 if (*i == v) return true; \
00700 \
00701 \
00702 } \
00703 } \
00704 return false; \
00705 } \
00706
00707
00708
00709
00710 _SCV_CONSTRAINT_RANGE_FC_I(int,int,unsigned,true,_scv_random_unsigned);
00711 _SCV_CONSTRAINT_RANGE_FC_I(unsigned,unsigned,unsigned,true,_scv_random_unsigned);
00712 _SCV_CONSTRAINT_RANGE_FC_I(double,double,double,false,_scv_random_double);
00713
00714 _SCV_CONSTRAINT_RANGE_FC_I(long_long,long long,unsigned long long,true,_scv_random_unsigned_ll);
00715 _SCV_CONSTRAINT_RANGE_FC_I(unsigned_long_long,unsigned long long,unsigned long long,true,_scv_random_unsigned_ll);
00716
00717 _SCV_CONSTRAINT_RANGE_FC_I(sc_unsigned,sc_unsigned ,sc_unsigned,true,_scv_random_unsigned_big);
00718 _SCV_CONSTRAINT_RANGE_FC_I(sc_signed ,sc_signed ,sc_unsigned,true,_scv_random_unsigned_big);
00719
00720
00721
00722
00723
00724
00725
00726
00727 #define _SCV_CONSTRAINT_RANGE_GENERATOR_FC_I(TypeId, EltT, SizeT, Discrete, FlexRandomT) \
00728 void _scv_constraint_range_generator_base_ ## TypeId::print(ostream& os, const char * prefixP) const { \
00729 string prefix = ""; \
00730 if (prefixP) prefix = prefixP; \
00731 os << prefix << "legal values : " << _simpleConstraint << endl; \
00732 if (_onGoingConstraintValid) \
00733 os << prefix << "legal values to avoid duplicate : " << _onGoingConstraint << endl; \
00734 if (_currentScanValueValid) \
00735 os << prefix << "scan status : last value generated is " << _currentScanValue << endl; \
00736 if (_scanFixedIncrement) \
00737 os << prefix << "scan interval : " << _scanIncrement << endl; \
00738 else \
00739 os << prefix << "scan interval : " \
00740 << *_scanIntervalGenP << endl; \
00741 os << prefix << "duplicate distance : " << _duplicateDistance << endl; \
00742 if (_distributionP && !_distributionP->empty()) { \
00743 os << prefix << "distribution : " << endl; \
00744 os << prefix << *_distributionP << endl; \
00745 } \
00746 } \
00747 void _scv_constraint_range_generator_base_ ## TypeId::checkConstraint(const char * locationP) { \
00748 reset(); \
00749 if (isEmpty()) \
00750 _scv_constraint_range_error::overConstraint(_nameP, locationP); \
00751 if (_distributionP && !_distributionP->empty()) { \
00752 _setWeightDistribution(*_distributionP,_distUseMarking); \
00753 } \
00754 } \
00755 EltT _scv_constraint_range_generator_base_ ## TypeId:: \
00756 randomNext() const { \
00757 if (isEmpty()) \
00758 _scv_constraint_range_error::emptyGenerator(_nameP); \
00759 return _simpleConstraint.getRandomValue(_randomP); \
00760 } \
00761 \
00762 EltT _scv_constraint_range_generator_base_ ## TypeId:: \
00763 distributionNext() const { \
00764 if (_distributionP && !_distributionP->empty()) { \
00765 if (_distributionP->unMarkedSize()==0) _distributionP->unmarkAll(); \
00766 return _distributionP->peekRandom(_distUseMarking); \
00767 } \
00768 _scv_constraint_range_error::invalidDistribution(_nameP,"next"); \
00769 return randomNext(); \
00770 } \
00771 \
00772 EltT _scv_constraint_range_generator_base_ ## TypeId:: \
00773 randomAvoidDuplicateNext() const { \
00774 if (isEmpty()) \
00775 _scv_constraint_range_error::emptyGenerator(_nameP); \
00776 if (!_onGoingConstraintValid) { \
00777 _onGoingConstraint = _simpleConstraint; \
00778 _onGoingConstraintValid = true; \
00779 } \
00780 EltT newValue = \
00781 _onGoingConstraint.getRandomValue(_randomP); \
00782 if (Discrete) \
00783 _onGoingConstraint.keepOut(newValue); \
00784 else \
00785 _onGoingConstraint.keepOut(newValue-_duplicateDistance, \
00786 newValue+_duplicateDistance); \
00787 if (_onGoingConstraint.isEmpty()) \
00788 _onGoingConstraintValid = false; \
00789 return newValue; \
00790 } \
00791 \
00792 EltT _scv_constraint_range_generator_base_ ## TypeId:: \
00793 scanNext() const { \
00794 if (isEmpty()) \
00795 _scv_constraint_range_error::emptyGenerator(_nameP); \
00796 if (!_onGoingConstraintValid) { \
00797 _onGoingConstraint = _simpleConstraint; \
00798 _onGoingConstraintValid = true; \
00799 } \
00800 if (!_currentScanValueValid) { \
00801 _currentScanValue = _onGoingConstraint.getLowerBound(); \
00802 _currentScanValueValid = true;; \
00803 return _currentScanValue; \
00804 } \
00805 \
00806 if (!_scanFixedIncrement) \
00807 _scanIncrement = _scanIntervalGenP->getRandomValue(_randomP); \
00808 \
00809 EltT nextValue \
00810 = _onGoingConstraint.getScanValue(_currentScanValue, \
00811 _scanIncrement); \
00812 if (nextValue == _currentScanValue) { \
00813 _currentScanValueValid = false; \
00814 _onGoingConstraintValid = false; \
00815 return scanNext(); \
00816 } \
00817 _currentScanValue = nextValue; \
00818 return _currentScanValue; \
00819 } \
00820 \
00821 _scv_constraint_range_generator_base_ ## TypeId:: \
00822 _scv_constraint_range_generator_base_ ## TypeId(const EltT& lb, const EltT& ub, \
00823 scv_shared_ptr<scv_random> random, const char * nameP) \
00824 : _nameP(nameP), \
00825 _simpleConstraint(lb,ub), \
00826 _onGoingConstraintValid(false), \
00827 _onGoingConstraint(lb,ub), \
00828 _currentScanValueValid(false), \
00829 _currentScanValue(lb), \
00830 _randomP(random), \
00831 _distUseMarking(false), \
00832 _distributionP(NULL), \
00833 _duplicateDistance(lb), \
00834 _scanIntervalGenP(NULL), \
00835 _scanFixedIncrement(true), \
00836 _scanIncrement(lb) \
00837 { \
00838 _duplicateDistance = 1; \
00839 _scanIncrement = 1; \
00840 } \
00841 \
00842 _scv_constraint_range_generator_base_ ## TypeId:: \
00843 _scv_constraint_range_generator_base_ ## TypeId(const _scv_constraint_range_generator_base_ ## TypeId& rhs, \
00844 const char * nameP) \
00845 : _nameP(nameP), \
00846 _simpleConstraint(rhs._simpleConstraint), \
00847 _onGoingConstraintValid(rhs._onGoingConstraintValid), \
00848 _onGoingConstraint(rhs._onGoingConstraint), \
00849 _currentScanValueValid(rhs._currentScanValueValid), \
00850 _currentScanValue(rhs._currentScanValue), \
00851 _randomP(rhs._randomP), \
00852 _distUseMarking(rhs._distUseMarking), \
00853 _distributionP(NULL), \
00854 _duplicateDistance(rhs._duplicateDistance), \
00855 _scanIntervalGenP(NULL), \
00856 _scanFixedIncrement(rhs._scanFixedIncrement), \
00857 _scanIncrement(rhs._scanIncrement) \
00858 { \
00859 if (rhs._distributionP) { \
00860 _distributionP = new scv_bag<EltT>(*rhs._distributionP); \
00861 _distributionP->setRandom(*_randomP); \
00862 } \
00863 if (rhs._scanIntervalGenP) \
00864 _scanIntervalGenP = new _scv_constraint_range_ ## TypeId(*rhs._scanIntervalGenP); \
00865 } \
00866 \
00867 void _scv_constraint_range_generator_base_ ## TypeId:: \
00868 setScanInterval(const SizeT& lb, const SizeT& ub) { \
00869 if (_scanIntervalGenP) { \
00870 delete _scanIntervalGenP; \
00871 _scanIntervalGenP = NULL; \
00872 } \
00873 if (lb==0) \
00874 _scv_constraint_range_error::invalidScanInterval(_nameP); \
00875 if (ub==0 || ub<=lb) { \
00876 _scanFixedIncrement = true; \
00877 _scanIncrement = lb; \
00878 } else { \
00879 _scanFixedIncrement = false; \
00880 _scanIntervalGenP = new _scv_constraint_range_ ## TypeId(lb,ub); \
00881 } \
00882 } \
00883 \
00884 void _scv_constraint_range_generator_base_ ## TypeId:: \
00885 setWeightDistribution(const scv_bag<EltT>& bag, bool useMarking) { \
00886 _setWeightDistribution(bag,useMarking); \
00887 if (_distributionP->empty()) { \
00888 _scv_constraint_range_error::invalidDistribution(_nameP,"setWeightDistribution"); \
00889 } \
00890 } \
00891 \
00892 void _scv_constraint_range_generator_base_ ## TypeId:: \
00893 _setWeightDistribution(const scv_bag<EltT>& bag, bool useMarking) { \
00894 _distUseMarking = useMarking; \
00895 if (_distributionP) \
00896 *_distributionP = bag; \
00897 else { \
00898 _distributionP = new scv_bag<EltT>(bag); \
00899 _distributionP->setRandom(*_randomP); \
00900 } \
00901 unsigned int size = _distributionP->distinctSize(); \
00902 for (unsigned int i=0; i<size; ++i) { \
00903 EltT j = _distributionP->peekNext('a',true); \
00904 if (!satisfyConstraints(j)) \
00905 _distributionP->remove(true); \
00906 } \
00907 } \
00908
00909
00910
00911 _SCV_CONSTRAINT_RANGE_GENERATOR_FC_I(int,int,unsigned,true,_scv_random_unsigned);
00912 _SCV_CONSTRAINT_RANGE_GENERATOR_FC_I(unsigned,unsigned,unsigned,true,_scv_random_unsigned);
00913 _SCV_CONSTRAINT_RANGE_GENERATOR_FC_I(double,double,double,false,_scv_random_double);
00914
00915 _SCV_CONSTRAINT_RANGE_GENERATOR_FC_I(long_long,long long,unsigned long long,true,_scv_random_unsigned_ll);
00916 _SCV_CONSTRAINT_RANGE_GENERATOR_FC_I(unsigned_long_long,unsigned long long,unsigned long long,true,_scv_random_unsigned_ll);
00917
00918 _SCV_CONSTRAINT_RANGE_GENERATOR_FC_I(sc_unsigned,sc_unsigned ,sc_unsigned,true,_scv_random_unsigned_big);
00919 _SCV_CONSTRAINT_RANGE_GENERATOR_FC_I(sc_signed ,sc_signed ,sc_unsigned,true,_scv_random_unsigned_big);
00920