Imported Upstream version 14.45.0
[platform/upstream/libzypp.git] / zypp / ResFilters.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/ResFilters.h
10  *
11 */
12 #ifndef ZYPP_RESFILTERS_H
13 #define ZYPP_RESFILTERS_H
14
15 #include <boost/function.hpp>
16
17 #include "zypp/base/Functional.h"
18 #include "zypp/Filter.h"
19 #include "zypp/Resolvable.h"
20
21 #include "zypp/PoolItem.h"
22 #include "zypp/Repository.h"
23
24 ///////////////////////////////////////////////////////////////////
25 namespace zypp
26 { /////////////////////////////////////////////////////////////////
27   ///////////////////////////////////////////////////////////////////
28   namespace resfilter
29   { /////////////////////////////////////////////////////////////////
30
31     /** \defgroup RESFILTERS Filter functors operating on ResObjects.
32      * \ingroup g_Functor
33      *
34      * A simple filter is a function or functor matching the signature:
35      * \code
36      *   bool simplefilter( ResObject::Ptr );
37      * \endcode
38      *
39      * \note It's not neccessary that your function or functor actually
40      * returns \c bool. Anything which is convertible into a \c bool
41      * will do;
42      *
43      * Besides basic filter functors which actually evaluate the
44      * \c ResObject (e.g. \ref ByKind, \ref ByName) you may
45      * use \ref LOGICALFILTERS to build more complex filters.
46      *
47      * \code
48      * // some 'action' functor, printing and counting
49      * // ResObjects.
50      * struct PrintAndCount
51      * {
52      *   PrintAndCount( unsigned & counter_r )
53      *   : _counter( counter_r )
54      *   {}
55      *
56      *   bool operator()( ResObject::Ptr p ) const
57      *   {
58      *     DBG << *p << endl;
59      *     ++_counter;
60      *     return true;
61      *   }
62      *
63      *   unsigned _counter;
64      * };
65      *
66      * ResStore store;
67      * unsigned counter = 0;
68      *
69      * // print and count all resolvables
70      * store.forEach( PrintAndCount(counter) );
71      *
72      * // print and count all resolvables named "kernel"
73      * counter = 0;
74      * store.forEach( ByName("kernel"), PrintAndCount(counter) );
75      *
76      * // print and count all Packages named "kernel"
77      * counter = 0;
78      * store.forEach( chain( ByKind(ResKind::package),
79      *                       ByName("kernel") ),
80      *                PrintAndCount(counter) );
81      *
82      * // print and count all Packages not named "kernel"
83      * counter = 0;
84      * store.forEach( chain( ByKind(ResKind::package),
85      *                       not_c(ByName("kernel")) ),
86      *                PrintAndCount(counter) );
87      *
88      * // same as above ;)
89      * counter = 0;
90      * store.forEach( chain( ByKind(ResKind::package),
91      *                       chain( not_c(ByName("kernel")),
92      *                              PrintAndCount(counter) ) ),
93      *                true_c() );
94      * \endcode
95      *
96      * As you can see in the last example there is no difference in using
97      * a filter or an action functor, as both have the same signature.
98      * A difference of course is the way forEach interprets the returned
99      * value.
100      *
101      * Consequently you can netgate and chain actions as well. Thus
102      * <tt>PrintAndCount(counter)</tt> could be
103      * <tt>chain(Print(),Count(counter))</tt>, if these functors are
104      * provided.
105      *
106      * \note These functors are not limited to be used with ResStore::forEach.
107      * You can use them with std::algorithms as well.
108      *
109      * \note In case you already have functions or methods which do what you
110      * want, but thet don't perfectly match the required signature: Make yourself
111      * familiar with <tt>std::ptr_fun, mem_fun, bind1st, bind2nd and compose</tt>.
112      * They are sometimes quite helpfull.
113      *
114      * \c PrintAndCount is an example how a functor can return data collected
115      * during the query. You ca easily write a collector, that takes a
116      * <tt>std:list\<ResObject::Ptr\>\&</tt> and fills it with the matches
117      * found.
118      *
119      * But as a rule of thumb, a functor should be lightweight. If you
120      * want to get data out, pass references to variables in (and assert
121      * these variables live as long as the query lasts). Or use \ref FunctorRef.
122      *
123      * Internally all functors are passed by value. Thus it would not help
124      * you to create an instance of some collecting functor, and pass it
125      * to the query. The query will then fill a copy of your functor, you
126      * won't get the data back. (Well, you probabely could, by using
127      * boosr::ref).
128      *
129      * Why functors and not plain functions?
130      *
131      * You can use plain functions if they don't have to deliver data back to
132      * the application.
133      * The \c C-style approach is having functions that take a <tt>void * data</tt>
134      * as last argument. This \c data pointer is then passed arround and casted
135      * up and down.
136      *
137      * If you look at a functor, you'll see that it contains both, the function
138      * to call (it's <tt>operator()</tt> ) and the data you'd otherwise pass as
139      * <tt>void * data</tt>. That's nice and safe.
140      *
141      * \todo migrate to namespace filter and enhance to support Solvables as well.
142     */
143     //@{
144     ///////////////////////////////////////////////////////////////////
145     //
146     // Some ResObject attributes
147     //
148     ///////////////////////////////////////////////////////////////////
149
150     /** */
151     typedef std::unary_function<ResObject::constPtr, bool> ResObjectFilterFunctor;
152     typedef boost::function<bool ( ResObject::constPtr )> ResFilter;
153
154     /** */
155     template<class _Res>
156       inline filter::ByKind byKind()
157       { return filter::ByKind( ResTraits<_Res>::kind ); }
158
159     /** Select ResObject by name. */
160     struct ByName : public ResObjectFilterFunctor
161     {
162       ByName( const std::string & name_r )
163       : _name( name_r )
164       {}
165
166       bool operator()( ResObject::constPtr p ) const
167       {
168         return p->name() == _name;
169       }
170
171       std::string _name;
172     };
173
174     /** Select ResObject by repository or repository alias. */
175     struct ByRepository : public ResObjectFilterFunctor
176     {
177       ByRepository( Repository repository_r )
178       : _alias( repository_r.info().alias() )
179       {}
180
181       ByRepository( const std::string & alias_r )
182       : _alias( alias_r )
183       {}
184
185       bool operator()( ResObject::constPtr p ) const
186       {
187         return p->repoInfo().alias() == _alias;
188       }
189
190       std::string _alias;
191     };
192
193     /** Select ResObject by Edition using \a _Compare functor.
194      *
195      * Selects ResObject if <tt>_Compare( ResObject->edition(), _edition )</tt>
196      * is \c true.
197      * \code
198      * // use the convenience funktions to create ByEdition:
199      *
200      * byEdition( someedition ); // selects ResObjects with edition == someedition
201      *
202      * byEdition( someedition, CompareByGT<Edition>() ) //  edition >  someedition
203      * \endcode
204     */
205     template<class _Compare = CompareByEQ<Edition> >
206       struct ByEdition : public ResObjectFilterFunctor
207       {
208         ByEdition( const Edition & edition_r,
209                    _Compare cmp_r )
210         : _edition( edition_r )
211         , _cmp( cmp_r )
212         {}
213
214         bool operator()( ResObject::constPtr p ) const
215         {
216           return _cmp( p->edition(), _edition );
217         }
218
219         Edition  _edition;
220         _Compare _cmp;
221       };
222
223     /** */
224     template<class _Compare>
225       ByEdition<_Compare> byEdition( const Edition & edition_r, _Compare cmp_r )
226       { return ByEdition<_Compare>( edition_r, cmp_r ); }
227
228     /** */
229     template<class _Compare>
230       ByEdition<_Compare> byEdition( const Edition & edition_r )
231       { return byEdition( edition_r, _Compare() ); }
232
233
234     /** Select ResObject by Arch using \a _Compare functor.
235      *
236      * Selects ResObject if <tt>_Compare( ResObject->arch(), _arch )</tt>
237      * is \c true.
238      * \code
239      * // use the convenience funktions to create ByArch:
240      *
241      * byArch( somearch ); // selects ResObjects with arch == somearch
242      *
243      * byArch( somearch, CompareByGT<Arch>() ) //  arch >  somearch
244      * \endcode
245     */
246     template<class _Compare = CompareByEQ<Arch> >
247       struct ByArch : public ResObjectFilterFunctor
248       {
249         ByArch( const Arch & arch_r,
250                    _Compare cmp_r )
251         : _arch( arch_r )
252         , _cmp( cmp_r )
253         {}
254
255         bool operator()( ResObject::constPtr p ) const
256         {
257           return _cmp( p->arch(), _arch );
258         }
259
260         Arch  _arch;
261         _Compare _cmp;
262       };
263
264     /** */
265     template<class _Compare>
266       ByArch<_Compare> byArch( const Arch & arch_r, _Compare cmp_r )
267       { return ByArch<_Compare>( arch_r, cmp_r ); }
268
269     /** */
270     template<class _Compare>
271       ByArch<_Compare> byArch( const Arch & arch_r )
272       { return byArch( arch_r, _Compare() ); }
273
274
275     ///////////////////////////////////////////////////////////////////
276
277     ///////////////////////////////////////////////////////////////////
278     //
279     // Some PoolItem attributes
280     //
281     ///////////////////////////////////////////////////////////////////
282
283     /** */
284     typedef std::unary_function<PoolItem, bool> PoolItemFilterFunctor;
285
286     /** Select PoolItem by installed. */
287     struct ByInstalled : public PoolItemFilterFunctor
288     {
289       bool operator()( const PoolItem & p ) const
290       {
291         return p.status().isInstalled();
292       }
293
294     };
295
296     /** Select PoolItem by uninstalled. */
297     struct ByUninstalled : public PoolItemFilterFunctor
298     {
299       bool operator()( const PoolItem & p ) const
300       {
301         return p.status().isUninstalled();
302       }
303     };
304
305     /** Select PoolItem by transact. */
306     struct ByTransact : public PoolItemFilterFunctor
307     {
308       bool operator()( const PoolItem & p ) const
309       {
310         return p.status().transacts();
311       }
312     };
313
314     /** Select PoolItem by lock. */
315     struct ByLock : public PoolItemFilterFunctor
316     {
317       bool operator()( const PoolItem & p ) const
318       {
319         return p.status().isLocked();
320       }
321     };
322
323     /** Select PoolItem by keep. */
324     struct ByKeep : public PoolItemFilterFunctor
325     {
326       bool operator()( const PoolItem & p ) const
327       {
328         return p.status().isKept();
329       }
330     };
331
332     /** PoolItem which is recommended. */
333     struct ByRecommended : public PoolItemFilterFunctor
334     {
335       bool operator()( const PoolItem & p ) const
336       {
337         return p.status().isRecommended();
338       }
339     };
340
341     /** PoolItem which is suggested. */
342     struct BySuggested : public PoolItemFilterFunctor
343     {
344       bool operator()( const PoolItem & p ) const
345       {
346         return p.status().isSuggested();
347       }
348     };
349
350     //@}
351     /////////////////////////////////////////////////////////////////
352   } // namespace resfilter
353   ///////////////////////////////////////////////////////////////////
354   /////////////////////////////////////////////////////////////////
355 } // namespace zypp
356 ///////////////////////////////////////////////////////////////////
357 #endif // ZYPP_RESFILTERS_H