00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00027
00028 #include <cstring>
00029 #include <iostream>
00030 #include "ShBitSet.hpp"
00031 #include "ShDebug.hpp"
00032 #include "ShError.hpp"
00033
00034 #define WORD_SIZE sizeof(unsigned int)
00035
00036 namespace {
00037
00038 std::size_t wordsize(std::size_t size)
00039 {
00040 return size / WORD_SIZE + (size % WORD_SIZE ? 1 : 0);
00041 }
00042
00043 std::size_t fullwordsize(std::size_t size)
00044 {
00045 return size / WORD_SIZE;
00046 }
00047
00048 }
00049
00050 namespace SH {
00051
00052 ShBitRef::operator bool() const
00053 {
00054 return (((*m_byte) & m_mask) == m_mask);
00055 }
00056
00057 ShBitRef& ShBitRef::operator=(bool b)
00058 {
00059 if (b) {
00060 *m_byte |= m_mask;
00061 } else {
00062 *m_byte &= ~m_mask;
00063 }
00064
00065 return (*this);
00066 }
00067
00068 ShBitRef::ShBitRef(unsigned int* byte, unsigned int mask)
00069 : m_byte(byte), m_mask(mask)
00070 {
00071 }
00072
00073 ShBitSet::ShBitSet()
00074 : m_size(0), m_data(0)
00075 {
00076 }
00077
00078 ShBitSet::ShBitSet(std::size_t size)
00079 : m_size(size), m_data(new unsigned int[wordsize(m_size)])
00080 {
00081 for (std::size_t i = 0; i < wordsize(m_size); i++) {
00082 m_data[i] = 0;
00083 }
00084 }
00085
00086 ShBitSet::ShBitSet(const ShBitSet& other)
00087 : m_size(other.m_size), m_data(new unsigned int[wordsize(m_size)])
00088 {
00089 memcpy(m_data, other.m_data, wordsize(m_size) * WORD_SIZE);
00090 }
00091
00092 ShBitSet::~ShBitSet()
00093 {
00094 delete [] m_data;
00095 }
00096
00097 ShBitSet& ShBitSet::operator=(const ShBitSet& other)
00098 {
00099 delete [] m_data;
00100 m_size = other.m_size;
00101 m_data = new unsigned int[wordsize(m_size)];
00102 memcpy(m_data, other.m_data, wordsize(m_size) * WORD_SIZE);
00103
00104 return (*this);
00105 }
00106
00107 ShBitSet& ShBitSet::operator&=(const ShBitSet& other)
00108 {
00109 if (m_size != other.m_size) shError( ShException( "ShBitSet operands of &= must be the same size." ) );
00110 for (std::size_t i = 0; i < wordsize(m_size); i++)
00111 m_data[i] &= other.m_data[i];
00112 return *this;
00113 }
00114
00115 ShBitSet& ShBitSet::operator|=(const ShBitSet& other)
00116 {
00117 if (m_size != other.m_size) shError( ShException( "ShBitSet operands of |= must be the same size." ) );
00118 for (std::size_t i = 0; i < wordsize(m_size); i++)
00119 m_data[i] |= other.m_data[i];
00120 return *this;
00121 }
00122
00123 ShBitSet& ShBitSet::operator^=(const ShBitSet& other)
00124 {
00125 if (m_size != other.m_size) shError( ShException( "ShBitSet operands of ^= must be the same size." ) );
00126 for (std::size_t i = 0; i < wordsize(m_size); i++)
00127 m_data[i] ^= other.m_data[i];
00128 return *this;
00129 }
00130
00131 ShBitSet ShBitSet::operator&(const ShBitSet& other) const
00132 {
00133 ShBitSet ret(*this);
00134 ret &= other;
00135 return ret;
00136 }
00137
00138 ShBitSet ShBitSet::operator|(const ShBitSet& other) const
00139 {
00140 ShBitSet ret(*this);
00141 ret |= other;
00142 return ret;
00143 }
00144
00145 ShBitSet ShBitSet::operator^(const ShBitSet& other) const
00146 {
00147 ShBitSet ret(*this);
00148 ret ^= other;
00149 return ret;
00150 }
00151
00152 ShBitSet ShBitSet::operator~() const
00153 {
00154 ShBitSet ret(m_size);
00155 for (std::size_t i = 0; i < wordsize(m_size); i++)
00156 ret.m_data[i] = ~m_data[i];
00157 return ret;
00158 }
00159
00160 bool ShBitSet::operator==(const ShBitSet& other) const
00161 {
00162 if (m_size != other.m_size) return false;
00163 for (unsigned int i = 0; i < fullwordsize(m_size); i++) {
00164 if (m_data[i] != other.m_data[i]) return false;
00165 }
00166 if (m_size % WORD_SIZE) {
00167 unsigned int mask = (1 << ((m_size % WORD_SIZE) + 1)) - 1;
00168 return ((m_data[m_size / WORD_SIZE] & mask) == (other.m_data[m_size / WORD_SIZE] & mask));
00169 }
00170 return true;
00171 }
00172
00173 bool ShBitSet::operator!=(const ShBitSet& other) const
00174 {
00175 return !(*this == other);
00176 }
00177
00178 std::size_t ShBitSet::size() const
00179 {
00180 return m_size;
00181 }
00182
00183 bool ShBitSet::full() const
00184 {
00185 for (int i = 0; i < fullwordsize(m_size); i++) {
00186 if (~m_data[i]) return false;
00187 }
00188 if (m_size % WORD_SIZE) {
00189 unsigned int mask = (1 << ((m_size % WORD_SIZE) + 1)) - 1;
00190 return (m_data[m_size / WORD_SIZE] & mask) == mask;
00191 }
00192
00193 return true;
00194 }
00195
00196 bool ShBitSet::empty() const
00197 {
00198 for (int i = 0; i < wordsize(m_size); i++) if (m_data[i]) return false;
00199 return true;
00200 }
00201
00202 bool ShBitSet::operator[](std::size_t i) const
00203 {
00204 return ((m_data[i / WORD_SIZE] & (1 << (i % WORD_SIZE))) != 0);
00205 }
00206
00207 ShBitRef ShBitSet::operator[](std::size_t i)
00208 {
00209 return ShBitRef(m_data + (i / WORD_SIZE), 1 << (i % WORD_SIZE));
00210 }
00211
00212 std::ostream& operator<<(std::ostream& out, const ShBitSet& bitset)
00213 {
00214 for (std::size_t i = 0; i < bitset.size(); i++) {
00215 out << (bitset[i] ? '1' : '0');
00216 }
00217 return out;
00218 }
00219
00220 }