00001
00002
00003
00004
00005
00006
00007
00008
00012 #ifndef ZYPP_BIT_H
00013 #define ZYPP_BIT_H
00014
00015 #include <iosfwd>
00016 #include <string>
00017
00018 #include "zypp/base/SafeBool.h"
00019
00021 namespace zypp
00022 {
00023
00024
00030 namespace bit
00031 {
00032
00033 namespace bit_detail
00034 {
00036 template<class _IntT, unsigned _size>
00037 struct Gen1Bits
00038 {
00039 static const _IntT value = (Gen1Bits<_IntT,_size-1>::value << 1)+1;
00040 };
00042 template<class _IntT>
00043 struct Gen1Bits<_IntT, 0>
00044 {
00045 static const _IntT value = 0;
00046 };
00047 }
00048
00050 template<class _IntT>
00051 struct MaxBits
00052 {
00053 typedef _IntT IntT;
00054 static const unsigned value = (sizeof(IntT)*8);
00055 };
00056
00058 template<class _IntT>
00059 inline std::string asString( _IntT val, char zero = '0', char one = '1' )
00060 {
00061 std::string s( MaxBits<_IntT>::value, zero );
00062 for( unsigned i = MaxBits<_IntT>::value; i; )
00063 {
00064 --i;
00065 if ( val & (_IntT)1 )
00066 s[i] = one;
00067 val = val >> 1;
00068 };
00069 return s;
00070 }
00071
00073 template<class _IntT, unsigned _begin, unsigned _size>
00074 struct Mask
00075 {
00076 typedef _IntT IntT;
00077 static const IntT value = bit_detail::Gen1Bits<IntT,_size>::value << _begin;
00078 static const IntT inverted = ~value;
00079 };
00080
00082 template<class _IntT, unsigned _begin, unsigned _size>
00083 struct Range
00084 {
00085 typedef _IntT IntT;
00086 typedef MaxBits<IntT> MaxBits;
00087 typedef Mask<IntT,_begin,_size> Mask;
00088
00089 static const unsigned begin = _begin;
00090 static const unsigned size = _size;
00091 static const unsigned end = _begin + _size;
00092 };
00097 template<class _IntT, unsigned _begin>
00098 struct Range<_IntT, _begin, 0>
00099 {};
00100
00111 template<class _Range, typename _Range::IntT _value>
00112 struct RangeValue
00113 {
00114 typedef _Range RangeT;
00115 typedef typename _Range::IntT IntT;
00116
00117 static const IntT value = _value << RangeT::begin;
00118 };
00119
00129 template<class _Range, unsigned _pos>
00130 struct RangeBit
00131 {
00132 typedef _Range RangeT;
00133 typedef typename _Range::IntT IntT;
00134
00135 static const IntT value = IntT(1) << (RangeT::begin + _pos);
00136 };
00137
00139
00140
00141
00160 template<class _IntT>
00161 class BitField : public Range<_IntT, 0, MaxBits<_IntT>::value>
00162 , public base::SafeBool<BitField<_IntT> >
00163 {
00164 typedef typename base::SafeBool<BitField<_IntT> >::bool_type bool_type;
00165
00166 public:
00168 BitField()
00169 : _value( (_IntT)0 )
00170 {}
00172 BitField( const _IntT & value_r )
00173 : _value( value_r )
00174 {}
00175
00176 public:
00178 using base::SafeBool<BitField<_IntT> >::operator bool_type;
00179
00180 public:
00182 template<class _Range>
00183 _IntT value() const
00184 {
00185 return _value & _Range::Mask::value;
00186 }
00187 _IntT value() const
00188 {
00189 return _value;
00190 }
00191
00193 template<class _Range>
00194 std::string asString() const
00195 {
00196 return bit::asString( _value & _Range::Mask::value, '_' );
00197 }
00198 std::string asString() const
00199 {
00200 return bit::asString( _value, '_' );
00201 }
00202
00204 template<class _Range>
00205 BitField & assign( _IntT rhs )
00206 {
00207 _value = (_value & _Range::Mask::inverted)
00208 | (rhs & _Range::Mask::value);
00209 return *this;
00210 }
00211 BitField & assign( _IntT rhs )
00212 {
00213 _value = rhs;
00214 return *this;
00215 }
00216
00218 template<class _Range>
00219 bool isEqual( _IntT rhs ) const
00220 {
00221 return (_value & _Range::Mask::value)
00222 == (rhs & _Range::Mask::value);
00223 }
00224 bool isEqual( _IntT rhs ) const
00225 {
00226 return _value == rhs;
00227 }
00228 public:
00229
00230 BitField & operator=( const BitField & rhs )
00231 { _value = rhs._value; return *this; }
00232
00233 BitField & operator&=( const BitField & rhs )
00234 { _value &= rhs._value; return *this; }
00235
00236 BitField & operator|=( const BitField & rhs )
00237 { _value |= rhs._value; return *this; }
00238
00239 BitField & operator^=( const BitField & rhs )
00240 { _value ^= rhs._value; return *this; }
00241
00242 BitField & operator<<=( unsigned num )
00243 { _value <<= num; return *this; }
00244
00245 BitField & operator>>=( unsigned num )
00246 { _value >>= num; return *this; }
00247
00248 BitField operator~() const
00249 { return ~_value; }
00250
00251 private:
00252 friend base::SafeBool<BitField<_IntT> >::operator bool_type() const;
00254 bool boolTest() const
00255 { return _value; }
00256
00257 private:
00258 _IntT _value;
00259 };
00261
00263 template<class _IntT>
00264 std::ostream & operator<<( std::ostream & str, const BitField<_IntT> & obj )
00265 {
00266 return str << obj.asString();
00267 }
00268
00269
00271 template<class _IntT>
00272 inline bool operator==( const BitField<_IntT> & lhs, const BitField<_IntT> & rhs )
00273 { return lhs.value() == rhs.value(); }
00274
00276 template<class _IntT>
00277 inline bool operator!=( const BitField<_IntT> & lhs, const BitField<_IntT> & rhs )
00278 { return ! (lhs == rhs); }
00279
00280
00282 template<class _IntT>
00283 inline BitField<_IntT> operator&( const BitField<_IntT> & lhs, const BitField<_IntT> & rhs )
00284 { return BitField<_IntT>(lhs) &= rhs; }
00285
00287 template<class _IntT>
00288 inline BitField<_IntT> operator|( const BitField<_IntT> & lhs, const BitField<_IntT> & rhs )
00289 { return BitField<_IntT>(lhs) |= rhs; }
00290
00292 template<class _IntT>
00293 inline BitField<_IntT> operator^( const BitField<_IntT> & lhs, const BitField<_IntT> & rhs )
00294 { return BitField<_IntT>(lhs) ^= rhs; }
00295
00297 template<class _IntT>
00298 inline BitField<_IntT> operator<<( const BitField<_IntT> & lhs, unsigned num )
00299 { return BitField<_IntT>(lhs) <<= num; }
00300
00302 template<class _IntT>
00303 inline BitField<_IntT> operator>>( const BitField<_IntT> & lhs, unsigned num )
00304 { return BitField<_IntT>(lhs) >>= num; }
00305
00307 }
00310 }
00312 #endif // ZYPP_BIT_H