Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

VCList.hpp

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file VCList.hpp
00003  */
00004 //----------------------------------------------------------------------------
00005 
00006 #ifndef VCLIST_HPP
00007 #define VCLIST_HPP
00008 
00009 #include "ChangeLog.hpp"
00010 #include "VC.hpp"
00011 
00012 _BEGIN_BENZENE_NAMESPACE_
00013 
00014 //----------------------------------------------------------------------
00015 
00016 /** Sorted list of VCs.
00017    
00018     The list is sorted by VC carrier size. When VCs are added, only
00019     VCs that are not duplicates or supersets of existing VCs in the
00020     list are considered; any elements currently in the list that are
00021     supersets of the new vc are removed. This means an add operation
00022     will run in linear time.
00023 
00024     The soft limit is the number of vcs used in vc calculations.  VCs
00025     that appear after the soft limit are not considered in vc
00026     calculations, but may be later on if some vcs are removed.  The
00027     idea is to keep around extra vcs that may be important later, but
00028     not at the expense of slower vc calculations now.
00029 */
00030 class VCList
00031 {
00032 public:
00033 
00034     /** Creates a list with given limits. */
00035     VCList(HexPoint x, HexPoint y, unsigned int soft);
00036 
00037     HexPoint getX() const;
00038     
00039     HexPoint getY() const;
00040 
00041     /** Returns the soft limit. */
00042     int softlimit() const;
00043 
00044     /** See softlimit() */
00045     void setSoftLimit(int limit);
00046 
00047     /** Empties the list and the changelog. */
00048     void clear();
00049 
00050     /** Returns the number of VCs in this list. */
00051     std::size_t size() const;
00052 
00053     /** Returns true if the list is empty. */
00054     bool empty() const;
00055 
00056     /** Dumps the contents of this list to a string. */
00057     std::string dump() const;
00058 
00059     //----------------------------------------------------------------------
00060 
00061     /** Returns true if bs is superset of connection in list. */
00062     bool isSupersetOfAny(const bitset_t& vc) const;
00063 
00064     /** Returns true if vc is subset of connection in list. */
00065     bool isSubsetOfAny(const bitset_t& vc) const;
00066 
00067     /** Removes any connection whose carrier is a superset of the
00068         given VC's carrier.  Returns number of connections
00069         removed. Does not dirty intersections if flag is set to false;
00070         only use this if you are for sure only removing supersets of a
00071         member of this list!
00072     */
00073     int removeSuperSetsOf(const bitset_t& vc, ChangeLog<VC>* log,
00074                           bool dirty_intersections = true);
00075    
00076     //----------------------------------------------------------------------
00077     
00078     /** @name Adding connections */
00079     // @{
00080 
00081     /** Return type for add() methods. */
00082     typedef enum 
00083     { 
00084         /** Add did not succeed, list is unchanged. */
00085         ADD_FAILED = 0, 
00086 
00087         /** Added connection within the soft limit. */
00088         ADDED_INSIDE_SOFT_LIMIT = 1, 
00089         
00090         /** Add connection within the hard limit. */
00091         ADDED_INSIDE_HARD_LIMIT = 2 
00092 
00093     } AddResult;
00094 
00095     /** Adds vc to the list.  
00096         
00097         Requires a single pass over the entire list. The add will fail
00098         if vc is a superset of some vc already in the list.  Supersets
00099         of this vc that are already in the list are removed.  
00100         
00101         Operations will be recorded in the log if log is not 0.
00102 
00103         @return true if the VC was added, false otherwise.
00104     */
00105     AddResult add(const VC& vc, ChangeLog<VC>* log);
00106 
00107 
00108     /** Adds the elements of other to list. Returns number of vcs
00109         added. Vcs are added as unprocessed. 
00110         Operations will be recorded in the log if log is not 0. */
00111     int add(const VCList& other, ChangeLog<VC>* log);
00112 
00113     /** 
00114      * Force the addition of this vc.  Used by VCSet::revert():
00115      *
00116      *    1) add(vc) can cause a superset to vc to be removed.
00117      *    2) this superset is then added to the log
00118      *    3) when reverting the log, we try to add the superset,
00119      *       but the add fails because vc is still in it.  
00120      *    4) Ooops!
00121      *
00122      *  This method does NO checks.  It simply adds vc into the
00123      *  proper position according to the ordering on the vcs.
00124      */
00125     void simple_add(const VC& vc);
00126 
00127     // @}
00128 
00129     //----------------------------------------------------------------------
00130 
00131     /** @name Iterators */
00132     // @{
00133 
00134     typedef std::list<VC>::iterator iterator;
00135 
00136     typedef std::list<VC>::const_iterator const_iterator;
00137 
00138     /** Returns an iterator to the given VC, or end() if vc is not in
00139         the list. Note that these methods are not constant, but as
00140         long as VCs are immutable (except for their processed flags)
00141         then the list cannot be altered by these methods. */
00142     iterator find(const VC& vc);
00143     iterator find(const VC& vc, const iterator& b, const iterator& e);
00144 
00145     /** Returns a constant iterator to the given VC, or end() if vc is
00146         not in the list. */
00147     const_iterator find(const VC& vc) const;
00148     const_iterator find(const VC& vc, 
00149                         const const_iterator& b, 
00150                         const const_iterator& e) const;
00151 
00152 
00153     /** Removes the element pointed to by i from the list.
00154         @return the next element. */
00155     iterator remove(iterator i, ChangeLog<VC>* log);
00156 
00157     /** Removes the given vc from the list.  Does nothing if vc is not
00158         actually in the list.  Takes O(n) time. Returns true if vc
00159         was actually removed, false otherwise. */
00160     bool remove(const VC& vc, ChangeLog<VC>* log);
00161 
00162     /** Returns an iterator to the start of the list. */
00163     iterator begin();
00164 
00165     /** Returns an iterator just past the end of the list. */
00166     iterator end();
00167 
00168     /** Returns a constant iterator to the start of the list. */
00169     const_iterator begin() const;
00170 
00171     /** Returns a constant iterator just past the end of the list. */
00172     const_iterator end() const;
00173 
00174     // @}
00175 
00176     //----------------------------------------------------------------------
00177 
00178     /** Returns the union of all carriers in the list. */
00179     bitset_t getUnion() const;
00180 
00181     /** Returns the union of all carriers in the list.
00182      
00183         Only includes carriers of VCs in the union if they shrink the
00184         intersection at each step (considered in the sorted order).
00185         
00186         @note Doing this may result in different sets of connections
00187         depending upon the relative order of the vcs in the list.  So,
00188         on an empty board, BLACK can have a slightly different
00189         connection set that WHITE.  Can also result in different vc
00190         connections between non-rotated and rotated versions of the
00191         board.
00192     */
00193     bitset_t getGreedyUnion() const;
00194 
00195     /** Returns soft-limit intersection. If list is empty, the bitset
00196         will have all of its bits set. */
00197     bitset_t softIntersection() const;
00198 
00199     /** Returns hard-limit intersection. If list is empty, the bitset
00200         will have all of its bits set. */
00201     bitset_t hardIntersection() const;
00202 
00203     //----------------------------------------------------------------------
00204 
00205     /** Removes all VCs that intersect with b.  Removed VCs are
00206         appended to out if out---note that the order of the vcs in out
00207         is the same as it was in the original list!  Returns number of
00208         vcs removed. */
00209     int removeAllContaining(HexPoint cell, std::list<VC>& out,
00210                             ChangeLog<VC>* log);
00211 
00212     int removeAllContaining(const bitset_t& b, std::list<VC>& out,
00213                             ChangeLog<VC>* log);
00214 
00215     int removeAllContaining(const bitset_t& b, ChangeLog<VC>* log);
00216    
00217     /** Performs list equality. */
00218     bool operator==(const VCList& other) const;
00219 
00220     /** Performs list inequality. */
00221     bool operator!=(const VCList& other) const;
00222 
00223 protected:
00224 
00225     /** Invalidates the precomputed list unions. */
00226     void dirty_list_unions();
00227 
00228     /** Invalidates the list intersection. */
00229     void dirty_list_intersections();
00230 
00231     /** Computes list unions in one pass: normal and greedy. */
00232     void computeUnions() const;
00233 
00234     /** Computes list intersections in one pass: soft and hard. */
00235     void computeIntersections() const;
00236 
00237     HexPoint m_x, m_y;
00238 
00239     /** See softlimit() */
00240     unsigned int m_softlimit;
00241 
00242     std::list<VC> m_vcs;
00243 
00244     mutable bool m_dirty_intersection;
00245     mutable bitset_t m_soft_intersection;
00246     mutable bitset_t m_hard_intersection;
00247 
00248     mutable bool m_dirty_union;
00249     mutable bitset_t m_union;
00250     mutable bitset_t m_greedy_union;
00251 };
00252 
00253 inline HexPoint VCList::getX() const
00254 {
00255     return m_x;
00256 }
00257 
00258 inline HexPoint VCList::getY() const
00259 {
00260     return m_y;
00261 }
00262 
00263 inline int VCList::softlimit() const
00264 {
00265     return m_softlimit;
00266 }
00267 
00268 inline void VCList::setSoftLimit(int limit)
00269 {
00270     if (limit != (int)m_softlimit)
00271     {
00272         m_softlimit = limit;
00273         m_dirty_intersection = true;
00274     }
00275 }
00276 
00277 // FIXME: size() is might be O(n) for lists:
00278 // keep track of size on our own?
00279 inline std::size_t VCList::size() const
00280 {
00281     return m_vcs.size();
00282 }
00283 
00284 inline bool VCList::empty() const
00285 {
00286     return m_vcs.empty();
00287 }
00288 
00289 inline void VCList::dirty_list_unions()
00290 {
00291     m_dirty_union = true;
00292 }
00293 
00294 inline void VCList::dirty_list_intersections()
00295 {
00296     m_dirty_intersection = true;
00297 }
00298 
00299 inline void VCList::clear()
00300 {
00301     m_vcs.clear();
00302 
00303     dirty_list_unions();
00304     
00305     m_dirty_intersection = false;
00306     m_soft_intersection.set();
00307     m_hard_intersection.set();
00308 }
00309 
00310 inline VCList::iterator VCList::begin()
00311 {
00312     return m_vcs.begin();
00313 }
00314 
00315 inline VCList::iterator VCList::end()
00316 {
00317     return m_vcs.end();
00318 }
00319 
00320 inline VCList::const_iterator VCList::begin() const
00321 {
00322     return m_vcs.begin();
00323 }
00324 
00325 inline VCList::const_iterator VCList::end() const
00326 {
00327     return m_vcs.end();
00328 }
00329 
00330 //----------------------------------------------------------------------------
00331 
00332 _END_BENZENE_NAMESPACE_
00333 
00334 #endif // VCLIST_HPP


6 Jan 2011 Doxygen 1.6.3