717792eda1347a71fe3fe37825e44129b76c353d
[platform/upstream/libzypp.git] / zypp / PoolItemBest.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/PoolItemBest.h
10  *
11 */
12 #ifndef ZYPP_POOLITEMBEST_H
13 #define ZYPP_POOLITEMBEST_H
14
15 #include <iosfwd>
16
17 #include "zypp/base/PtrTypes.h"
18 #include "zypp/base/Function.h"
19 #include "zypp/base/Iterator.h"
20 #include "zypp/base/Tr1hash.h"
21
22 #include "zypp/PoolItem.h"
23
24 ///////////////////////////////////////////////////////////////////
25 namespace zypp
26 { /////////////////////////////////////////////////////////////////
27
28   ///////////////////////////////////////////////////////////////////
29   //
30   //    CLASS NAME : PoolItemBest
31   //
32   /** Find the best candidates e.g. in a \ref PoolQuery result.
33    *
34    * The class basically maintains a \c map<IdString,PoolItem> and remembers
35    * for each \c ident (\ref sat::Solvable::ident) the best \ref PoolItem that
36    * was added.
37    *
38    * The default \ref Predicate to determine the best choice is the same that
39    * sorts the \ref ui::Selectable list of available objects, thus follows the
40    * same rules the \ref resolver will apply.
41    *
42    * Ctor argument \ref preferNotLocked causes locked packages to be considered
43    * less than not locked packages.
44    *
45    * \code
46    *   PoolQuery q;
47    *   q.addAttribute(sat::SolvAttr::name, "lib*");
48    *   q.setMatchGlob();
49    *
50    *  // get the best matches and tag them for installation:
51    *  PoolItemBest bestMatches( q.begin(), q.end() );
52    *  if ( ! bestMatches.empty() )
53    *  {
54    *    for_( it, bestMatches.begin(), bestMatches.end() )
55    *    {
56    *      ui::asSelectable()( *it )->setOnSystem( *it, ResStatus::USER );
57    *    }
58    *  }
59    * \endcode
60    *
61    * \todo Support arbitrary Predicates.
62    */
63   class PoolItemBest
64   {
65       typedef std::tr1::unordered_map<IdString,PoolItem> Container;
66     public:
67       /** Predicate returning \c True if \a lhs is a better choice. */
68       typedef boost::function<bool ( const PoolItem & lhs, const PoolItem & rhs )> Predicate;
69
70       typedef Container::size_type      size_type;
71       typedef Container::value_type     value_type;
72       typedef MapKVIteratorTraits<Container>::Value_const_iterator      iterator;
73       typedef MapKVIteratorTraits<Container>::Key_const_iterator        ident_iterator;
74
75     public:
76       /** Indicator argument for ctor: consider locked packages less than not locked packages. */
77       static constexpr bool preferNotLocked = true;
78
79     public:
80       /** Default ctor. */
81       PoolItemBest( bool preferNotLocked_r = false )
82       { _ctor_init( preferNotLocked_r ); }
83
84       /** Ctor feeding a \ref sat::Solvable. */
85       PoolItemBest( sat::Solvable slv_r, bool preferNotLocked_r = false )
86       { _ctor_init( preferNotLocked_r ); add( slv_r ); }
87
88       /** Ctor feeding a \ref PoolItem. */
89       PoolItemBest( const PoolItem & pi_r, bool preferNotLocked_r = false )
90       { _ctor_init( preferNotLocked_r ); add( pi_r ); }
91
92       /** Ctor feeding a range of  \ref sat::Solvable or \ref PoolItem. */
93       template<class TIterator>
94       PoolItemBest( TIterator begin_r, TIterator end_r, bool preferNotLocked_r = false )
95       { _ctor_init( preferNotLocked_r ); add( begin_r, end_r ); }
96
97     public:
98       /** Feed one \ref sat::Solvable. */
99       void add( sat::Solvable slv_r )
100       { add( PoolItem( slv_r ) ); }
101
102       /** Feed one \ref PoolItem. */
103       void add( const PoolItem & pi_r );
104
105       /** Feed a range of  \ref sat::Solvable or \ref PoolItem. */
106       template<class _Iterator>
107       void add( _Iterator begin_r, _Iterator end_r )
108       {
109         for_( it, begin_r, end_r )
110           add( *it );
111       }
112
113     public:
114       /** \name Iterate the collected PoolItems. */
115       //@{
116       /** Whether PoolItems were collected. */
117       bool empty() const        { return container().empty(); }
118       /** Number of PoolItems collected. */
119       size_type size() const    { return container().size(); }
120       /** Pointer to the first PoolItem. */
121       iterator begin() const    { return make_map_value_begin( container() ); }
122       /** Pointer behind the last PoolItem. */
123       iterator end() const      { return make_map_value_end( container() ); }
124
125       /** Return the collected \ref PoolItem with \ref sat::Solvable::ident \a ident_r. */
126       PoolItem find( IdString ident_r ) const;
127       /** \overload Use Solvables ident string. */
128       PoolItem find( sat::Solvable slv_r ) const        { return find( slv_r.ident() ); }
129       /** \overload Use PoolItems ident string. */
130       PoolItem find( const PoolItem & pi_r ) const      { return find( pi_r.satSolvable().ident() ); }
131       //@}
132
133       /** \name Iterate the collected PoolItems ident strings. */
134       //@{
135       /** Pointer to the first item. */
136       ident_iterator identBegin() const { return make_map_key_begin( container() ); }
137       /** Pointer behind the last item. */
138       ident_iterator identEnd() const   { return make_map_key_end( container() ); }
139       //@}
140
141     private:
142       void _ctor_init( bool preferNotLocked_r );
143       void _ctor_init(/*preferNotLocked = false*/);     ///< bin.compat legacy
144       const Container & container() const;
145     private:
146       /** Implementation  */
147       class Impl;
148       /** Pointer to implementation */
149       RWCOW_pointer<Impl> & pimpl()             { return *(reinterpret_cast<RWCOW_pointer<Impl>*>( _dont_use_this_use_pimpl.get() )); }
150       /** Pointer to implementation */
151       const RWCOW_pointer<Impl> & pimpl() const { return *(reinterpret_cast<RWCOW_pointer<Impl>*>( _dont_use_this_use_pimpl.get() )); }
152       /** Avoid need to include Impl definition when inlined ctors (due to tepmlate) are provided. */
153       shared_ptr<void> _dont_use_this_use_pimpl;
154   };
155   ///////////////////////////////////////////////////////////////////
156
157   /** \relates PoolItemBest Stream output */
158   std::ostream & operator<<( std::ostream & str, const PoolItemBest & obj );
159
160   /////////////////////////////////////////////////////////////////
161 } // namespace zypp
162 ///////////////////////////////////////////////////////////////////
163 #endif // ZYPP_POOLITEMBEST_H