problem solution moved to toplevel; setTransacts --> setTransact
[platform/upstream/libzypp.git] / zypp / ResStatus.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/ResStatus.h
10  *
11 */
12 #ifndef ZYPP_RESSTATUS_H
13 #define ZYPP_RESSTATUS_H
14
15 #include <iosfwd>
16
17 #include "zypp/Bit.h"
18
19 ///////////////////////////////////////////////////////////////////
20 namespace zypp
21 { /////////////////////////////////////////////////////////////////
22
23   ///////////////////////////////////////////////////////////////////
24   //
25   //    CLASS NAME : ResStatus
26   //
27   /** Status bitfield.
28    *
29    * \li \c StateField Whether the resolvable is currently installed
30    *        or uninstalled (available).
31    * \li \c EstablishField Established status computed by the solver as
32    *        unneeded (have freshens but none of them trigger)
33    *        satisfied (no freshen or at least one triggered freshen and
34    *        all requires fulfilled)
35    *        or incomplete (no freshen or at least one triggered freshen and
36    *        NOT all requires fulfilled)
37    * \li \c TransactField Wheter to transact this resolvable
38    *        (delete if installed install if uninstalled).
39    * \li \c TransactByField Who triggered the transaction. Transaction
40    *        bit may be reset by higer levels only.
41    * \li \c TransactDetailField Reason why the Resolvable transacts.
42    *        Splitted into \c InstallDetailValue and \c RemoveDetailValue
43    *        dependent on the kind of transaction.
44    *
45   */
46   class ResStatus
47   {
48     friend std::ostream & operator<<( std::ostream & str, const ResStatus & obj );
49     friend bool operator==( const ResStatus & lhs, const ResStatus & rhs );
50
51     /** \name BitField range definitions.
52      *
53      * \note Enlarge FieldType if more bit's needed. It's not yet
54      * checked by the compiler.
55      */
56     //@{
57     typedef char FieldType;
58     // Bit Ranges within FieldType defined by 1st bit and size:
59     typedef bit::Range<FieldType,0,                    1> StateField;
60     typedef bit::Range<FieldType,StateField::end,      2> EstablishField;
61     typedef bit::Range<FieldType,EstablishField::end,  1> TransactField;
62     typedef bit::Range<FieldType,TransactField::end,   2> TransactByField;
63     typedef bit::Range<FieldType,TransactByField::end, 2> TransactDetailField;
64     // enlarge FieldType if more bit's needed. It's not yet
65     // checked by the compiler.
66     //@}
67   public:
68
69     /** \name Status values.
70      *
71      * Each enum corresponds to a BitField range.
72      * \note Take care that enumerator values actually fit into
73      * the corresponding field. It's not yet checked by the compiler.
74      */
75     //@{
76     enum StateValue
77       {
78         UNINSTALLED = 0,
79         INSTALLED   = StateField::minval
80       };
81     enum EstablishValue
82       {
83         UNDETERMINED = 0,
84         UNNEEDED     = EstablishField::minval,          // has freshens, none trigger
85         SATISFIED,                                      // has none or triggered freshens, all requirements fulfilled
86         INCOMPLETE                                      // installed: has none or triggered freshens, requirements unfulfilled
87       };
88     enum TransactValue
89       {
90         KEEP_STATE = 0,
91         TRANSACT = TransactField::minval                // change state installed <-> uninstalled
92       };
93     enum TransactByValue
94       {
95         SOLVER = 0,
96         APPL_LOW  = TransactByField::minval,
97         APPL_HIGH,
98         USER
99       };
100
101     enum InstallDetailValue
102       {
103         EXPLICIT_INSTALL = 0,
104         SOFT_REQUIRES = TransactDetailField::minval
105       };
106     enum RemoveDetailValue
107       {
108         EXPLICIT_REMOVE = 0,
109         DUE_TO_OBSOLETE = TransactDetailField::minval,
110         DUE_TO_UNLINK
111       };
112     //@}
113
114   public:
115
116     /** Default ctor. */
117     ResStatus();
118
119     /** Ctor setting the initial . */
120     ResStatus( bool isInstalled_r );
121
122     /** Dtor. */
123     ~ResStatus();
124
125   public:
126
127     bool isInstalled() const
128     { return fieldValueIs<StateField>( INSTALLED ); }
129
130     bool staysInstalled() const
131     { return isInstalled() && !transacts(); }
132
133     bool isToBeInstalled() const
134     { return isUninstalled() && transacts(); }
135
136     bool staysUninstalled() const
137     { return isUninstalled() && !transacts(); }
138
139     bool isUninstalled() const
140     { return fieldValueIs<StateField>( UNINSTALLED ); }
141
142     bool isToBeUninstalled() const
143     { return isInstalled() && transacts(); }
144
145     bool isUnneeded() const
146     { return isUninstalled() && fieldValueIs<EstablishField>( UNNEEDED ); }
147
148     bool isSatisfied() const
149     { return isUninstalled() && fieldValueIs<EstablishField>( SATISFIED ); }
150
151     bool isComplete () const
152     { return isInstalled() && fieldValueIs<EstablishField>( SATISFIED ); }
153
154     bool isIncomplete() const
155     { return isInstalled() && fieldValueIs<EstablishField>( INCOMPLETE ); }
156
157     bool isNeeded() const
158     { return isUninstalled() && fieldValueIs<EstablishField>( INCOMPLETE ); }
159
160     bool transacts() const
161     { return fieldValueIs<TransactField>( TRANSACT ); }
162
163     bool isBySolver() const
164     { return fieldValueIs<TransactByField>( SOLVER ); }
165
166     bool isByApplLow() const
167     { return fieldValueIs<TransactByField>( APPL_LOW ); }
168
169     bool isByApplHigh() const
170     { return fieldValueIs<TransactByField>( APPL_HIGH ); }
171
172     bool isByUser() const
173     { return fieldValueIs<TransactByField>( USER ); }
174
175     bool isToBeUninstalledDueToObsolete () const
176     { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( DUE_TO_OBSOLETE ); }
177
178     bool isToBeUninstalledDueToUnlink() const
179     { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( DUE_TO_UNLINK); }
180
181     bool isToBeInstalledSoft () const
182     { return isToBeInstalled() && fieldValueIs<TransactDetailField> (SOFT_REQUIRES); }
183
184   public:
185
186     //------------------------------------------------------------------------
187     // get/set functions, returnig \c true if requested status change
188     // was successfull (i.e. leading to the desired transaction).
189     // If a lower level (e.g.SOLVER) wants to transact, but it's
190     // already set by a higher level, \c true should be returned.
191     // Removing a higher levels transaction bit should fail.
192     //
193     // The may functions checks only, if the action would return true
194     // if it is called.
195
196     bool setNoTransact (TransactByValue causer)
197     {
198         if (!isGreaterThan<TransactByField>( causer )) {
199             setTransact (false, causer);
200             fieldValueAssign<TransactDetailField>(0);
201             return true;
202         } else if (!transacts()) {
203             return true; // is already set
204         } else {
205             return false;
206         }
207     }
208       
209     bool maySetNoTransact (TransactByValue causer)
210     {
211         bit::BitField<FieldType> savBitfield = _bitfield;
212         bool ret = setNoTransact (causer);
213         _bitfield = savBitfield;
214         return ret;
215     }
216
217     bool setTransact (bool val_r, TransactByValue causer)
218     {
219         if (!isGreaterThan<TransactByField>( causer )) {        
220             fieldValueAssign<TransactField>( val_r ? TRANSACT : KEEP_STATE );
221             fieldValueAssign<TransactByField>( causer );
222             return true;
223         } else if (fieldValueIs<TransactField>(val_r ? TRANSACT : KEEP_STATE)) { 
224             return true; // is already set
225         } else {
226             return false;
227         }           
228     }
229
230     bool maySetTransact (bool val_r, TransactByValue causer)
231     {
232         bit::BitField<FieldType> savBitfield = _bitfield;
233         bool ret = setTransact (val_r, causer);
234         _bitfield = savBitfield;
235         return ret;
236     }
237
238     bool setToBeInstalled (TransactByValue causer)
239     {
240       if (isInstalled()) return false;
241       return setTransact (true, causer);
242     }
243
244     bool maySetToBeInstalled (TransactByValue causer)
245     {
246         bit::BitField<FieldType> savBitfield = _bitfield;
247         bool ret = setToBeInstalled (causer);
248         _bitfield = savBitfield;
249         return ret;
250     }      
251
252     bool setToBeUninstalled (TransactByValue causer)
253     {
254       if (!isInstalled()) return false;
255       return setTransact (true, causer);
256     }
257
258     bool maySetToBeUninstalled (TransactByValue causer)
259     {
260         bit::BitField<FieldType> savBitfield = _bitfield;
261         bool ret = setToBeUninstalled (causer);
262         _bitfield = savBitfield;
263         return ret;
264     }            
265
266     //------------------------------------------------------------------------
267     // *** These are only for the Resolver ***
268
269     bool setToBeUninstalledDueToUnlink ( )
270     {
271       if (!setToBeUninstalled (SOLVER)) return false;
272       fieldValueAssign<TransactDetailField>(DUE_TO_UNLINK);
273       return true;
274     }
275
276     bool setToBeUninstalledDueToObsolete ( )
277     {
278       if (!setToBeUninstalled (SOLVER)) return false;
279       fieldValueAssign<TransactDetailField>(DUE_TO_OBSOLETE);
280       return true;
281     }
282
283     bool setToBeInstalledSoft ( )
284     {
285       if (!setToBeInstalled(SOLVER)) return false;
286       fieldValueAssign<TransactDetailField>(SOFT_REQUIRES);
287       return true;
288     }
289       
290
291     bool setUnneeded ()
292     {
293       fieldValueAssign<EstablishField>(UNNEEDED);
294       return true;
295     }
296
297     bool setSatisfied ()
298     {
299       fieldValueAssign<EstablishField>(SATISFIED);
300       return true;
301     }
302
303     bool setIncomplete ()
304     {
305       fieldValueAssign<EstablishField>(INCOMPLETE);
306       return true;
307     }
308
309     void setStatus (ResStatus status)
310     {
311         _bitfield = status._bitfield;
312     }
313
314     /** \name Builtin ResStatus constants. */
315     //@{
316     static const ResStatus toBeInstalled;
317     static const ResStatus toBeInstalledSoft;
318     static const ResStatus toBeUninstalled;
319     static const ResStatus toBeUninstalledDueToUnlink;
320     static const ResStatus toBeUninstalledDueToObsolete;
321     static const ResStatus satisfied;   // uninstalled, satisfied
322     static const ResStatus complete;    // installed, satisfied
323     static const ResStatus unneeded;    // uninstalled, unneeded
324     static const ResStatus needed;      // uninstalled, incomplete
325     static const ResStatus incomplete;  // installed, incomplete
326     //@}
327
328   private:
329     /** Ctor for intialization of builtin constants. */
330     ResStatus( StateValue s,
331                EstablishValue e     = UNDETERMINED,
332                TransactValue t      = TRANSACT,
333                InstallDetailValue i = EXPLICIT_INSTALL,
334                RemoveDetailValue r  = EXPLICIT_REMOVE );
335
336     /** Return whether the corresponding Field has value \a val_r.
337     */
338     template<class _Field>
339       bool fieldValueIs( FieldType val_r ) const
340       { return _bitfield.isEqual<_Field>( val_r ); }
341
342     /** Set the corresponding Field to value \a val_r.
343     */
344     template<class _Field>
345       void fieldValueAssign( FieldType val_r )
346       { _bitfield.assign<_Field>( val_r ); }
347
348     /** compare two values.
349     */
350     template<class _Field>
351       bool isGreaterThan( FieldType val_r )
352           { return _bitfield.value<_Field>() > val_r; }
353
354   private:
355     bit::BitField<FieldType> _bitfield;
356   };
357   ///////////////////////////////////////////////////////////////////
358
359   /** \relates ResStatus Stream output */
360   std::ostream & operator<<( std::ostream & str, const ResStatus & obj );
361
362   /** \relates ResStatus */
363   inline bool operator==( const ResStatus & lhs, const ResStatus & rhs )
364   { return lhs._bitfield == rhs._bitfield; }
365
366   /** \relates ResStatus */
367   inline bool operator!=( const ResStatus & lhs, const ResStatus & rhs )
368   { return ! (lhs == rhs); }
369
370   /////////////////////////////////////////////////////////////////
371 } // namespace zypp
372 ///////////////////////////////////////////////////////////////////
373 #endif // ZYPP_RESSTATUS_H