e17c06743056239ceb11007182f9049fb70d2ee9
[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()
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 _Compare functor.
197      *
198      * Selects ResObject if <tt>_Compare( 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 _Compare = CompareByEQ<Edition> >
209       struct ByEdition : public ResObjectFilterFunctor
210       {
211         ByEdition( const Edition & edition_r,
212                    _Compare cmp_r )
213         : _edition( edition_r )
214         , _cmp( cmp_r )
215         {}
216
217         bool operator()( ResObject::constPtr p ) const
218         {
219           return _cmp( p->edition(), _edition );
220         }
221
222         Edition  _edition;
223         _Compare _cmp;
224       };
225
226     /** */
227     template<class _Compare>
228       ByEdition<_Compare> byEdition( const Edition & edition_r, _Compare cmp_r )
229       { return ByEdition<_Compare>( edition_r, cmp_r ); }
230
231     /** */
232     template<class _Compare>
233       ByEdition<_Compare> byEdition( const Edition & edition_r )
234       { return byEdition( edition_r, _Compare() ); }
235
236
237     /** Select ResObject by Arch using \a _Compare functor.
238      *
239      * Selects ResObject if <tt>_Compare( ResObject->arch(), _arch )</tt>
240      * is \c true.
241      * \code
242      * // use the convenience funktions to create ByArch:
243      *
244      * byArch( somearch ); // selects ResObjects with arch == somearch
245      *
246      * byArch( somearch, CompareByGT<Arch>() ) //  arch >  somearch
247      * \endcode
248     */
249     template<class _Compare = CompareByEQ<Arch> >
250       struct ByArch : public ResObjectFilterFunctor
251       {
252         ByArch( const Arch & arch_r,
253                    _Compare cmp_r )
254         : _arch( arch_r )
255         , _cmp( cmp_r )
256         {}
257
258         bool operator()( ResObject::constPtr p ) const
259         {
260           return _cmp( p->arch(), _arch );
261         }
262
263         Arch  _arch;
264         _Compare _cmp;
265       };
266
267     /** */
268     template<class _Compare>
269       ByArch<_Compare> byArch( const Arch & arch_r, _Compare cmp_r )
270       { return ByArch<_Compare>( arch_r, cmp_r ); }
271
272     /** */
273     template<class _Compare>
274       ByArch<_Compare> byArch( const Arch & arch_r )
275       { return byArch( arch_r, _Compare() ); }
276
277
278     ///////////////////////////////////////////////////////////////////
279
280     ///////////////////////////////////////////////////////////////////
281     //
282     // Some PoolItem attributes
283     //
284     ///////////////////////////////////////////////////////////////////
285
286     /** */
287     typedef std::unary_function<PoolItem, bool> PoolItemFilterFunctor;
288
289     /** Select PoolItem by installed. */
290     struct ByInstalled : public PoolItemFilterFunctor
291     {
292       bool operator()( const PoolItem & p ) const
293       {
294         return p.status().isInstalled();
295       }
296
297     };
298
299     /** Select PoolItem by uninstalled. */
300     struct ByUninstalled : public PoolItemFilterFunctor
301     {
302       bool operator()( const PoolItem & p ) const
303       {
304         return p.status().isUninstalled();
305       }
306     };
307
308     /** Select PoolItem by transact. */
309     struct ByTransact : public PoolItemFilterFunctor
310     {
311       bool operator()( const PoolItem & p ) const
312       {
313         return p.status().transacts();
314       }
315     };
316
317     /** Select PoolItem by lock. */
318     struct ByLock : public PoolItemFilterFunctor
319     {
320       bool operator()( const PoolItem & p ) const
321       {
322         return p.status().isLocked();
323       }
324     };
325
326     /** Select PoolItem by keep. */
327     struct ByKeep : public PoolItemFilterFunctor
328     {
329       bool operator()( const PoolItem & p ) const
330       {
331         return p.status().isKept();
332       }
333     };
334
335     /** PoolItem which is recommended. */
336     struct ByRecommended : public PoolItemFilterFunctor
337     {
338       bool operator()( const PoolItem & p ) const
339       {
340         return p.status().isRecommended();
341       }
342     };
343
344     /** PoolItem which is suggested. */
345     struct BySuggested : public PoolItemFilterFunctor
346     {
347       bool operator()( const PoolItem & p ) const
348       {
349         return p.status().isSuggested();
350       }
351     };
352
353     //@}
354     /////////////////////////////////////////////////////////////////
355   } // namespace resfilter
356   ///////////////////////////////////////////////////////////////////
357   /////////////////////////////////////////////////////////////////
358 } // namespace zypp
359 ///////////////////////////////////////////////////////////////////
360 #endif // ZYPP_RESFILTERS_H