ignore
[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/Resolvable.h"
19 #include "zypp/CapFilters.h"
20
21 #include "zypp/Source.h"
22
23 #include "zypp/PoolItem.h"
24 #include "zypp/CapAndItem.h"
25
26 ///////////////////////////////////////////////////////////////////
27 namespace zypp
28 { /////////////////////////////////////////////////////////////////
29   ///////////////////////////////////////////////////////////////////
30   namespace resfilter
31   { /////////////////////////////////////////////////////////////////
32
33     /** \defgroup RESFILTERS Filter functors operating on ResObjects.
34      * \ingroup g_Functor
35      *
36      * A simple filter is a function or functor matching the signature:
37      * \code
38      *   bool simplefilter( ResObject::Ptr );
39      * \endcode
40      *
41      * \note It's not neccessary that your function or functor actually
42      * returns \c bool. Anything which is convertible into a \c bool
43      * will do;
44      *
45      * Besides basic filter functors which actually evaluate the
46      * \c ResObject (e.g. \ref ByKind, \ref ByName) you may
47      * use \ref LOGICALFILTERS to build more complex filters.
48      *
49      * \code
50      * // some 'action' functor, printing and counting
51      * // ResObjects.
52      * struct PrintAndCount
53      * {
54      *   PrintAndCount( unsigned & counter_r )
55      *   : _counter( counter_r )
56      *   {}
57      *
58      *   bool operator()( ResObject::Ptr p ) const
59      *   {
60      *     DBG << *p << endl;
61      *     ++_counter;
62      *     return true;
63      *   }
64      *
65      *   unsigned & _counter;
66      * };
67      *
68      * ResStore store;
69      * unsigned counter = 0;
70      *
71      * // print and count all resolvables
72      * store.forEach( PrintAndCount(counter) );
73      *
74      * // print and count all resolvables named "kernel"
75      * counter = 0;
76      * store.forEach( ByName("kernel"), PrintAndCount(counter) );
77      *
78      * // print and count all Packages named "kernel"
79      * counter = 0;
80      * store.forEach( chain( ByKind(ResTraits<Package>::kind),
81      *                       ByName("kernel") ),
82      *                PrintAndCount(counter) );
83      *
84      * // print and count all Packages not named "kernel"
85      * counter = 0;
86      * store.forEach( chain( ByKind(ResTraits<Package>::kind),
87      *                       not_c(ByName("kernel")) ),
88      *                PrintAndCount(counter) );
89      *
90      * // same as above ;)
91      * counter = 0;
92      * store.forEach( chain( ByKind(ResTraits<Package>::kind),
93      *                       chain( not_c(ByName("kernel")),
94      *                              PrintAndCount(counter) ) ),
95      *                true_c() );
96      * \endcode
97      *
98      * As you can see in the last example there is no difference in using
99      * a filter or an action functor, as both have the same signature.
100      * A difference of course is the way forEach interprets the returned
101      * value.
102      *
103      * Consequently you can netgate and chain actions as well. Thus
104      * <tt>PrintAndCount(counter)</tt> could be
105      * <tt>chain(Print(),Count(counter))</tt>, if these functors are
106      * provided.
107      *
108      * \note These functors are not limited to be used with ResStore::forEach.
109      * You can use them with std::algorithms as well.
110      *
111      * \note In case you already have functions or methods which do what you
112      * want, but thet don't perfectly match the required signature: Make yourself
113      * familiar with <tt>std::ptr_fun, mem_fun, bind1st, bind2nd and compose</tt>.
114      * They are sometimes quite helpfull.
115      *
116      * \c PrintAndCount is an example how a functor can return data collected
117      * during the query. You ca easily write a collector, that takes a
118      * <tt>std:list\<ResObject::Ptr\>\&</tt> and fills it with the matches
119      * found.
120      *
121      * But as a rule of thumb, a functor should be lightweight. If you
122      * want to get data out, pass references to variables in (and assert
123      * these variables live as long as the query lasts). Or use \ref FunctorRef.
124      *
125      * Internally all functors are passed by value. Thus it would not help
126      * you to create an instance of some collecting functor, and pass it
127      * to the query. The query will then fill a copy of your functor, you
128      * won't get the data back. (Well, you probabely could, by using
129      * boosr::ref).
130      *
131      * Why functors and not plain functions?
132      *
133      * You can use plain functions if they don't have to deliver data back to
134      * the application.
135      * The \c C-style approach is having functions that take a <tt>void * data</tt>
136      * as last argument. This \c data pointer is then passed arround and casted
137      * up and down.
138      *
139      * If you look at a functor, you'll see that it contains both, the function
140      * to call (it's <tt>operator()</tt> ) and the data you'd otherwise pass as
141      * <tt>void * data</tt>. That's nice and safe.
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     /** Select ResObject by kind. */
155     struct ByKind : public ResObjectFilterFunctor
156     {
157       ByKind( const ResObject::Kind & kind_r )
158       : _kind( kind_r )
159       {}
160
161       bool operator()( ResObject::constPtr p ) const
162       {
163         return p->kind() == _kind;
164       }
165
166       ResObject::Kind _kind;
167     };
168
169     /** */
170     template<class _Res>
171       inline ByKind byKind()
172       { return ByKind( ResTraits<_Res>::kind ); }
173
174     /** Select ResObject by name. */
175     struct ByName : public ResObjectFilterFunctor
176     {
177       ByName( const std::string & name_r )
178       : _name( name_r )
179       {}
180
181       bool operator()( ResObject::constPtr p ) const
182       {
183         return p->name() == _name;
184       }
185
186       std::string _name;
187     };
188
189
190     /** Select ResObject by source. */
191     struct BySource : public ResObjectFilterFunctor
192     {
193       BySource( Source_Ref source_r )
194       : _source( source_r )
195       {}
196
197       bool operator()( ResObject::constPtr p ) const
198       {
199         return p->source() == _source;
200       }
201
202       Source_Ref _source;
203     };
204
205
206     /** Select ResObject by Edition using \a _Compare functor.
207      *
208      * Selects ResObject if <tt>_Compare( ResObject->edition(), _edition )<\tt>
209      * is \c true.
210      * \code
211      * // use the convenience funktions to create ByEdition:
212      *
213      * byEdition( someedition ); // selects ResObjects with edition == someedition
214      *
215      * byEdition( someedition, CompareByGT<Edition>() ) //  edition >  someedition
216      * \endcode
217     */
218     template<class _Compare = CompareByEQ<Edition> >
219       struct ByEdition : public ResObjectFilterFunctor
220       {
221         ByEdition( const Edition & edition_r,
222                    _Compare cmp_r )
223         : _edition( edition_r )
224         , _cmp( cmp_r )
225         {}
226
227         bool operator()( ResObject::constPtr p ) const
228         {
229           return _cmp( p->edition(), _edition );
230         }
231
232         Edition  _edition;
233         _Compare _cmp;
234       };
235
236     /** */
237     template<class _Compare>
238       ByEdition<_Compare> byEdition( const Edition & edition_r, _Compare cmp_r )
239       { return ByEdition<_Compare>( edition_r, cmp_r ); }
240
241     /** */
242     template<class _Compare>
243       ByEdition<_Compare> byEdition( const Edition & edition_r )
244       { return byEdition( edition_r, _Compare() ); }
245
246
247     /** Select ResObject by Arch using \a _Compare functor.
248      *
249      * Selects ResObject if <tt>_Compare( ResObject->arch(), _arch )<\tt>
250      * is \c true.
251      * \code
252      * // use the convenience funktions to create ByArch:
253      *
254      * byArch( somearch ); // selects ResObjects with arch == somearch
255      *
256      * byArch( somearch, CompareByGT<Arch>() ) //  arch >  somearch
257      * \endcode
258     */
259     template<class _Compare = CompareByEQ<Arch> >
260       struct ByArch : public ResObjectFilterFunctor
261       {
262         ByArch( const Arch & arch_r,
263                    _Compare cmp_r )
264         : _arch( arch_r )
265         , _cmp( cmp_r )
266         {}
267
268         bool operator()( ResObject::constPtr p ) const
269         {
270           return _cmp( p->arch(), _arch );
271         }
272
273         Arch  _arch;
274         _Compare _cmp;
275       };
276
277     /** */
278     template<class _Compare>
279       ByArch<_Compare> byArch( const Arch & arch_r, _Compare cmp_r )
280       { return ByArch<_Compare>( arch_r, cmp_r ); }
281
282     /** */
283     template<class _Compare>
284       ByArch<_Compare> byArch( const Arch & arch_r )
285       { return byArch( arch_r, _Compare() ); }
286
287
288     ///////////////////////////////////////////////////////////////////
289
290     ///////////////////////////////////////////////////////////////////
291     //
292     // Some PoolItem attributes
293     //
294     ///////////////////////////////////////////////////////////////////
295
296     /** */
297     typedef std::unary_function<PoolItem, bool> PoolItemFilterFunctor;
298
299     /** Select PoolItem by installed. */
300     struct ByInstalled : public PoolItemFilterFunctor
301     {
302       bool operator()( const PoolItem & p ) const
303       {
304         return p.status().isInstalled();
305       }
306
307     };
308
309     /** Select PoolItem by uninstalled. */
310     struct ByUninstalled : public PoolItemFilterFunctor
311     {
312       bool operator()( const PoolItem & p ) const
313       {
314         return p.status().isUninstalled();
315       }
316     };
317
318     /** Select PoolItem by transact. */
319     struct ByTransact : public PoolItemFilterFunctor
320     {
321       bool operator()( const PoolItem & p ) const
322       {
323         return p.status().transacts();
324       }
325     };
326
327     /** Select PoolItem by lock. */
328     struct ByLock : public PoolItemFilterFunctor
329     {
330       bool operator()( const PoolItem & p ) const
331       {
332         return p.status().isLocked();
333       }
334     };
335       
336
337     ///////////////////////////////////////////////////////////////////
338
339     /** Select ResObject if at least one Capability with
340      *  index \a index_r was found in dependency \a depType_r.
341     */
342     struct ByCapabilityIndex
343     {
344       bool operator()( const CapAndItem & /*cai*/ ) const
345       {
346         return true;                    // its all in the PoolImpl !
347       }
348     };
349
350
351     /** Select ResObject if at least one Capability with
352      *  index \a index_r was found in dependency \a depType_r.
353     */
354     struct ByCapMatch
355     {
356       bool operator()( const CapAndItem & cai ) const
357       {
358         return cai.cap.matches( _cap ) == CapMatch::yes;
359       }
360       ByCapMatch( const Capability & cap_r )
361         : _cap( cap_r )
362       {}
363       const Capability &  _cap;
364     };
365
366
367     /** Select PoolItem by uninstalled. */
368     struct ByCaIUninstalled
369     {
370       bool operator()( const CapAndItem & cai ) const
371       {
372         return cai.item.status().isUninstalled();
373       }
374     };
375
376     /** Select PoolItem by installed. */
377     struct ByCaIInstalled
378     {
379       bool operator()( const CapAndItem & cai ) const
380       {
381         return cai.item.status().isInstalled();
382       }
383     };
384
385     /** Select PoolItem by transact. */
386     struct ByCaITransact
387     {
388       bool operator()( const CapAndItem & cai ) const
389       {
390         return cai.item.status().transacts();
391       }
392     };
393
394     /** Select PoolItem by not transact. */
395     struct ByCaINotTransact
396     {
397       bool operator()( const CapAndItem & cai ) const
398       {
399         return !(cai.item.status().transacts());
400       }
401     };
402
403
404     /** Select CapAndItem by kind. */
405     struct ByCaIKind
406     {
407       ByCaIKind( const ResObject::Kind & kind_r )
408       : _kind( kind_r )
409       {}
410
411       bool operator()( const CapAndItem & cai ) const
412       {
413         return cai.item->kind() == _kind;
414       }
415
416       ResObject::Kind _kind;
417     };
418
419     /** */
420     template<class _Res>
421       inline ByCaIKind byCaIKind()
422       { return ByCaIKind( ResTraits<_Res>::kind ); }
423
424     ///////////////////////////////////////////////////////////////////
425
426     //@}
427     /////////////////////////////////////////////////////////////////
428   } // namespace resfilter
429   ///////////////////////////////////////////////////////////////////
430   /////////////////////////////////////////////////////////////////
431 } // namespace zypp
432 ///////////////////////////////////////////////////////////////////
433 #endif // ZYPP_RESFILTERS_H