00001
00002
00003
00004
00005
00006 #include "VCList.hpp"
00007 #include "ChangeLog.hpp"
00008
00009 using namespace benzene;
00010
00011
00012
00013 VCList::VCList(HexPoint x, HexPoint y, unsigned int soft)
00014 : m_x(x), m_y(y),
00015 m_softlimit(soft),
00016 m_vcs(),
00017 m_dirty_intersection(false),
00018 m_dirty_union(true)
00019 {
00020 m_soft_intersection.set();
00021 m_hard_intersection.set();
00022 }
00023
00024
00025
00026 std::string VCList::dump() const
00027 {
00028 int i=0;
00029 std::ostringstream os;
00030 const_iterator it, end = m_vcs.end();
00031 for (it = m_vcs.begin(); it != end; ++it) {
00032 os << i++ << ": ";
00033 os << *it;
00034 os << std::endl;
00035 }
00036 return os.str();
00037 }
00038
00039
00040
00041 bool VCList::isSupersetOfAny(const bitset_t& bs) const
00042 {
00043 for (const_iterator it = m_vcs.begin(); it != m_vcs.end(); ++it)
00044 if (BitsetUtil::IsSubsetOf(it->carrier(), bs))
00045 return true;
00046 return false;
00047 }
00048
00049 bool VCList::isSubsetOfAny(const bitset_t& bs) const
00050 {
00051 for (const_iterator it = m_vcs.begin(); it != m_vcs.end(); ++it)
00052 if (BitsetUtil::IsSubsetOf(bs, it->carrier()))
00053 return true;
00054 return false;
00055 }
00056
00057 int VCList::removeSuperSetsOf(const bitset_t& bs, ChangeLog<VC>* log,
00058 bool dirty_intersections)
00059 {
00060 int count = 0;
00061 for (iterator it = m_vcs.begin(); it != m_vcs.end(); )
00062 {
00063 if (BitsetUtil::IsSubsetOf(bs, it->carrier()))
00064 {
00065 if (log) log->push(ChangeLog<VC>::REMOVE, *it);
00066 it = m_vcs.erase(it);
00067 count++;
00068 }
00069 else
00070 ++it;
00071 }
00072 if (count)
00073 {
00074 dirty_list_unions();
00075 if (dirty_intersections)
00076 dirty_list_intersections();
00077 }
00078 return count;
00079 }
00080
00081
00082
00083 void VCList::simple_add(const VC& vc)
00084 {
00085 HexAssert((vc.x() == getX() && vc.y() == getY()) ||
00086 (vc.x() == getY() && vc.y() == getX()));
00087
00088 iterator it;
00089 unsigned count = 0;
00090 for (it = m_vcs.begin(); it != m_vcs.end(); ++it, ++count) {
00091 if (*it > vc)
00092 break;
00093 }
00094 it = m_vcs.insert(it, vc);
00095
00096
00097 dirty_list_unions();
00098 if (count < m_softlimit) m_soft_intersection &= vc.carrier();
00099 m_hard_intersection &= vc.carrier();
00100 }
00101
00102 VCList::AddResult VCList::add(const VC& vc, ChangeLog<VC>* log)
00103 {
00104 HexAssert((vc.x() == getX() && vc.y() == getY()) ||
00105 (vc.x() == getY() && vc.y() == getX()));
00106
00107 unsigned count = 0;
00108 iterator it = m_vcs.begin();
00109 for (; it != m_vcs.end(); ++it, ++count)
00110 {
00111 if (*it > vc)
00112 break;
00113
00114 if ((*it).isSubsetOf(vc))
00115 return ADD_FAILED;
00116 }
00117
00118 if (log) log->push(ChangeLog<VC>::ADD, vc);
00119 it = m_vcs.insert(it, vc);
00120
00121
00122 dirty_list_unions();
00123 if (count < m_softlimit) m_soft_intersection &= vc.carrier();
00124 m_hard_intersection &= vc.carrier();
00125
00126
00127 for (++it; it != m_vcs.end(); )
00128 {
00129 if (vc.isSubsetOf(*it))
00130 {
00131 if (log) log->push(ChangeLog<VC>::REMOVE, *it);
00132 it = m_vcs.erase(it);
00133
00134 } else {
00135 ++it;
00136 }
00137 }
00138
00139 return (count < m_softlimit) ?
00140 ADDED_INSIDE_SOFT_LIMIT:
00141 ADDED_INSIDE_HARD_LIMIT;
00142 }
00143
00144 int VCList::add(const VCList& other, ChangeLog<VC>* log)
00145 {
00146 int count = 0;
00147 for (const_iterator it = other.begin(); it != other.end(); ++it)
00148 {
00149 VC v(getX(), getY(), it->key(), it->carrier(), it->rule());
00150 v.setProcessed(false);
00151 if (this->add(v, log))
00152 count++;
00153 }
00154 return count;
00155 }
00156
00157
00158
00159 VCList::iterator VCList::remove(iterator it, ChangeLog<VC>* log)
00160 {
00161 if (log) log->push(ChangeLog<VC>::REMOVE, *it);
00162 it = m_vcs.erase(it);
00163
00164 dirty_list_unions();
00165 dirty_list_intersections();
00166 return it;
00167 }
00168
00169 bool VCList::remove(const VC& vc, ChangeLog<VC>* log)
00170 {
00171 iterator it = find(vc);
00172 if (it == end())
00173 return false;
00174
00175 remove(it, log);
00176 return true;
00177 }
00178
00179
00180
00181 VCList::const_iterator VCList::find(const VC& vc,
00182 const const_iterator& b,
00183 const const_iterator& e) const
00184 {
00185 const_iterator it = b;
00186 for (; it != e; ++it) {
00187 if (vc == *it)
00188 break;
00189 }
00190 return it;
00191 }
00192
00193 VCList::const_iterator VCList::find(const VC& vc) const
00194 {
00195 return find(vc, begin(), end());
00196 }
00197
00198 VCList::iterator VCList::find(const VC& vc,
00199 const iterator& b,
00200 const iterator& e)
00201 {
00202 iterator it = b;
00203 for (; it != e; ++it) {
00204 if (vc == *it)
00205 break;
00206 }
00207 return it;
00208 }
00209
00210 VCList::iterator VCList::find(const VC& vc)
00211 {
00212 return find(vc, begin(), end());
00213 }
00214
00215
00216
00217 void VCList::computeUnions() const
00218 {
00219 bitset_t inter;
00220 inter.set();
00221 m_union.reset();
00222 m_greedy_union.reset();
00223
00224 const_iterator cur = m_vcs.begin();
00225 const_iterator end = m_vcs.end();
00226 for (; cur!=end; ++cur) {
00227 m_union |= cur->carrier();
00228 bitset_t c = inter & cur->carrier();
00229 if (inter != c) {
00230 m_greedy_union |= cur->carrier();
00231 inter = c;
00232 }
00233 }
00234 m_dirty_union = false;
00235 }
00236
00237 bitset_t VCList::getUnion() const
00238 {
00239 if (m_dirty_union) {
00240 computeUnions();
00241 }
00242 return m_union;
00243 }
00244
00245 bitset_t VCList::getGreedyUnion() const
00246 {
00247 if (m_dirty_union) {
00248 computeUnions();
00249 }
00250 return m_greedy_union;
00251 }
00252
00253
00254
00255 void VCList::computeIntersections() const
00256 {
00257 m_soft_intersection.set();
00258 const_iterator cur = m_vcs.begin();
00259 const_iterator end = m_vcs.end();
00260
00261
00262 for (int count=0; count<softlimit() && cur!=end; ++cur, ++count) {
00263 m_soft_intersection &= cur->carrier();
00264 }
00265 m_hard_intersection = m_soft_intersection;
00266
00267 for (; cur != end; ++cur) {
00268 m_hard_intersection &= cur->carrier();
00269 }
00270
00271 m_dirty_intersection = false;
00272 }
00273
00274 bitset_t VCList::softIntersection() const
00275 {
00276 if (m_dirty_intersection) {
00277 computeIntersections();
00278 }
00279 return m_soft_intersection;
00280 }
00281
00282 bitset_t VCList::hardIntersection() const
00283 {
00284 if (m_dirty_intersection) {
00285 computeIntersections();
00286 }
00287 return m_hard_intersection;
00288 }
00289
00290
00291
00292 int VCList::removeAllContaining(HexPoint cell, std::list<VC>& out,
00293 ChangeLog<VC>* log)
00294 {
00295 if (!getUnion().test(cell))
00296 return 0;
00297
00298 int count = 0;
00299 for (iterator it = m_vcs.begin(); it != m_vcs.end(); ) {
00300 if (it->carrier().test(cell)) {
00301 out.push_back(*it);
00302 if (log) log->push(ChangeLog<VC>::REMOVE, *it);
00303 it = m_vcs.erase(it);
00304 ++count;
00305 } else {
00306 ++it;
00307 }
00308 }
00309
00310 if (count) {
00311 dirty_list_unions();
00312 dirty_list_intersections();
00313 }
00314 return count;
00315 }
00316
00317 int VCList::removeAllContaining(const bitset_t& b, std::list<VC>& out,
00318 ChangeLog<VC>* log)
00319 {
00320 if ((getUnion() & b).none())
00321 return 0;
00322
00323 int count = 0;
00324 for (iterator it = m_vcs.begin(); it != m_vcs.end(); ) {
00325 if ((it->carrier() & b).any()) {
00326 out.push_back(*it);
00327 if (log) log->push(ChangeLog<VC>::REMOVE, *it);
00328 it = m_vcs.erase(it);
00329 ++count;
00330 } else {
00331 ++it;
00332 }
00333 }
00334
00335 if (count) {
00336 dirty_list_unions();
00337 dirty_list_intersections();
00338 }
00339 return count;
00340 }
00341
00342 int VCList::removeAllContaining(const bitset_t& b, ChangeLog<VC>* log)
00343 {
00344 if ((getUnion() & b).none())
00345 return 0;
00346
00347 int count = 0;
00348 for (iterator it = m_vcs.begin(); it != m_vcs.end(); ) {
00349 if ((it->carrier() & b).any()) {
00350 if (log) log->push(ChangeLog<VC>::REMOVE, *it);
00351 it = m_vcs.erase(it);
00352 ++count;
00353 } else {
00354 ++it;
00355 }
00356 }
00357
00358 if (count) {
00359 dirty_list_unions();
00360 dirty_list_intersections();
00361 }
00362 return count;
00363 }
00364
00365
00366
00367 bool VCList::operator==(const VCList& other) const
00368 {
00369 if (m_softlimit != other.m_softlimit)
00370 return false;
00371 if (size() != other.size())
00372 return false;
00373
00374 const_iterator us = begin();
00375 const_iterator them = other.begin();
00376 while (us != end()) {
00377 if (*us != *them) return false;
00378 if (us->processed() != them->processed()) return false;
00379 ++us;
00380 ++them;
00381 }
00382 return true;
00383 }
00384
00385 bool VCList::operator!=(const VCList& other) const
00386 {
00387 if (size() != other.size())
00388 return true;
00389
00390 const_iterator us = begin();
00391 const_iterator them = other.begin();
00392 while (us != end()) {
00393 if (*us != *them) return true;
00394 if (us->processed() != them->processed()) return true;
00395 ++us;
00396 ++them;
00397 }
00398 return false;
00399 }
00400
00401