- Create the cache directly from the schema (installed) file.
[platform/upstream/libzypp.git] / zypp / Bit.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/Bit.h
10  *
11 */
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
20 ///////////////////////////////////////////////////////////////////
21 namespace zypp
22 { /////////////////////////////////////////////////////////////////
23 ///////////////////////////////////////////////////////////////////
24   /**
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 ).
29   */
30   namespace bit
31   { /////////////////////////////////////////////////////////////////
32
33     namespace bit_detail
34     {
35       /** Generate constants with \a _size trailing '1'-bits */
36       template<class _IntT, unsigned _size>
37         struct Gen1Bits
38         {
39           static const _IntT value = (Gen1Bits<_IntT,_size-1>::value << 1)+1;
40         };
41       /** Specialization for \a _length 0 */
42       template<class _IntT>
43         struct Gen1Bits<_IntT, 0>
44         {
45           static const _IntT value = 0;
46         };
47     }
48
49     /** Number of bits available in \a _IntT. */
50     template<class _IntT>
51       struct MaxBits
52       {
53         typedef _IntT IntT;
54         static const unsigned value = (sizeof(IntT)*8);
55       };
56
57     /** For printing bits. */
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
72     /** A bitmaks of \a _size 1-bits starting at bit \a _begin. */
73     template<class _IntT, unsigned _begin, unsigned _size>
74       struct Mask
75       {
76         typedef _IntT IntT;
77         static const IntT value    = bit_detail::Gen1Bits<IntT,_size>::value << _begin;
78         static const IntT inverted = ~value;
79       };
80
81     /** Range of bits starting at bit \a _begin with length \a _size. */
82     template<class _IntT, unsigned _begin, unsigned _size>
83       struct Range
84       {
85         typedef _IntT IntT;
86         typedef MaxBits<IntT>           MaxBits;
87         typedef Mask<IntT,_begin,_size> Mask;
88
89         static const unsigned begin  = _begin;
90         static const unsigned size   = _size;
91         static const unsigned end    = _begin + _size;
92       };
93     /** Range specialisation for (illegal) zero \a _size.
94      * Force error at compiletime. Currently because types
95      * and values are undefined
96     */
97     template<class _IntT, unsigned _begin>
98       struct Range<_IntT, _begin, 0>
99       {};
100
101     /** A value with in a Range.
102      * \code
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
109      * \endcode
110     */
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
120     /** A single 1-bit within a Range.
121      * \code
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
127      * \endcode
128     */
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
138     ///////////////////////////////////////////////////////////////////
139     //
140     //  CLASS NAME : BitField
141     //
142     /** An integral type used as BitField.
143      *
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.
148      * \code
149      * BitField<char> bf;                // 00000000
150      * typedef Range<char,2,3> SubField; // bits 2,3,4 in a char field
151      *
152      * bf<SubField>.assign( -1 );        // assign SubField in -1
153      *                                   // to SubField in bf.
154      *                                   // 00011100
155      * bf.assign( -1 );                  // assign -1 to bf
156      *                                   // 11111111
157      * bf<SubField>.assign( 0 );         // 11100011
158      * \endcode
159     */
160     template<class _IntT>
161       class BitField  : public Range<_IntT, 0, MaxBits<_IntT>::value>
162                       , public base::SafeBool<BitField<_IntT> > /* private, but gcc refuses */
163       {
164         typedef typename base::SafeBool<BitField<_IntT> >::bool_type bool_type;
165
166       public:
167         /** Default ctor: zero. */
168         BitField()
169         : _value( (_IntT)0 )
170         {}
171         /** Ctor taking an \a _IntT. */
172         BitField( const _IntT & value_r )
173         : _value( value_r )
174         {}
175
176       public:
177         /** Validate in a boolean context. */
178         using base::SafeBool<BitField<_IntT> >::operator bool_type;
179
180       public:
181         /** Return the value. */
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
192         /** Value as bit string. */
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
203         /** Assign Range in \a rhs to \c this. */
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
217         /** Test for equal value within a Range. */
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       public:
229
230         BitField & operator=( const BitField & rhs )
231         { _value = rhs._value; return *this; }
232
233         BitField & operator&=( const BitField & rhs )
234         { _value &= rhs._value; return *this; }
235
236         BitField & operator|=( const BitField & rhs )
237         { _value |= rhs._value; return *this; }
238
239         BitField & operator^=( const BitField & rhs )
240         { _value ^= rhs._value; return *this; }
241
242         BitField & operator<<=( unsigned num )
243         { _value <<= num; return *this; }
244
245         BitField & operator>>=( unsigned num )
246         { _value >>= num; return *this; }
247
248         BitField operator~() const
249         { return ~_value; }
250
251       private:
252         friend base::SafeBool<BitField<_IntT> >::operator bool_type() const;
253         /** \ref base::SafeBool test. */
254         bool boolTest() const
255         { return _value; }
256
257       private:
258         _IntT _value;
259       };
260     ///////////////////////////////////////////////////////////////////
261
262     /** \relates BitField Stream output */
263     template<class _IntT>
264       std::ostream & operator<<( std::ostream & str, const BitField<_IntT> & obj )
265       {
266         return str << obj.asString();
267       }
268
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(); }
273
274     /** \relates BitField */
275     template<class _IntT>
276       inline bool operator!=( const BitField<_IntT> & lhs, const BitField<_IntT> & rhs )
277       { return ! (lhs == rhs); }
278
279
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; }
284
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; }
289
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; }
294
295     /** \relates BitField */
296     template<class _IntT>
297       inline BitField<_IntT> operator<<( const BitField<_IntT> & lhs, unsigned num )
298       { return BitField<_IntT>(lhs) <<= num; }
299
300     /** \relates BitField */
301     template<class _IntT>
302       inline BitField<_IntT> operator>>( const BitField<_IntT> & lhs, unsigned num )
303       { return BitField<_IntT>(lhs) >>= num; }
304
305     /////////////////////////////////////////////////////////////////
306   } // namespace bit
307   ///////////////////////////////////////////////////////////////////
308   /////////////////////////////////////////////////////////////////
309 } // namespace zypp
310 ///////////////////////////////////////////////////////////////////
311 #endif // ZYPP_BIT_H