Remove obsolete ResStatus bits.
[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 <inttypes.h>
16 #include <iosfwd>
17 #include "zypp/Bit.h"
18
19 ///////////////////////////////////////////////////////////////////
20 namespace zypp
21 { /////////////////////////////////////////////////////////////////
22
23   namespace resstatus
24   {
25     class UserLockQueryManip;
26     class StatusBackup;
27   }
28
29   ///////////////////////////////////////////////////////////////////
30   //
31   //    CLASS NAME : ResStatus
32   //
33   /** Status bitfield.
34    *
35    * \li \c StateField Whether the resolvable is or uninstalled (available).
36    * \li \c ValidateField Validate status computed by the solver as
37    *        nonrelevant: it is unimportant for the user
38    *        satisfied: it important nothing has to be done
39    *        broken: it is incomplete. So e.g. an update is needed
40    * \li \c TransactField Wheter to transact this resolvable
41    *        (delete if installed install if uninstalled).
42    *        In case the resolvable is locked, only USER may modify the
43    *        transact bit.
44    * \li \c TransactByField Who triggered the transaction. Transaction
45    *        bit may be reset by higer levels only.
46    * \li \c TransactDetailField Reason why the Resolvable transacts.
47    *        Splitted into \c InstallDetailValue and \c RemoveDetailValue
48    *        dependent on the kind of transaction.
49    * \li \c WeakField The solvable will be recommended/suggested by
50    *        a to be installed/deleted solvable.
51    *
52   */
53   class ResStatus
54   {
55     friend std::ostream & operator<<( std::ostream & str, const ResStatus & obj );
56     friend bool operator==( const ResStatus & lhs, const ResStatus & rhs );
57
58   public:
59     /** \name BitField range definitions.
60      *
61      * \note Enlarge FieldType if more bit's needed. It's not yet
62      * checked by the compiler.
63      */
64     //@{
65     typedef uint16_t FieldType;
66     typedef bit::BitField<FieldType> BitFieldType;
67     // Bit Ranges within FieldType defined by 1st bit and size:
68     typedef bit::Range<FieldType,0,                          1> StateField;
69     typedef bit::Range<FieldType,StateField::end,            2> ValidateField;
70     typedef bit::Range<FieldType,ValidateField::end,         2> TransactField;
71     typedef bit::Range<FieldType,TransactField::end,         2> TransactByField;
72     typedef bit::Range<FieldType,TransactByField::end,       2> TransactDetailField;
73     typedef bit::Range<FieldType,TransactDetailField::end,   1> LicenceConfirmedField;
74     typedef bit::Range<FieldType,LicenceConfirmedField::end, 2> WeakField;
75     typedef bit::Range<FieldType,WeakField::end,             1> UserLockQueryField; // internal
76     // enlarge FieldType if more bit's needed. It's not yet
77     // checked by the compiler.
78     //@}
79   public:
80
81     /** \name Status values.
82      *
83      * Each enum corresponds to a BitField range.
84      * \note Take care that enumerator values actually fit into
85      * the corresponding field. It's not yet checked by the compiler.
86      */
87     //@{
88     enum StateValue
89       {
90         UNINSTALLED = bit::RangeValue<StateField,0>::value,
91         INSTALLED   = bit::RangeValue<StateField,1>::value
92       };
93     enum ValidateValue
94       {
95         UNDETERMINED = bit::RangeValue<ValidateField,0>::value,
96         BROKEN       = bit::RangeValue<ValidateField,1>::value,
97         SATISFIED    = bit::RangeValue<ValidateField,2>::value,
98         NONRELEVANT  = bit::RangeValue<ValidateField,3>::value
99       };
100     enum TransactValue
101       {
102         KEEP_STATE = bit::RangeValue<TransactField,0>::value,
103         LOCKED     = bit::RangeValue<TransactField,1>::value, // locked, must not transact
104         TRANSACT   = bit::RangeValue<TransactField,2>::value  // transact according to state
105       };
106     enum TransactByValue
107       {
108         SOLVER    = bit::RangeValue<TransactByField,0>::value,
109         APPL_LOW  = bit::RangeValue<TransactByField,1>::value,
110         APPL_HIGH = bit::RangeValue<TransactByField,2>::value,
111         USER      = bit::RangeValue<TransactByField,3>::value
112       };
113
114     enum DetailValue
115       {
116         /** Detail for no transact, i.e. reset any Install/RemoveDetailValue. */
117         NO_DETAIL = bit::RangeValue<TransactDetailField,0>::value,
118       };
119     enum InstallDetailValue
120       {
121         EXPLICIT_INSTALL = bit::RangeValue<TransactDetailField,0>::value,
122         SOFT_INSTALL     = bit::RangeValue<TransactDetailField,1>::value
123       };
124     enum RemoveDetailValue
125       {
126         EXPLICIT_REMOVE = bit::RangeValue<TransactDetailField,0>::value,
127         SOFT_REMOVE     = bit::RangeValue<TransactDetailField,1>::value,
128         DUE_TO_OBSOLETE = bit::RangeValue<TransactDetailField,2>::value,
129         DUE_TO_UPGRADE  = bit::RangeValue<TransactDetailField,3>::value
130       };
131
132     enum LicenceConfirmedValue
133       {
134         LICENCE_UNCONFIRMED = bit::RangeValue<LicenceConfirmedField,0>::value,
135         LICENCE_CONFIRMED   = bit::RangeValue<LicenceConfirmedField,1>::value
136       };
137
138     enum WeakValue
139       {
140         NO_WEAK                 = bit::RangeValue<WeakField,0>::value,
141         SUGGESTED               = bit::RangeValue<WeakField,1>::value,
142         RECOMMENDED             = bit::RangeValue<WeakField,2>::value,
143         SUGGESTED_AND_RECOMMENDED = bit::RangeValue<WeakField,3>::value
144       };
145
146     enum UserLockQuery // internal
147       {
148         USERLOCK_NOMATCH        = bit::RangeValue<UserLockQueryField,0>::value,
149         USERLOCK_MATCH          = bit::RangeValue<UserLockQueryField,1>::value
150       };
151     //@}
152
153   public:
154
155     /** Default ctor. */
156     ResStatus();
157
158     /** Ctor setting the initial . */
159     ResStatus( bool isInstalled_r );
160
161     /** Dtor. */
162     ~ResStatus();
163
164     /** Debug helper returning the bitfield.
165      * It's save to expose the bitfield, as it can't be used to
166      * recreate a ResStatus. So it is not possible to bypass
167      * transition rules.
168     */
169     BitFieldType bitfield() const
170     { return _bitfield; }
171
172   public:
173
174     bool isLicenceConfirmed() const
175     { return fieldValueIs<LicenceConfirmedField>( LICENCE_CONFIRMED ); }
176
177     void setLicenceConfirmed( bool toVal_r = true )
178     { fieldValueAssign<LicenceConfirmedField>( toVal_r ? LICENCE_CONFIRMED : LICENCE_UNCONFIRMED ); }
179
180   public:
181
182     bool isRecommended() const
183     { return fieldValueIs<WeakField>( RECOMMENDED ); }
184
185     bool isSuggested() const
186     { return fieldValueIs<WeakField>( SUGGESTED ); }
187
188     bool resetWeak() const
189     { return fieldValueIs<WeakField>( NO_WEAK ); }
190
191     void setRecommended( bool toVal_r = true )
192     { if (isSuggested())
193         fieldValueAssign<WeakField>( toVal_r ? SUGGESTED_AND_RECOMMENDED : SUGGESTED );
194     else
195         fieldValueAssign<WeakField>( toVal_r ? RECOMMENDED : NO_WEAK );
196     }
197
198     void setSuggested( bool toVal_r = true )
199     { if (isRecommended())
200         fieldValueAssign<WeakField>( toVal_r ? SUGGESTED_AND_RECOMMENDED : RECOMMENDED );
201     else
202         fieldValueAssign<WeakField>( toVal_r ? SUGGESTED : NO_WEAK );
203     }
204
205     ValidateValue validate() const
206     { return (ValidateValue)_bitfield.value<ValidateField>(); }
207
208     bool isUndetermined() const
209     { return fieldValueIs<ValidateField>( UNDETERMINED ); }
210
211     bool isSatisfied() const
212     { return fieldValueIs<ValidateField>( SATISFIED ); }
213
214     bool isBroken() const
215     { return fieldValueIs<ValidateField>( BROKEN ); }
216
217     bool isNonRelevant() const
218     { return fieldValueIs<ValidateField>( NONRELEVANT ); }
219
220   public:
221     // These two are IMMUTABLE!
222
223     bool isInstalled() const
224     { return fieldValueIs<StateField>( INSTALLED ); }
225
226     bool isUninstalled() const
227     { return fieldValueIs<StateField>( UNINSTALLED ); }
228
229   public:
230
231     bool staysInstalled() const
232     { return isInstalled() && !transacts(); }
233
234     bool wasInstalled() const { return staysInstalled(); }      //for old status
235
236     bool isToBeInstalled() const
237     { return isUninstalled() && transacts(); }
238
239     bool staysUninstalled() const
240     { return isUninstalled() && !transacts(); }
241
242     bool wasUninstalled() const { return staysUninstalled(); }  // for old status
243
244     bool isToBeUninstalled() const
245     { return isInstalled() && transacts(); }
246
247     bool isLocked() const
248     { return fieldValueIs<TransactField>( LOCKED ); }
249
250     bool isUserLocked() const
251     { return isLocked() && isByUser(); }
252
253     bool isSoftLocked( TransactByValue causer_r = USER ) const
254     { return isKept() && fieldValueIs<TransactByField>( causer_r ); }
255
256     bool isKept() const
257     { return fieldValueIs<TransactField>( KEEP_STATE ); }
258
259     bool transacts() const
260     { return fieldValueIs<TransactField>( TRANSACT ); }
261
262     TransactValue getTransactValue() const
263     { return (TransactValue)_bitfield.value<TransactField>(); }
264
265     /** True if would be on system after commit. */
266     bool onSystem() const
267     { return( isInstalled() != transacts() ); }
268
269     /** True if would be off system after commit. */
270     bool offSystem() const
271     { return ! onSystem(); }
272
273     bool isBySolver() const
274     { return fieldValueIs<TransactByField>( SOLVER ); }
275
276     bool isByApplLow() const
277     { return fieldValueIs<TransactByField>( APPL_LOW ); }
278
279     bool isByApplHigh() const
280     { return fieldValueIs<TransactByField>( APPL_HIGH ); }
281
282     bool isByUser() const
283     { return fieldValueIs<TransactByField>( USER ); }
284
285     TransactByValue getTransactByValue() const
286     { return (TransactByValue)_bitfield.value<TransactByField>(); }
287
288     bool setTransactByValue(TransactByValue causer)
289     {
290         if ( isLessThan<TransactByField>( causer ) ) {
291             fieldValueAssign<TransactByField>( causer );
292             return true;
293         } else {
294             return false;
295         }
296     }
297
298     bool isToBeUninstalledDueToObsolete () const
299     { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( DUE_TO_OBSOLETE ); }
300
301     bool isToBeUninstalledDueToUpgrade() const
302     { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( DUE_TO_UPGRADE ); }
303
304     bool isToBeInstalledSoft () const
305     { return isToBeInstalled() && fieldValueIs<TransactDetailField>( SOFT_INSTALL ); }
306
307     bool isToBeInstalledNotSoft () const
308     { return isToBeInstalled() && !fieldValueIs<TransactDetailField>( SOFT_INSTALL ); }
309
310     bool isToBeUninstalledSoft () const
311     { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( SOFT_REMOVE ); }
312
313   private:
314
315     /** \name Internal hard lock maintainance */
316     //@{
317     friend class resstatus::UserLockQueryManip;
318
319     bool isUserLockQueryMatch() const
320     { return fieldValueIs<UserLockQueryField>( USERLOCK_MATCH ); }
321
322     void setUserLockQueryMatch( bool match_r )
323     { fieldValueAssign<UserLockQueryField>( match_r ? USERLOCK_MATCH : USERLOCK_NOMATCH ); }
324     //@}
325
326   public:
327
328     //------------------------------------------------------------------------
329     // get/set functions, returnig \c true if requested status change
330     // was successfull (i.e. leading to the desired transaction).
331     // If a lower level (e.g.SOLVER) wants to transact, but it's
332     // already set by a higher level, \c true should be returned.
333     // Removing a higher levels transaction bit should fail.
334     //
335     // The may functions checks only, if the action would return true
336     // if it is called.
337
338     /** Set TransactValue.
339      * Convenience to set TransactValue from enum.
340      */
341     bool setTransactValue( TransactValue newVal_r, TransactByValue causer_r )
342     {
343       switch ( newVal_r )
344         {
345         case KEEP_STATE:
346           return setTransact( false, causer_r );
347           break;
348         case LOCKED:
349           return setLock( true, causer_r );
350           break;
351         case TRANSACT:
352           return setTransact( true, causer_r );
353           break;
354         }
355       return false;
356     }
357
358     bool maySetTransactValue( TransactValue newVal_r, TransactByValue causer_r )
359     {
360         bit::BitField<FieldType> savBitfield = _bitfield;
361         bool ret = setTransactValue( newVal_r, causer_r );
362         _bitfield = savBitfield;
363         return ret;
364     }
365
366     /** Apply a lock (prevent transaction).
367      * Currently by USER or APPL_HIGH only, but who knows...
368      * Set LOCKED from KEEP_STATE to be shure all transaction
369      * details were reset properly.
370     */
371     bool setLock( bool toLock_r, TransactByValue causer_r )
372     {
373       if ( toLock_r == isLocked() )
374         {
375           // we're already in the desired state, but in case of
376           // LOCKED, remember a superior causer.
377           if ( isLocked() && isLessThan<TransactByField>( causer_r ) )
378             fieldValueAssign<TransactByField>( causer_r );
379            return true;
380         }
381       // Here: Lock status is to be changed:
382       if ( causer_r != USER && causer_r != APPL_HIGH )
383         return false;
384       if ( toLock_r ) {
385         // We're in unlocked state, which includes TRANSACT.
386         // Causer must be allowed to reset this. But from
387         // KEEP_STATE every causer is allowed to set the lock.
388         if ( ! setTransact( false, causer_r ) )
389           return false;
390         fieldValueAssign<TransactField>( LOCKED );
391         fieldValueAssign<TransactByField>( causer_r );
392       } else {
393         // To leave Locked state it needs a superior causer.
394         if ( isGreaterThan<TransactByField>( causer_r ) )
395           return false;
396         fieldValueAssign<TransactField>( KEEP_STATE );
397         fieldValueAssign<TransactByField>( SOLVER ); // reset to lowest causer
398                                                      // in order to distinguish from keep_state_by_user
399       }
400       return true;
401     }
402
403     bool maySetLock( bool to_r, TransactByValue causer_r )
404     {
405         bit::BitField<FieldType> savBitfield = _bitfield;
406         bool ret = setLock( to_r, causer_r );
407         _bitfield = savBitfield;
408         return ret;
409     }
410
411     /** Toggle between TRANSACT and KEEP_STATE.
412      * LOCKED state means KEEP_STATE. But in contrary to KEEP_STATE,
413      * LOCKED state is immutable for \a causer_r less than TransactByValue.
414      * KEEP_STATE may be canged by any \a causer_r.
415     */
416     bool setTransact( bool toTansact_r, TransactByValue causer_r )
417     {
418       if ( toTansact_r == transacts() )
419         {
420           // we're already in the desired state, but in case of
421           // TRANSACT, remember a superior causer.
422           if ( transacts() && isLessThan<TransactByField>( causer_r ) )
423               fieldValueAssign<TransactByField>( causer_r );
424
425           fieldValueAssign<TransactDetailField>( NO_DETAIL ); // Details has to be set again
426           return true;
427         }
428       // Here: transact status is to be changed:
429       if (    ! fieldValueIs<TransactField>( KEEP_STATE )
430               && isGreaterThan<TransactByField>( causer_r ) ) {
431         return false;
432       }
433
434       if ( toTansact_r )
435       {
436           fieldValueAssign<TransactField>( TRANSACT );
437       }
438       else
439       {
440           fieldValueAssign<TransactField>( KEEP_STATE );
441       }
442       fieldValueAssign<TransactDetailField>( NO_DETAIL ); // Details has to be set again
443       fieldValueAssign<TransactByField>( causer_r );
444       return true;
445     }
446
447     bool maySetTransact( bool val_r, TransactByValue causer )
448     {
449         bit::BitField<FieldType> savBitfield = _bitfield;
450         bool ret = setTransact (val_r, causer);
451         _bitfield = savBitfield;
452         return ret;
453     }
454
455     /** */
456     bool setSoftLock( TransactByValue causer_r )
457     {
458       if ( ! setTransact( false, causer_r ) )
459         return false;
460       if ( fieldValueIs<TransactField>( KEEP_STATE )
461            && isLessThan<TransactByField>( causer_r ) )
462         fieldValueAssign<TransactByField>( causer_r );
463       return true;
464     }
465
466     /** Not the same as setTransact( false ).
467      */
468     bool resetTransact( TransactByValue causer_r )
469     {
470       if ( ! setTransact( false, causer_r ) )
471         return false;
472       if ( fieldValueIs<TransactField>( KEEP_STATE ) )
473         fieldValueAssign<TransactByField>( SOLVER );
474       return true;
475     }
476
477     /** Soft toggle between TRANSACT and KEEP_STATE.
478      * Similar to setTransact, but leaving KEEP_STATE also requires
479      * a superior \a causerLimit_r. So this is a kind of soft lock.
480      * \code
481      * // SOLVER wants to set TRANSACT, iff KEEP_STATE is
482      * // not superior to APPL_LOW.
483      * setSoftTransact( true, SOLVER, APPL_LOW );
484      * \endcode
485     */
486     bool setSoftTransact( bool toTansact_r, TransactByValue causer_r,
487                           TransactByValue causerLimit_r )
488     {
489       if ( fieldValueIs<TransactField>( KEEP_STATE )
490            && toTansact_r != transacts()
491            && isGreaterThan<TransactByField>( causerLimit_r ) )
492         {
493           // any transact status change requires a superior causer.
494           return false;
495         }
496       return setTransact( toTansact_r, causer_r );
497     }
498
499     bool setSoftTransact( bool toTansact_r, TransactByValue causer_r )
500     { return setSoftTransact( toTansact_r, causer_r, causer_r ); }
501
502     bool maySetSoftTransact( bool val_r, TransactByValue causer,
503                              TransactByValue causerLimit_r )
504     {
505         bit::BitField<FieldType> savBitfield = _bitfield;
506         bool ret = setSoftTransact( val_r, causer, causerLimit_r );
507         _bitfield = savBitfield;
508         return ret;
509     }
510
511     bool maySetSoftTransact( bool val_r, TransactByValue causer )
512     { return maySetSoftTransact( val_r, causer, causer ); }
513
514     bool setToBeInstalled (TransactByValue causer)
515     {
516       if (isInstalled()) return false;
517       return setTransact (true, causer);
518     }
519
520     bool maySetToBeInstalled (TransactByValue causer)
521     {
522         bit::BitField<FieldType> savBitfield = _bitfield;
523         bool ret = setToBeInstalled (causer);
524         _bitfield = savBitfield;
525         return ret;
526     }
527
528     bool setToBeUninstalled (TransactByValue causer)
529     {
530       if (!isInstalled()) return false;
531       return setTransact (true, causer);
532     }
533
534     bool maySetToBeUninstalled (TransactByValue causer)
535     {
536         bit::BitField<FieldType> savBitfield = _bitfield;
537         bool ret = setToBeUninstalled (causer);
538         _bitfield = savBitfield;
539         return ret;
540     }
541
542     //------------------------------------------------------------------------
543     // *** These are only for the Resolver ***
544
545     bool setToBeUninstalledDueToObsolete ( )
546     {
547       if (!setToBeUninstalled (SOLVER)) return false;
548       fieldValueAssign<TransactDetailField>(DUE_TO_OBSOLETE);
549       return true;
550     }
551
552     bool setToBeUninstalledDueToUpgrade ( TransactByValue causer )
553     {
554       if (!setToBeUninstalled (causer)) return false;
555       fieldValueAssign<TransactDetailField>(DUE_TO_UPGRADE);
556       return true;
557     }
558
559     bool setToBeInstalledSoft ( )
560     {
561       if (isInstalled()
562           || !setSoftTransact (true, SOLVER))
563           return false;
564
565       fieldValueAssign<TransactDetailField>(SOFT_INSTALL);
566       return true;
567     }
568
569     bool setToBeUninstalledSoft ( )
570     {
571       if (!isInstalled()
572           || !setSoftTransact (true, SOLVER))
573           return false;
574
575       fieldValueAssign<TransactDetailField>(SOFT_REMOVE);
576       return true;
577     }
578
579     bool maySetToBeUninstalledSoft ()
580     {
581         bit::BitField<FieldType> savBitfield = _bitfield;
582         bool ret = setToBeUninstalledSoft ();
583         _bitfield = savBitfield;
584         return ret;
585     }
586
587     bool isSoftInstall () {
588         return fieldValueIs<TransactDetailField> (SOFT_INSTALL);
589     }
590
591     bool isSoftUninstall () {
592         return fieldValueIs<TransactDetailField> (SOFT_REMOVE);
593     }
594
595     bool setSoftInstall (bool flag) {
596         fieldValueAssign<TransactDetailField>(flag?SOFT_INSTALL:0);
597         return true;
598     }
599
600     bool setSoftUninstall (bool flag) {
601         fieldValueAssign<TransactDetailField>(flag?SOFT_REMOVE:0);
602         return true;
603     }
604
605     bool setUndetermined ()
606     {
607       fieldValueAssign<ValidateField>(UNDETERMINED);
608       return true;
609     }
610
611     bool setSatisfied ()
612     {
613       fieldValueAssign<ValidateField>(SATISFIED);
614       return true;
615     }
616
617     bool setBroken ()
618     {
619       fieldValueAssign<ValidateField>(BROKEN);
620       return true;
621     }
622
623     bool setNonRelevant ()
624     {
625       fieldValueAssign<ValidateField>(NONRELEVANT);
626       return true;
627     }
628
629     bool setStatus( ResStatus newStatus_r )
630     {
631       // State field is immutable!
632       if ( _bitfield.value<StateField>() != newStatus_r._bitfield.value<StateField>() )
633         return false;
634       // Transaction state change allowed?
635       if ( ! setTransactValue( newStatus_r.getTransactValue(), newStatus_r.getTransactByValue() ) )
636         return false;
637
638       // Ok, we take it all..
639       _bitfield = newStatus_r._bitfield;
640       return true;
641     }
642
643     /** \name Builtin ResStatus constants. */
644     //@{
645     static const ResStatus toBeInstalled;
646     static const ResStatus toBeUninstalled;
647     static const ResStatus toBeUninstalledDueToUpgrade;
648     static const ResStatus toBeUninstalledDueToObsolete;
649     //@}
650
651   private:
652     /** Ctor for intialization of builtin constants. */
653     ResStatus( StateValue s,
654                ValidateValue v      = UNDETERMINED,
655                TransactValue t      = KEEP_STATE,
656                InstallDetailValue i = EXPLICIT_INSTALL,
657                RemoveDetailValue r  = EXPLICIT_REMOVE );
658
659     /** Return whether the corresponding Field has value \a val_r.
660     */
661     template<class _Field>
662       bool fieldValueIs( FieldType val_r ) const
663       { return _bitfield.isEqual<_Field>( val_r ); }
664
665     /** Set the corresponding Field to value \a val_r.
666     */
667     template<class _Field>
668       void fieldValueAssign( FieldType val_r )
669       { _bitfield.assign<_Field>( val_r ); }
670
671     /** compare two values.
672     */
673     template<class _Field>
674       bool isGreaterThan( FieldType val_r )
675           { return _bitfield.value<_Field>() > val_r; }
676
677     template<class _Field>
678       bool isLessThan( FieldType val_r )
679           { return _bitfield.value<_Field>() < val_r; }
680
681   private:
682     friend class resstatus::StatusBackup;
683     BitFieldType _bitfield;
684   };
685   ///////////////////////////////////////////////////////////////////
686
687   /** \relates ResStatus Stream output */
688   std::ostream & operator<<( std::ostream & str, const ResStatus & obj );
689
690   /** \relates ResStatus Stream output */
691   std::ostream & operator<<( std::ostream & str, ResStatus::TransactValue obj );
692
693   /** \relates ResStatus Stream output */
694   std::ostream & operator<<( std::ostream & str, ResStatus::TransactByValue obj );
695
696   /** \relates ResStatus */
697   inline bool operator==( const ResStatus & lhs, const ResStatus & rhs )
698   { return lhs._bitfield == rhs._bitfield; }
699
700   /** \relates ResStatus */
701   inline bool operator!=( const ResStatus & lhs, const ResStatus & rhs )
702   { return ! (lhs == rhs); }
703
704   ///////////////////////////////////////////////////////////////////
705
706   namespace resstatus
707   {
708     class StatusBackup
709     {
710       public:
711         StatusBackup()
712         : _status( 0 )
713         {}
714
715         StatusBackup( ResStatus & status_r )
716         : _status( &status_r )
717         , _bitfield( _status->_bitfield )
718         {}
719
720         void replay()
721         { if ( _status ) _status->_bitfield = _bitfield; }
722
723       private:
724         ResStatus *             _status;
725         ResStatus::BitFieldType _bitfield;
726     };
727   }
728
729  /////////////////////////////////////////////////////////////////
730 } // namespace zypp
731 ///////////////////////////////////////////////////////////////////
732 #endif // ZYPP_RESSTATUS_H