Imported Upstream version 16.3.2
[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 TRes>
156       inline filter::ByKind byKind()
157       { return filter::ByKind( ResTraits<TRes>::kind ); }
158
159     /** Select ResObject by name. */
160     struct ByName : public ResObjectFilterFunctor
161     {
162       ByName()
163       {}
164
165       ByName( const std::string & name_r )
166       : _name( name_r )
167       {}
168
169       bool operator()( ResObject::constPtr p ) const
170       {
171         return p->name() == _name;
172       }
173
174       std::string _name;
175     };
176
177     /** Select ResObject by repository or repository alias. */
178     struct ByRepository : public ResObjectFilterFunctor
179     {
180       ByRepository( Repository repository_r )
181       : _alias( repository_r.info().alias() )
182       {}
183
184       ByRepository( const std::string & alias_r )
185       : _alias( alias_r )
186       {}
187
188       bool operator()( ResObject::constPtr p ) const
189       {
190         return p->repoInfo().alias() == _alias;
191       }
192
193       std::string _alias;
194     };
195
196     /** Select ResObject by Edition using \a TCompare functor.
197      *
198      * Selects ResObject if <tt>TCompare( ResObject->edition(), _edition )</tt>
199      * is \c true.
200      * \code
201      * // use the convenience funktions to create ByEdition:
202      *
203      * byEdition( someedition ); // selects ResObjects with edition == someedition
204      *
205      * byEdition( someedition, CompareByGT<Edition>() ) //  edition >  someedition
206      * \endcode
207     */
208     template<class TCompare = CompareByEQ<Edition> >
209       struct ByEdition : public ResObjectFilterFunctor
210       {
211         ByEdition( const Edition & edition_r, TCompare cmp_r )
212         : _edition( edition_r )
213         , _cmp( cmp_r )
214         {}
215
216         bool operator()( ResObject::constPtr p ) const
217         {
218           return _cmp( p->edition(), _edition );
219         }
220
221         Edition  _edition;
222         TCompare _cmp;
223       };
224
225     /** */
226     template<class TCompare>
227       ByEdition<TCompare> byEdition( const Edition & edition_r, TCompare cmp_r )
228       { return ByEdition<TCompare>( edition_r, cmp_r ); }
229
230     /** */
231     template<class TCompare>
232       ByEdition<TCompare> byEdition( const Edition & edition_r )
233       { return byEdition( edition_r, TCompare() ); }
234
235
236     /** Select ResObject by Arch using \a TCompare functor.
237      *
238      * Selects ResObject if <tt>TCompare( ResObject->arch(), _arch )</tt>
239      * is \c true.
240      * \code
241      * // use the convenience funktions to create ByArch:
242      *
243      * byArch( somearch ); // selects ResObjects with arch == somearch
244      *
245      * byArch( somearch, CompareByGT<Arch>() ) //  arch >  somearch
246      * \endcode
247     */
248     template<class TCompare = CompareByEQ<Arch> >
249       struct ByArch : public ResObjectFilterFunctor
250       {
251         ByArch( const Arch & arch_r, TCompare cmp_r )
252         : _arch( arch_r )
253         , _cmp( cmp_r )
254         {}
255
256         bool operator()( ResObject::constPtr p ) const
257         {
258           return _cmp( p->arch(), _arch );
259         }
260
261         Arch  _arch;
262         TCompare _cmp;
263       };
264
265     /** */
266     template<class TCompare>
267       ByArch<TCompare> byArch( const Arch & arch_r, TCompare cmp_r )
268       { return ByArch<TCompare>( arch_r, cmp_r ); }
269
270     /** */
271     template<class TCompare>
272       ByArch<TCompare> byArch( const Arch & arch_r )
273       { return byArch( arch_r, TCompare() ); }
274
275
276     ///////////////////////////////////////////////////////////////////
277
278     ///////////////////////////////////////////////////////////////////
279     //
280     // Some PoolItem attributes
281     //
282     ///////////////////////////////////////////////////////////////////
283
284     /** */
285     typedef std::unary_function<PoolItem, bool> PoolItemFilterFunctor;
286
287     /** Select PoolItem by installed. */
288     struct ByInstalled : public PoolItemFilterFunctor
289     {
290       bool operator()( const PoolItem & p ) const
291       {
292         return p.status().isInstalled();
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