libzypp
10.5.0
|
00001 /*---------------------------------------------------------------------\ 00002 | ____ _ __ __ ___ | 00003 | |__ / \ / / . \ . \ | 00004 | / / \ V /| _/ _/ | 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 // CLASS NAME : BitField 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 } // namespace bit 00352 } // namespace zypp 00354 #endif // ZYPP_BIT_H