Imported Upstream version 16.3.2
[platform/upstream/libzypp.git] / zypp / ui / SelectableImpl.h
index efba04d..9bdf405 100644 (file)
@@ -17,7 +17,8 @@
 
 #include "zypp/base/PtrTypes.h"
 
-#include "zypp/ZConfig.h"
+#include "zypp/ResPool.h"
+#include "zypp/Resolver.h"
 #include "zypp/ui/Selectable.h"
 #include "zypp/ui/SelectableTraits.h"
 
@@ -55,11 +56,11 @@ namespace zypp
       typedef SelectableTraits::PickList               PickList;
 
     public:
-      template <class _Iterator>
-      Impl( const ResObject::Kind & kind_r,
+      template <class TIterator>
+      Impl( const ResKind & kind_r,
             const std::string & name_r,
-            _Iterator begin_r,
-            _Iterator end_r )
+            TIterator begin_r,
+            TIterator end_r )
       : _ident( sat::Solvable::SplitIdent( kind_r, name_r ).ident() )
       , _kind( kind_r )
       , _name( name_r )
@@ -71,7 +72,6 @@ namespace zypp
           else
             _availableItems.insert( *it );
         }
-        _defaultCandidate = defaultCandidate();
       }
 
     public:
@@ -80,7 +80,7 @@ namespace zypp
       { return _ident; }
 
       /**  */
-      ResObject::Kind kind() const
+      ResKind kind() const
       { return _kind; }
 
       /**  */
@@ -111,7 +111,7 @@ namespace zypp
         PoolItem ret( transactingCandidate() );
         if ( ret )
           return ret;
-        return _candidate ? _candidate : _defaultCandidate;
+        return _candidate ? _candidate : defaultCandidate();
       }
 
       /** Set a userCandidate (out of available objects).
@@ -127,10 +127,10 @@ namespace zypp
        */
       PoolItem candidateObjFrom( Repository repo_r ) const
       {
-        for_( it, availableBegin(), availableEnd() )
+        for ( const PoolItem & pi : available() )
         {
-          if ( (*it)->repository() == repo_r )
-            return *it;
+          if ( pi.repository() == repo_r )
+            return pi;
         }
         return PoolItem();
       }
@@ -143,74 +143,80 @@ namespace zypp
        */
       PoolItem updateCandidateObj() const
       {
-       if ( multiversionInstall() )
-         return identicalInstalled( _defaultCandidate ) ? PoolItem() : _defaultCandidate;
+       PoolItem defaultCand( defaultCandidate() );
 
-        if ( installedEmpty() || ! _defaultCandidate )
-          return _defaultCandidate;
-        // Here: installed and _defaultCandidate are non NULL and it's not a
-        //       multiversion install.
+       // multiversionInstall: This returns the candidate for the last
+       // instance installed. Actually we'd need a list here.
 
-        // update candidate must come from the highest priority repo
-        if ( _defaultCandidate->repoInfo().priority() != (*availableBegin())->repoInfo().priority() )
-          return PoolItem();
+        if ( installedEmpty() || ! defaultCand )
+          return defaultCand;
+        // Here: installed and defaultCand are non NULL and it's not a
+        //       multiversion install.
 
         PoolItem installed( installedObj() );
         // check vendor change
-        if ( ! ( ZConfig::instance().solver_allowVendorChange()
-                 || VendorAttr::instance().equivalent( _defaultCandidate->vendor(), installed->vendor() ) ) )
+        if ( ! ( ResPool::instance().resolver().allowVendorChange()
+                 || VendorAttr::instance().equivalent( defaultCand->vendor(), installed->vendor() ) ) )
           return PoolItem();
 
         // check arch change (arch noarch changes are allowed)
-        if ( _defaultCandidate->arch() != installed->arch()
-           && ! ( _defaultCandidate->arch() == Arch_noarch || installed->arch() == Arch_noarch ) )
+        if ( defaultCand->arch() != installed->arch()
+           && ! ( defaultCand->arch() == Arch_noarch || installed->arch() == Arch_noarch ) )
           return PoolItem();
 
         // check greater edition
-        if ( _defaultCandidate->edition() <= installed->edition() )
+        if ( defaultCand->edition() <= installed->edition() )
           return PoolItem();
 
-        return _defaultCandidate;
+        return defaultCand;
       }
 
       /** \copydoc Selectable::highestAvailableVersionObj()const */
       PoolItem highestAvailableVersionObj() const
       {
         PoolItem ret;
-        for_( it, availableBegin(), availableEnd() )
+        for ( const PoolItem & pi : available() )
         {
-          if ( !ret || (*it).satSolvable().edition() > ret.satSolvable().edition() )
-            ret = *it;
+          if ( !ret || pi.edition() > ret.edition() )
+            ret = pi;
         }
         return ret;
       }
 
       /** \copydoc Selectable::identicalAvailable( const PoolItem & )const */
       bool identicalAvailable( const PoolItem & rhs ) const
