Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

Bitset.hpp

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file Bitset.hpp
00003  */
00004 //----------------------------------------------------------------------------
00005 
00006 #ifndef BITSET_HPP
00007 #define BITSET_HPP
00008 
00009 #include <cassert>
00010 #include <set>
00011 #include <string>
00012 #include <vector>
00013 
00014 #include "Benzene.hpp"
00015 #include "Types.hpp"
00016 
00017 /** If true, uses our own bitset, otherwise std::bitset.
00018 
00019     Homebrewed bitset is a copy of std::bitset with subset and
00020     less-than operations built in. Using the homebrewed bitset should
00021     improve performance slightly.
00022 
00023     If you are getting compile errors, switch to the stl bitset.
00024  */
00025 #define USE_HOMEBREWED_BITSET   1
00026 
00027 #if USE_HOMEBREWED_BITSET
00028 #include "BenzeneBitset.hpp"
00029 #else
00030 #include <bitset>
00031 #endif
00032 
00033 _BEGIN_BENZENE_NAMESPACE_
00034 
00035 //----------------------------------------------------------------------------
00036 
00037 /** Maximum size of a bitset. 
00038     Very important. Only mess with this if you know what you are
00039     doing!
00040 */
00041 #if defined(SUPPORT_19x19)
00042 
00043 /** Actually need only 361+7 for 19x19. */
00044 static const int BITSETSIZE = 384;
00045 
00046 #elif defined(SUPPORT_14x14)
00047 
00048 /** Actually need only 196+7 for 14x14. */
00049 static const int BITSETSIZE = 224;
00050 
00051 #elif defined(SUPPORT_13x13)
00052 
00053 /** Actually need only 169+7 for 13x13. */
00054 static const int BITSETSIZE = 192;
00055 
00056 #else
00057 
00058 /** Fits 11x11 exactly. */
00059 static const int BITSETSIZE = 128;
00060 
00061 #endif
00062 
00063 //----------------------------------------------------------------------------
00064 
00065 /** Standard-sized bitset. */
00066 typedef benzene_bitset<BITSETSIZE> bitset_t;
00067 
00068 /** Global empty bitset. */
00069 static const bitset_t EMPTY_BITSET;
00070 
00071 //----------------------------------------------------------------------------
00072 
00073 /** Utilities on bitsets. */
00074 namespace BitsetUtil 
00075 {
00076     /** Converts the bottom numbits of b into a byte stream. */
00077     void BitsetToBytes(const bitset_t& b, byte* out, int numbits);
00078     
00079     /** Converts a byte stream into a bitset. */
00080     bitset_t BytesToBitset(const byte* bytes, int numbits);
00081 
00082     /** Converts a bitset into a string of hex symbols. */
00083     std::string BitsetToHex(const bitset_t& b, int numbits);
00084 
00085     /** Converts a string of hex symbols into a bitset. */
00086     bitset_t HexToBitset(const std::string& str);
00087 
00088     //------------------------------------------------------------------------
00089 
00090     /** Subtracts b2 from b1. */
00091     bitset_t Subtract(const bitset_t& b1, const bitset_t& b2);
00092 
00093     /** If removeFrom - remove is not empty, stores that value in
00094         removeFrom and returns true.  Otherwise, removeFrom is not
00095         changed and returns false. */
00096     bool SubtractIfLeavesAny(bitset_t& removeFrom, const bitset_t& remove);
00097 
00098     /** Returns true if b1 is a subset of b2. */
00099     bool IsSubsetOf(const bitset_t& b1, const bitset_t& b2);
00100     
00101     /** Returns true if b1 comes before b2 in some consistent order
00102         (any well defined ordering, not necessarily lexicographic). */
00103     bool IsLessThan(const bitset_t& b1, const bitset_t& b2);
00104 
00105     //------------------------------------------------------------------------
00106 
00107     /** Stores indices of set bits in b in indices. 
00108         @note INT must be convertible to an int.
00109     */
00110     template<typename INT>
00111     void BitsetToVector(const bitset_t& b, std::vector<INT>& indices);
00112 
00113     /** Converts of set of indices into a bitset with those bits set. 
00114         @note INT must be convertible to an int. 
00115      */
00116     template<typename INT>
00117     bitset_t SetToBitset(const std::set<INT>& indices);
00118     
00119     //------------------------------------------------------------------------
00120 
00121     /** Returns the bit that is set in b. */
00122     int FindSetBit(const bitset_t& b);
00123 
00124     /** Returns least-significant set bit in b. */
00125     int FirstSetBit(const bitset_t& b);
00126 }
00127 
00128 //----------------------------------------------------------------------------
00129 
00130 template<typename INT>
00131 void BitsetUtil::BitsetToVector(const bitset_t& b, 
00132                                 std::vector<INT>& indices)
00133 {
00134     indices.clear();
00135     for (int i=0; i<BITSETSIZE; i++) {
00136         if (b.test(i))
00137             indices.push_back(static_cast<INT>(i));
00138     }
00139     assert(b.count() == indices.size());
00140 }
00141 
00142 template<typename INT>
00143 bitset_t BitsetUtil::SetToBitset(const std::set<INT>& indices)
00144 {
00145     bitset_t ret;
00146     typedef typename std::set<INT>::const_iterator const_iterator;
00147     for (const_iterator it=indices.begin(); 
00148          it != indices.end();
00149          ++it) 
00150     {
00151         ret.set(static_cast<int>(*it));
00152     }
00153     return ret;
00154 }
00155 
00156 //----------------------------------------------------------------------------
00157 
00158 inline bool BitsetUtil::IsSubsetOf(const bitset_t& b1, const bitset_t& b2)
00159 {
00160 #if USE_HOMEBREWED_BITSET
00161     return b1.is_subset_of(b2);
00162 #else
00163     return ((b1 & b2) == b1);
00164 #endif
00165 }
00166 
00167 inline bool BitsetUtil::IsLessThan(const bitset_t& b1, const bitset_t& b2)
00168 {
00169 #if USE_HOMEBREWED_BITSET
00170     return b1.is_less_than(b2);
00171 #else
00172     // holy crap this is sloooow!
00173     for (int i = 0; i < BITSETSIZE; ++i) 
00174     {
00175         if (b1[i] != b2[i]) 
00176             return !b1[i];
00177     }
00178 #endif
00179 }
00180 
00181 //----------------------------------------------------------------------------
00182 
00183 /** Extends the standard binary '-' operator for bitsets. */
00184 bitset_t operator-(const bitset_t& b1, const bitset_t& b2);
00185 
00186 //----------------------------------------------------------------------------
00187 
00188 _END_BENZENE_NAMESPACE_
00189 
00190 #endif // BITSET_HPP


6 Jan 2011 Doxygen 1.6.3