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