libzypp  12.16.5
Bit.h
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #ifndef ZYPP_BIT_H
13 #define ZYPP_BIT_H
14 
15 #include <iosfwd>
16 #include <string>
17 
18 #include "zypp/base/SafeBool.h"
19 
21 namespace zypp
22 {
23 
24 
30  namespace bit
31  {
32 
33  namespace bit_detail
34  {
36  template<class _IntT, unsigned _size>
37  struct Gen1Bits
38  {
39  static const _IntT value = (Gen1Bits<_IntT,_size-1>::value << 1)+1;
40  };
42  template<class _IntT>
43  struct Gen1Bits<_IntT, 0>
44  {
45  static const _IntT value = 0;
46  };
47  }
48 
50  template<class _IntT>
51  struct MaxBits
52  {
53  typedef _IntT IntT;
54  static const unsigned value = (sizeof(IntT)*8);
55  };
56 
58  template<class _IntT>
59  inline std::string asString( _IntT val, char zero = '0', char one = '1' )
60  {
61  std::string s( MaxBits<_IntT>::value, zero );
62  for( unsigned i = MaxBits<_IntT>::value; i; )
63  {
64  --i;
65  if ( val & (_IntT)1 )
66  s[i] = one;
67  val = val >> 1;
68  };
69  return s;
70  }
71 
73  template<class _IntT, unsigned _begin, unsigned _size>
74  struct Mask
75  {
76  typedef _IntT IntT;
78  static const IntT inverted = ~value;
79  };
80 
82  template<class _IntT, unsigned _begin, unsigned _size>
83  struct Range
84  {
85  typedef _IntT IntT;
88 
89  static const unsigned begin = _begin;
90  static const unsigned size = _size;
91  static const unsigned end = _begin + _size;
92  };
97  template<class _IntT, unsigned _begin>
98  struct Range<_IntT, _begin, 0>
99  {};
100 
111  template<class _Range, typename _Range::IntT _value>
112  struct RangeValue
113  {
114  typedef _Range RangeT;
115  typedef typename _Range::IntT IntT;
116 
117  static const IntT value = _value << RangeT::begin;
118  };
119 
129  template<class _Range, unsigned _pos>
130  struct RangeBit
131  {
132  typedef _Range RangeT;
133  typedef typename _Range::IntT IntT;
134 
135  static const IntT value = IntT(1) << (RangeT::begin + _pos);
136  };
137 
139  //
140  // CLASS NAME : BitField
141  //
160  template<class _IntT>
161  class BitField : public Range<_IntT, 0, MaxBits<_IntT>::value>
162  , private base::SafeBool<BitField<_IntT> >
163  {
165 
166  public:
169  : _value( (_IntT)0 )
170  {}
172  BitField( const _IntT & value_r )
173  : _value( value_r )
174  {}
175 
176  public:
178  using base::SafeBool<BitField<_IntT> >::operator bool_type;
179 
180  public:
182  template<class _Range>
183  _IntT value() const
184  {
185  return _value & _Range::Mask::value;
186  }
187  _IntT value() const
188  {
189  return _value;
190  }
191 
193  template<class _Range>
194  std::string asString() const
195  {
196  return bit::asString( _value & _Range::Mask::value, '_' );
197  }
198  std::string asString() const
199  {
200  return bit::asString( _value, '_' );
201  }
202 
204  template<class _Range>
205  BitField & assign( _IntT rhs )
206  {
207  _value = (_value & _Range::Mask::inverted)
208  | (rhs & _Range::Mask::value);
209  return *this;
210  }
211  BitField & assign( _IntT rhs )
212  {
213  _value = rhs;
214  return *this;
215  }
216 
218  template<class _Range>
219  bool isEqual( _IntT rhs ) const
220  {
221  return (_value & _Range::Mask::value)
222  == (rhs & _Range::Mask::value);
223  }
224  bool isEqual( _IntT rhs ) const
225  {
226  return _value == rhs;
227  }
228 
229  public:
230 
232  template<class _Range>
233  BitField & set( _IntT rhs, bool doset_r )
234  { return set( (rhs & _Range::Mask::value), doset_r ); }
235 
236  BitField & set( _IntT rhs, bool doset_r )
237  { return doset_r ? set( rhs ) : unset( rhs ); }
238 
240  template<class _Range>
241  BitField & set( _IntT rhs )
242  { return set( rhs & _Range::Mask::value ); }
243 
244  BitField & set( _IntT rhs )
245  { _value |= rhs; return *this; }
246 
248  template<class _Range>
249  BitField & unset( _IntT rhs )
250  { return unset( rhs & _Range::Mask::value ); }
251 
252  BitField & unset( _IntT rhs )
253  { _value &= ~rhs; return *this; }
254 
256  template<class _Range>
257  bool test( _IntT rhs )
258  { return test( rhs & _Range::Mask::value ); }
259 
260  bool test( _IntT rhs ) const
261  { return (_value & rhs) == rhs; }
262 
264  template<class _Range>
265  bool testAnyOf( _IntT rhs )
266  { return testAnyOf( rhs & _Range::Mask::value ); }
267 
268  bool testAnyOf( _IntT rhs ) const
269  { return (_value & rhs); }
270 
271  public:
272 
273  BitField & operator=( const BitField & rhs )
274  { _value = rhs._value; return *this; }
275 
276  BitField & operator&=( const BitField & rhs )
277  { _value &= rhs._value; return *this; }
278 
279  BitField & operator|=( const BitField & rhs )
280  { _value |= rhs._value; return *this; }
281 
282  BitField & operator^=( const BitField & rhs )
283  { _value ^= rhs._value; return *this; }
284 
285  BitField & operator<<=( unsigned num )
286  { _value <<= num; return *this; }
287 
288  BitField & operator>>=( unsigned num )
289  { _value >>= num; return *this; }
290 
292  { return ~_value; }
293 
294  private:
295  friend base::SafeBool<BitField<_IntT> >::operator bool_type() const;
297  bool boolTest() const
298  { return _value; }
299 
300  private:
301  _IntT _value;
302  };
304 
306  template<class _IntT>
307  std::ostream & operator<<( std::ostream & str, const BitField<_IntT> & obj )
308  {
309  return str << obj.asString();
310  }
311 
313  template<class _IntT>
314  inline bool operator==( const BitField<_IntT> & lhs, const BitField<_IntT> & rhs )
315  { return lhs.value() == rhs.value(); }
316 
318  template<class _IntT>
319  inline bool operator!=( const BitField<_IntT> & lhs, const BitField<_IntT> & rhs )
320  { return ! (lhs == rhs); }
321 
322 
324  template<class _IntT>
325  inline BitField<_IntT> operator&( const BitField<_IntT> & lhs, const BitField<_IntT> & rhs )
326  { return BitField<_IntT>(lhs) &= rhs; }
327 
329  template<class _IntT>
330  inline BitField<_IntT> operator|( const BitField<_IntT> & lhs, const BitField<_IntT> & rhs )
331  { return BitField<_IntT>(lhs) |= rhs; }
332 
334  template<class _IntT>
335  inline BitField<_IntT> operator^( const BitField<_IntT> & lhs, const BitField<_IntT> & rhs )
336  { return BitField<_IntT>(lhs) ^= rhs; }
337 
339  template<class _IntT>
340  inline BitField<_IntT> operator<<( const BitField<_IntT> & lhs, unsigned num )
341  { return BitField<_IntT>(lhs) <<= num; }
342 
344  template<class _IntT>
345  inline BitField<_IntT> operator>>( const BitField<_IntT> & lhs, unsigned num )
346  { return BitField<_IntT>(lhs) >>= num; }
347 
349  } // namespace bit
352 } // namespace zypp
354 #endif // ZYPP_BIT_H