Bit.h
Go to the documentation of this file.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 zypp::bit::MaxBits<IntT> MaxBits;
00087 typedef zypp::bit::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 , private 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
00229 public:
00230
00232 template<class _Range>
00233 BitField & set( _IntT rhs, bool doset_r )
00234 { return set( (rhs & _Range::Mask::value), doset_r ); }
00235
00236 BitField & set( _IntT rhs, bool doset_r )
00237 { return doset_r ? set( rhs ) : unset( rhs ); }
00238
00240 template<class _Range>
00241 BitField & set( _IntT rhs )
00242 { return set( rhs & _Range::Mask::value ); }
00243
00244 BitField & set( _IntT rhs )
00245 { _value |= rhs; return *this; }
00246
00248 template<class _Range>
00249 BitField & unset( _IntT rhs )
00250 { return unset( rhs & _Range::Mask::value ); }
00251
00252 BitField & unset( _IntT rhs )
00253 { _value &= ~rhs; return *this; }
00254
00256 template<class _Range>
00257 bool test( _IntT rhs )
00258 { return test( rhs & _Range::Mask::value ); }
00259
00260 bool test( _IntT rhs ) const
00261 { return (_value & rhs) == rhs; }
00262
00264 template<class _Range>
00265 bool testAnyOf( _IntT rhs )
00266 { return testAnyOf( rhs & _Range::Mask::value ); }
00267
00268 bool testAnyOf( _IntT rhs ) const
00269 { return (_value & rhs); }
00270
00271 public:
00272
00273 BitField & operator=( const BitField & rhs )
00274 { _value = rhs._value; return *this; }
00275
00276 BitField & operator&=( const BitField & rhs )
00277 { _value &= rhs._value; return *this; }
00278
00279 BitField & operator|=( const BitField & rhs )
00280 { _value |= rhs._value; return *this; }
00281
00282 BitField & operator^=( const BitField & rhs )
00283 { _value ^= rhs._value; return *this; }
00284
00285 BitField & operator<<=( unsigned num )
00286 { _value <<= num; return *this; }
00287
00288 BitField & operator>>=( unsigned num )
00289 { _value >>= num; return *this; }
00290
00291 BitField operator~() const
00292 { return ~_value; }
00293
00294 private:
00295 friend base::SafeBool<BitField<_IntT> >::operator bool_type() const;
00297 bool boolTest() const
00298 { return _value; }
00299
00300 private:
00301 _IntT _value;
00302 };
00304
00306 template<class _IntT>
00307 std::ostream & operator<<( std::ostream & str, const BitField<_IntT> & obj )
00308 {
00309 return str << obj.asString();
00310 }
00311
00313 template<class _IntT>
00314 inline bool operator==( const BitField<_IntT> & lhs, const BitField<_IntT> & rhs )
00315 { return lhs.value() == rhs.value(); }
00316
00318 template<class _IntT>
00319 inline bool operator!=( const BitField<_IntT> & lhs, const BitField<_IntT> & rhs )
00320 { return ! (lhs == rhs); }
00321
00322
00324 template<class _IntT>
00325 inline BitField<_IntT> operator&( const BitField<_IntT> & lhs, const BitField<_IntT> & rhs )
00326 { return BitField<_IntT>(lhs) &= rhs; }
00327
00329 template<class _IntT>
00330 inline BitField<_IntT> operator|( const BitField<_IntT> & lhs, const BitField<_IntT> & rhs )
00331 { return BitField<_IntT>(lhs) |= rhs; }
00332
00334 template<class _IntT>
00335 inline BitField<_IntT> operator^( const BitField<_IntT> & lhs, const BitField<_IntT> & rhs )
00336 { return BitField<_IntT>(lhs) ^= rhs; }
00337
00339 template<class _IntT>
00340 inline BitField<_IntT> operator<<( const BitField<_IntT> & lhs, unsigned num )
00341 { return BitField<_IntT>(lhs) <<= num; }
00342
00344 template<class _IntT>
00345 inline BitField<_IntT> operator>>( const BitField<_IntT> & lhs, unsigned num )
00346 { return BitField<_IntT>(lhs) >>= num; }
00347
00349 }
00352 }
00354 #endif // ZYPP_BIT_H