1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
18 #include "zypp/base/SafeBool.h"
20 ///////////////////////////////////////////////////////////////////
22 { /////////////////////////////////////////////////////////////////
23 ///////////////////////////////////////////////////////////////////
25 * \todo Use boost::mpl library to assert constraints
26 * at compiletime! There various like (_IntT is an integral type)
27 * (begin+size < maxbits) or ( field dependent
28 * constants must be within the range defined by size ).
31 { /////////////////////////////////////////////////////////////////
35 /** Generate constants with \a _size trailing '1'-bits */
36 template<class _IntT, unsigned _size>
39 static const _IntT value = (Gen1Bits<_IntT,_size-1>::value << 1)+1;
41 /** Specialization for \a _length 0 */
43 struct Gen1Bits<_IntT, 0>
45 static const _IntT value = 0;
49 /** Number of bits available in \a _IntT. */
54 static const unsigned value = (sizeof(IntT)*8);
57 /** For printing bits. */
59 inline std::string asString( _IntT val, char zero = '0', char one = '1' )
61 std::string s( MaxBits<_IntT>::value, zero );
62 for( unsigned i = MaxBits<_IntT>::value; i; )
72 /** A bitmaks of \a _size 1-bits starting at bit \a _begin. */
73 template<class _IntT, unsigned _begin, unsigned _size>
77 static const IntT value = bit_detail::Gen1Bits<IntT,_size>::value << _begin;
78 static const IntT inverted = ~value;
81 /** Range of bits starting at bit \a _begin with length \a _size. */
82 template<class _IntT, unsigned _begin, unsigned _size>
86 typedef MaxBits<IntT> MaxBits;
87 typedef Mask<IntT,_begin,_size> Mask;
89 static const unsigned begin = _begin;
90 static const unsigned size = _size;
91 static const unsigned end = _begin + _size;
93 /** Range specialisation for (illegal) zero \a _size.
94 * Force error at compiletime. Currently because types
95 * and values are undefined
97 template<class _IntT, unsigned _begin>
98 struct Range<_IntT, _begin, 0>
101 /** A value with in a Range.
103 * typedef Range<char,2,3> SubField; // bits 2,3,4 in a char field
104 * SubField::Mask::value; // 00011100
105 * RangeValue<SubField,0>::value; // 00000000
106 * RangeValue<SubField,1>::value; // 00000100
107 * RangeValue<SubField,2>::value; // 00001000
108 * RangeValue<SubField,3>::value; // 00001100
111 template<class _Range, typename _Range::IntT _value>
114 typedef _Range RangeT;
115 typedef typename _Range::IntT IntT;
117 static const IntT value = _value << RangeT::begin;
120 /** A single 1-bit within a Range.
122 * typedef Range<char,2,3> SubField; // bits 2,3,4 in a char field
123 * SubField::Mask::value; // 00011100
124 * RangeBit<SubField,0>::value; // 00000100
125 * RangeBit<SubField,1>::value; // 00001000
126 * RangeBit<SubField,2>::value; // 00010000
129 template<class _Range, unsigned _pos>
132 typedef _Range RangeT;
133 typedef typename _Range::IntT IntT;
135 static const IntT value = IntT(1) << (RangeT::begin + _pos);
138 ///////////////////////////////////////////////////////////////////
140 // CLASS NAME : BitField
142 /** An integral type used as BitField.
144 * Most methods exist as templated and nontemplated
145 * version. The nontemplated operates on the complete
146 * BitField, while the tamplated ones are restricted
147 * to the given Range.
149 * BitField<char> bf; // 00000000
150 * typedef Range<char,2,3> SubField; // bits 2,3,4 in a char field
152 * bf<SubField>.assign( -1 ); // assign SubField in -1
153 * // to SubField in bf.
155 * bf.assign( -1 ); // assign -1 to bf
157 * bf<SubField>.assign( 0 ); // 11100011
160 template<class _IntT>
161 class BitField : public Range<_IntT, 0, MaxBits<_IntT>::value>
162 , public base::SafeBool<BitField<_IntT> > /* private, but gcc refuses */
164 typedef typename base::SafeBool<BitField<_IntT> >::bool_type bool_type;
167 /** Default ctor: zero. */
171 /** Ctor taking an \a _IntT. */
172 BitField( const _IntT & value_r )
177 /** Validate in a boolean context. */
178 using base::SafeBool<BitField<_IntT> >::operator bool_type;
181 /** Return the value. */
182 template<class _Range>
185 return _value & _Range::Mask::value;
192 /** Value as bit string. */
193 template<class _Range>
194 std::string asString() const
196 return bit::asString( _value & _Range::Mask::value, '_' );
198 std::string asString() const
200 return bit::asString( _value, '_' );
203 /** Assign Range in \a rhs to \c this. */
204 template<class _Range>
205 BitField & assign( _IntT rhs )
207 _value = (_value & _Range::Mask::inverted)
208 | (rhs & _Range::Mask::value);
211 BitField & assign( _IntT rhs )
217 /** Test for equal value within a Range. */
218 template<class _Range>
219 bool isEqual( _IntT rhs ) const
221 return (_value & _Range::Mask::value)
222 == (rhs & _Range::Mask::value);
224 bool isEqual( _IntT rhs ) const
226 return _value == rhs;
230 BitField & operator=( const BitField & rhs )
231 { _value = rhs._value; return *this; }
233 BitField & operator&=( const BitField & rhs )
234 { _value &= rhs._value; return *this; }
236 BitField & operator|=( const BitField & rhs )
237 { _value |= rhs._value; return *this; }
239 BitField & operator^=( const BitField & rhs )
240 { _value ^= rhs._value; return *this; }
242 BitField & operator<<=( unsigned num )
243 { _value <<= num; return *this; }
245 BitField & operator>>=( unsigned num )
246 { _value >>= num; return *this; }
248 BitField operator~() const
252 friend base::SafeBool<BitField<_IntT> >::operator bool_type() const;
253 /** \ref base::SafeBool test. */
254 bool boolTest() const
260 ///////////////////////////////////////////////////////////////////
262 /** \relates BitField Stream output */
263 template<class _IntT>
264 std::ostream & operator<<( std::ostream & str, const BitField<_IntT> & obj )
266 return str << obj.asString();
269 /** \relates BitField */
270 template<class _IntT>
271 inline bool operator==( const BitField<_IntT> & lhs, const BitField<_IntT> & rhs )
272 { return lhs.value() == rhs.value(); }
274 /** \relates BitField */
275 template<class _IntT>
276 inline bool operator!=( const BitField<_IntT> & lhs, const BitField<_IntT> & rhs )
277 { return ! (lhs == rhs); }
280 /** \relates BitField */
281 template<class _IntT>
282 inline BitField<_IntT> operator&( const BitField<_IntT> & lhs, const BitField<_IntT> & rhs )
283 { return BitField<_IntT>(lhs) &= rhs; }
285 /** \relates BitField */
286 template<class _IntT>
287 inline BitField<_IntT> operator|( const BitField<_IntT> & lhs, const BitField<_IntT> & rhs )
288 { return BitField<_IntT>(lhs) |= rhs; }
290 /** \relates BitField */
291 template<class _IntT>
292 inline BitField<_IntT> operator^( const BitField<_IntT> & lhs, const BitField<_IntT> & rhs )
293 { return BitField<_IntT>(lhs) ^= rhs; }
295 /** \relates BitField */
296 template<class _IntT>
297 inline BitField<_IntT> operator<<( const BitField<_IntT> & lhs, unsigned num )
298 { return BitField<_IntT>(lhs) <<= num; }
300 /** \relates BitField */
301 template<class _IntT>
302 inline BitField<_IntT> operator>>( const BitField<_IntT> & lhs, unsigned num )
303 { return BitField<_IntT>(lhs) >>= num; }
305 /////////////////////////////////////////////////////////////////
307 ///////////////////////////////////////////////////////////////////
308 /////////////////////////////////////////////////////////////////
310 ///////////////////////////////////////////////////////////////////