+      { return bool(identicalAvailableObj( rhs )); }
+
+      /** \copydoc Selectable::identicalInstalled( const PoolItem & )const */
+      bool identicalInstalled( const PoolItem & rhs ) const
+      { return bool(identicalInstalledObj( rhs )); }
+
+      /** \copydoc Selectable::identicalAvailableObj( const PoolItem & rhs ) const */
+      PoolItem identicalAvailableObj( const PoolItem & rhs ) const
       {
         if ( !availableEmpty() && rhs )
         {
           for_( it, _availableItems.begin(), _availableItems.end() )
           {
             if ( identical( *it, rhs ) )
-              return true;
+              return *it;
           }
         }
-        return false;
+        return PoolItem();
       }
 
-      /** \copydoc Selectable::identicalInstalled( const PoolItem & )const */
-      bool identicalInstalled( const PoolItem & rhs ) const
+      /** \copydoc Selectable::identicalInstalledObj( const PoolItem & rhs ) const */
+      PoolItem identicalInstalledObj( const PoolItem & rhs ) const
       {
         if ( !installedEmpty() && rhs )
         {
           for_( it, _installedItems.begin(), _installedItems.end() )
           {
             if ( identical( *it, rhs ) )
-              return true;
+              return *it;
           }
         }
-        return false;
+        return PoolItem();
       }
 
       /** Best among all objects. */
@@ -230,12 +236,15 @@ namespace zypp
       available_size_type availableSize() const
       { return _availableItems.size(); }
 
-      available_const_iterator availableBegin() const
+      available_iterator availableBegin() const
       { return _availableItems.begin(); }
 
-      available_const_iterator availableEnd() const
+      available_iterator availableEnd() const
       { return _availableItems.end(); }
 
+      inline Iterable<available_iterator>  available() const
+      { return makeIterable( availableBegin(), availableEnd() ); }
+
       ////////////////////////////////////////////////////////////////////////
 
       bool installedEmpty() const
@@ -250,6 +259,9 @@ namespace zypp
       installed_iterator installedEnd() const
       { return _installedItems.end(); }
 
+      inline Iterable<installed_iterator>  installed() const
+      { return makeIterable( installedBegin(), installedEnd() ); }
+
       ////////////////////////////////////////////////////////////////////////
 
       const PickList & picklist() const
@@ -258,10 +270,10 @@ namespace zypp
         {
           _picklistPtr.reset( new PickList );
           // installed without identical avaialble first:
-          for_( it, _installedItems.begin(), _installedItems.end() )
+          for ( const PoolItem & pi : installed() )
           {
-            if ( ! identicalAvailable( *it ) )
-              _picklistPtr->push_back( *it );
+            if ( ! identicalAvailable( pi ) )
+              _picklistPtr->push_back( pi );
           }
           _picklistPtr->insert( _picklistPtr->end(), availableBegin(), availableEnd() );
         }
@@ -286,7 +298,14 @@ namespace zypp
       { return availableEmpty(); }
 
       bool multiversionInstall() const
-      { return theObj().satSolvable().multiversionInstall(); }
+      {
+       for ( const PoolItem & pi : picklist() )
+       {
+         if ( pi.multiversionInstall() )
+           return true;
+       }
+       return false;
+      }
 
       bool pickInstall( const PoolItem & pi_r, ResStatus::TransactByValue causer_r, bool yesno_r );
 
