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
00026
00027
00028
00029 #ifndef __SEAL_BITREG_H__
00030 #define __SEAL_BITREG_H__
00031
00032 #include "config.h"
00033 #include "exception.h"
00034 #include <sstream>
00035
00036 namespace seal
00037 {
00038
00042 template <unsigned int bits>
00043 class BitReg
00044 {
00045 public:
00046
00050 BitReg(void);
00051
00054 BitReg(const BitReg<bits> ®);
00055
00059 BitReg(const int val);
00060
00063 ~BitReg();
00064
00070 inline bool get(const int index) const throw(OutOfRangeException<int>);
00071
00078 inline void set(const int index, bool val) throw(OutOfRangeException<int>);
00079
00083 void operator=(const int rhs);
00084
00088 void operator=(const BitReg<bits> ®);
00089
00093 template <unsigned int rbits>
00094 void operator=(const BitReg<rbits> ®);
00095
00098 void operator<<(const int val);
00099
00102 void operator>>(const int val);
00103
00106 template <unsigned int rbits>
00107 BitReg<bits+rbits> operator,(const BitReg<rbits> ®);
00108
00109 private:
00110 unsigned char data[bits/SIZEOF_UCHAR + ((bits%SIZEOF_UCHAR > 0) ? 1 : 0)];
00111 };
00112
00113 template <unsigned int bits>
00114 BitReg<bits>::BitReg()
00115 {
00116 int bytes = bits/SIZEOF_UCHAR + ((bits%SIZEOF_UCHAR > 0) ? 1 : 0);
00117 for (int i = 0; i < bytes; i++)
00118 data[i] = 0;
00119 }
00120
00121 template <unsigned int bits>
00122 BitReg<bits>::BitReg(const BitReg<bits> ®)
00123 {
00124 int bytes = bits/SIZEOF_UCHAR + ((bits%SIZEOF_UCHAR > 0) ? 1 : 0);
00125 for (int i = 0; i < bytes; i++)
00126 data[i] = reg.data[i];
00127 }
00128
00129 template <unsigned int bits>
00130 BitReg<bits>::BitReg(const int val)
00131 {
00132 for (int i = 0; i < bits; i++)
00133 set(i, ((val & (1 << i)) > 0) ? true : false);
00134 }
00135
00136 template <unsigned int bits>
00137 BitReg<bits>::~BitReg()
00138 {}
00139
00140 template <unsigned int bits>
00141 bool BitReg<bits>::get(const int index) const throw(OutOfRangeException<int>)
00142 {
00143 if (index < 0 || index >= bits)
00144 throw OutOfRangeException<int>(0, bits-1, index);
00145
00146 int byte = index / SIZEOF_UCHAR, byteIndex = index % SIZEOF_UCHAR;
00147
00148 unsigned int byteVal = data[byte];
00149 return ((byteVal & (1 << byteIndex)) > 0 ? 1 : 0);
00150 }
00151
00152 template <unsigned int bits>
00153 void BitReg<bits>::set(const int index, bool val) throw(OutOfRangeException<int>)
00154 {
00155 if (index < 0 || index >= bits)
00156 throw OutOfRangeException<int>(0, bits-1, index);
00157
00158 int byte = index / SIZEOF_UCHAR, byteIndex = index % SIZEOF_UCHAR;
00159 if (val)
00160 data[byte] = data[byte] | (1 << byteIndex);
00161 else
00162 data[byte] = data[byte] & (255 ^ (1 << byteIndex));
00163 }
00164
00165 template <unsigned int bits>
00166 void BitReg<bits>::operator=(const int rhs)
00167 {
00168 for (int i = 0; i < bits; i++)
00169 set(i, ((rhs & (1 << i)) > 0) ? true : false);
00170 }
00171
00172 template <unsigned int bits>
00173 void BitReg<bits>::operator=(const BitReg<bits> ®)
00174 {
00175 int bytes = bits/SIZEOF_UCHAR + ((bits%SIZEOF_UCHAR > 0) ? 1 : 0);
00176 for (int i = 0; i < bytes; i++)
00177 data[i] = reg.data[i];
00178 }
00179
00180 template <unsigned int lbits>
00181 template <unsigned int rbits>
00182 void BitReg<lbits>::operator=(const BitReg<rbits> ®)
00183 {
00184 unsigned int bits = lbits > rbits ? lbits : rbits;
00185 int bytes = bits/SIZEOF_UCHAR + ((bits%SIZEOF_UCHAR > 0) ? 1 : 0);
00186
00187 for (int i = 0; i < bytes; i++)
00188 data[i] = reg.data[i];
00189 }
00190
00191 template <unsigned int bits>
00192 void BitReg<bits>::operator<<(const int val)
00193 {
00194 if (val >= bits)
00195 {
00196 int bytes = bits/SIZEOF_UCHAR + ((bits%SIZEOF_UCHAR > 0) ? 1 : 0);
00197 for (int i = 0; i < bytes; i++)
00198 data[i] = 0;
00199
00200 return;
00201 }
00202
00203 for (int i = bits-1; i-val >= 0; i--)
00204 set(i, get(i-val));
00205
00206 for (int i = 0; i < val; i++)
00207 set(i, false);
00208 }
00209
00210 template <unsigned int bits>
00211 void BitReg<bits>::operator>>(const int val)
00212 {
00213 if (val >= bits)
00214 {
00215 int bytes = bits/SIZEOF_UCHAR + ((bits%SIZEOF_UCHAR > 0) ? 1 : 0);
00216 for (int i = 0; i < bytes; i++)
00217 data[i] = 0;
00218
00219 return;
00220 }
00221
00222 for (int i = 0; i+val < bits; i++)
00223 set(i, get(i+val));
00224
00225 for (int i = bits-val; i < bits; i++)
00226 set(i, false);
00227 }
00228
00229 template <unsigned int bits>
00230 template <unsigned int rbits>
00231 BitReg<bits+rbits> BitReg<bits>::operator,(const BitReg<rbits> ®)
00232 {
00233 BitReg<bits+rbits> newReg;
00234 for (int i = 0; i < rbits; i++)
00235 newReg.set(i, reg.get(i));
00236
00237 for (int i = 0; i < bits; i++)
00238 newReg.set(i+rbits, get(i));
00239
00240 return newReg;
00241 }
00242
00243 }
00244
00245 template <unsigned int bits>
00246 std::ostream& operator<<(std::ostream &obj, const seal::BitReg<bits> ®)
00247 {
00248 for (int i = bits-1; i >= 0; i--)
00249 std::cout << (reg.get(i) ? 1 : 0);
00250
00251 return std::cout;
00252 }
00253
00254 template <unsigned int bits>
00255 std::stringstream& operator<<(std::stringstream &obj, const seal::BitReg<bits> ®)
00256 {
00257 for (int i = bits-1; i >= 0; i--)
00258 obj << (reg.get(i) ? 1 : 0);
00259
00260 return obj;
00261 }
00262
00263 #endif // __SEAL_BITREG_H__
00264