libzypp  10.5.0
Bit.h
Go to the documentation of this file.
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