Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

VCList.cpp

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file VCList.cpp
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     // update unions/intersections
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     // update unions/intersections
00122     dirty_list_unions();
00123     if (count < m_softlimit) m_soft_intersection &= vc.carrier();
00124     m_hard_intersection &= vc.carrier();
00125 
00126     // remove supersets of vc
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)      // @todo check size for speedup!
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     // @todo abort loops early if intersection is empty?
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 //----------------------------------------------------------------------------


6 Jan 2011 Doxygen 1.6.3