@@ -333,49 +352,47 @@ namespace zypp
     private:
       PoolItem transactingInstalled() const
       {
-        for_( it, installedBegin(), installedEnd() )
+        for ( const PoolItem & pi : installed() )
           {
-            if ( (*it).status().transacts() )
-              return (*it);
+            if ( pi.status().transacts() )
+              return pi;
           }
         return PoolItem();
       }
 
       PoolItem transactingCandidate() const
       {
-        for_( it, availableBegin(), availableEnd() )
+        for ( const PoolItem & pi : available() )
           {
-            if ( (*it).status().transacts() )
-              return (*it);
+            if ( pi.status().transacts() )
+              return pi;
           }
         return PoolItem();
       }
 
       PoolItem defaultCandidate() const
       {
-        if ( ! ( multiversionInstall() || installedEmpty() ) )
+        if ( ! installedEmpty() )
         {
           // prefer the installed objects arch and vendor
-          bool solver_allowVendorChange( ZConfig::instance().solver_allowVendorChange() );
-          for ( installed_const_iterator iit = installedBegin();
-                iit != installedEnd(); ++iit )
+          bool solver_allowVendorChange( ResPool::instance().resolver().allowVendorChange() );
+          for ( const PoolItem & ipi : installed() )
           {
             PoolItem sameArch; // in case there's no same vendor at least stay with same arch.
-            for ( available_const_iterator it = availableBegin();
-                  it != availableEnd(); ++it )
+            for (  const PoolItem & api : available() )
             {
               // 'same arch' includes allowed changes to/from noarch.
-              if ( (*iit)->arch() == (*it)->arch() || (*iit)->arch() == Arch_noarch || (*it)->arch() == Arch_noarch )
+              if ( ipi.arch() == api.arch() || ipi.arch() == Arch_noarch || api.arch() == Arch_noarch )
               {
                 if ( ! solver_allowVendorChange )
                 {
-                  if ( VendorAttr::instance().equivalent( (*iit), (*it) ) )
-                    return *it;
+                  if ( VendorAttr::instance().equivalent( ipi, api ) )
+                    return api;
                   else if ( ! sameArch ) // remember best same arch in case no same vendor found
-                     sameArch = *it;
+                     sameArch = api;
                 }
                 else // same arch is sufficient
-                  return *it;
+                  return api;
               }
             }
             if ( sameArch )
@@ -390,10 +407,9 @@ namespace zypp
 
       bool allCandidatesLocked() const
       {
-        for ( available_const_iterator it = availableBegin();
-              it != availableEnd(); ++it )
+        for ( const PoolItem & pi : available() )
           {
-            if ( ! (*it).status().isLocked() )
+            if ( ! pi.status().isLocked() )
               return false;
           }
         return( ! _availableItems.empty() );
@@ -401,10 +417,9 @@ namespace zypp
 
       bool allInstalledLocked() const
       {
-        for ( installed_const_iterator it = installedBegin();
-              it != installedEnd(); ++it )
+        for ( const PoolItem & pi : installed() )
           {
-            if ( ! (*it).status().isLocked() )
+            if ( ! pi.status().isLocked() )
               return false;
           }
         return( ! _installedItems.empty() );
@@ -413,12 +428,10 @@ namespace zypp
 
     private:
       const IdString         _ident;
-      const ResObject::Kind  _kind;
+      const ResKind          _kind;
       const std::string      _name;
       InstalledItemSet       _installedItems;
       AvailableItemSet       _availableItems;
-      //! Best among availabe with restpect to installed.
-      PoolItem               _defaultCandidate;
       //! The object selected by setCandidateObj() method.
       PoolItem               _candidate;
       //! lazy initialized picklist
@@ -447,14 +460,14 @@ namespace zypp
       {
         PoolItem icand( obj.installedObj() );
         str << "   (I " << obj.installedSize() << ") {" << endl;
-        for_( it, obj.installedBegin(), obj.installedEnd() )
+        for ( const PoolItem & pi : obj.installed() )
         {
           char t = ' ';
-          if ( *it == icand )
+          if ( pi == icand )
           {
             t = 'i';
           }
-          str << " " << t << " " << *it << endl;
+          str << " " << t << " " << pi << endl;
         }
         str << "}  ";
       }
@@ -468,18 +481,18 @@ namespace zypp
         PoolItem cand( obj.candidateObj() );
         PoolItem up( obj.updateCandidateObj() );
         str << "(A " << obj.availableSize() << ") {" << endl;
-        for_( it, obj.availableBegin(), obj.availableEnd() )
+        for ( const PoolItem & pi : obj.available() )
         {
           char t = ' ';
-          if ( *it == cand )
+          if ( pi == cand )
           {
-            t = *it == up ? 'C' : 'c';
+            t = pi == up ? 'C' : 'c';
           }
-          else if ( *it == up )
+          else if ( pi == up )
           {
             t = 'u';
           }
-          str << " " << t << " " << *it << endl;
+          str << " " << t << " " << pi << endl;
         }
         str << "}  ";
       }
@@ -493,18 +506,18 @@ namespace zypp
         PoolItem cand( obj.candidateObj() );
         PoolItem up( obj.updateCandidateObj() );
         str << "(P " << obj.picklistSize() << ") {" << endl;
-        for_( it, obj.picklistBegin(), obj.picklistEnd() )
+        for ( const PoolItem & pi : obj.picklist() )
         {
           char t = ' ';
-          if ( *it == cand )
+          if ( pi == cand )
           {
-            t = *it == up ? 'C' : 'c';
+            t = pi == up ? 'C' : 'c';
           }
-          else if ( *it == up )
+          else if ( pi == up )
           {
             t = 'u';
           }
-          str << " " << t << " " << *it << "\t" << obj.pickStatus( *it ) << endl;
+          str << " " << t << " " << pi << "\t" << obj.pickStatus( pi ) << endl;
         }
         str << "}  ";
       }