1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/ResFilters.h
12 #ifndef ZYPP_RESFILTERS_H
13 #define ZYPP_RESFILTERS_H
15 #include <boost/function.hpp>
17 #include "zypp/base/Functional.h"
18 #include "zypp/Resolvable.h"
19 #include "zypp/CapFilters.h"
21 #include "zypp/Source.h"
23 #include "zypp/PoolItem.h"
24 #include "zypp/CapAndItem.h"
26 ///////////////////////////////////////////////////////////////////
28 { /////////////////////////////////////////////////////////////////
29 ///////////////////////////////////////////////////////////////////
31 { /////////////////////////////////////////////////////////////////
33 /** \defgroup RESFILTERS Filter functors operating on ResObjects.
36 * A simple filter is a function or functor matching the signature:
38 * bool simplefilter( ResObject::Ptr );
41 * \note It's not neccessary that your function or functor actually
42 * returns \c bool. Anything which is convertible into a \c bool
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.
50 * // some 'action' functor, printing and counting
52 * struct PrintAndCount
54 * PrintAndCount( unsigned & counter_r )
55 * : _counter( counter_r )
58 * bool operator()( ResObject::Ptr p ) const
65 * unsigned & _counter;
69 * unsigned counter = 0;
71 * // print and count all resolvables
72 * store.forEach( PrintAndCount(counter) );
74 * // print and count all resolvables named "kernel"
76 * store.forEach( ByName("kernel"), PrintAndCount(counter) );
78 * // print and count all Packages named "kernel"
80 * store.forEach( chain( ByKind(ResTraits<Package>::kind),
82 * PrintAndCount(counter) );
84 * // print and count all Packages not named "kernel"
86 * store.forEach( chain( ByKind(ResTraits<Package>::kind),
87 * not_c(ByName("kernel")) ),
88 * PrintAndCount(counter) );
92 * store.forEach( chain( ByKind(ResTraits<Package>::kind),
93 * chain( not_c(ByName("kernel")),
94 * PrintAndCount(counter) ) ),
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
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
108 * \note These functors are not limited to be used with ResStore::forEach.
109 * You can use them with std::algorithms as well.
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.
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
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.
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
131 * Why functors and not plain functions?
133 * You can use plain functions if they don't have to deliver data back to
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
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.
144 ///////////////////////////////////////////////////////////////////
146 // Some ResObject attributes
148 ///////////////////////////////////////////////////////////////////
151 typedef std::unary_function<ResObject::constPtr, bool> ResObjectFilterFunctor;
152 typedef boost::function<bool ( ResObject::constPtr )> ResFilter;
154 /** Select ResObject by kind. */
155 struct ByKind : public ResObjectFilterFunctor
157 ByKind( const ResObject::Kind & kind_r )
161 bool operator()( ResObject::constPtr p ) const
163 return p->kind() == _kind;
166 ResObject::Kind _kind;
171 inline ByKind byKind()
172 { return ByKind( ResTraits<_Res>::kind ); }
174 /** Select ResObject by name. */
175 struct ByName : public ResObjectFilterFunctor
177 ByName( const std::string & name_r )
181 bool operator()( ResObject::constPtr p ) const
183 return p->name() == _name;
190 /** Select ResObject by source. */
191 struct BySource : public ResObjectFilterFunctor
193 BySource( Source_Ref source_r )
194 : _source( source_r )
197 bool operator()( ResObject::constPtr p ) const
199 return p->source() == _source;
206 /** Select ResObject by Edition using \a _Compare functor.
208 * Selects ResObject if <tt>_Compare( ResObject->edition(), _edition )<\tt>
211 * // use the convenience funktions to create ByEdition:
213 * byEdition( someedition ); // selects ResObjects with edition == someedition
215 * byEdition( someedition, CompareByGT<Edition>() ) // edition > someedition
218 template<class _Compare = CompareByEQ<Edition> >
219 struct ByEdition : public ResObjectFilterFunctor
221 ByEdition( const Edition & edition_r,
223 : _edition( edition_r )
227 bool operator()( ResObject::constPtr p ) const
229 return _cmp( p->edition(), _edition );
237 template<class _Compare>
238 ByEdition<_Compare> byEdition( const Edition & edition_r, _Compare cmp_r )
239 { return ByEdition<_Compare>( edition_r, cmp_r ); }
242 template<class _Compare>
243 ByEdition<_Compare> byEdition( const Edition & edition_r )
244 { return byEdition( edition_r, _Compare() ); }
247 /** Select ResObject by Arch using \a _Compare functor.
249 * Selects ResObject if <tt>_Compare( ResObject->arch(), _arch )<\tt>
252 * // use the convenience funktions to create ByArch:
254 * byArch( somearch ); // selects ResObjects with arch == somearch
256 * byArch( somearch, CompareByGT<Arch>() ) // arch > somearch
259 template<class _Compare = CompareByEQ<Arch> >
260 struct ByArch : public ResObjectFilterFunctor
262 ByArch( const Arch & arch_r,
268 bool operator()( ResObject::constPtr p ) const
270 return _cmp( p->arch(), _arch );
278 template<class _Compare>
279 ByArch<_Compare> byArch( const Arch & arch_r, _Compare cmp_r )
280 { return ByArch<_Compare>( arch_r, cmp_r ); }
283 template<class _Compare>
284 ByArch<_Compare> byArch( const Arch & arch_r )
285 { return byArch( arch_r, _Compare() ); }
288 ///////////////////////////////////////////////////////////////////
290 ///////////////////////////////////////////////////////////////////
292 // Some PoolItem attributes
294 ///////////////////////////////////////////////////////////////////
297 typedef std::unary_function<PoolItem, bool> PoolItemFilterFunctor;
299 /** Select PoolItem by installed. */
300 struct ByInstalled : public PoolItemFilterFunctor
302 bool operator()( const PoolItem & p ) const
304 return p.status().isInstalled();
309 /** Select PoolItem by uninstalled. */
310 struct ByUninstalled : public PoolItemFilterFunctor
312 bool operator()( const PoolItem & p ) const
314 return p.status().isUninstalled();
318 /** Select PoolItem by transact. */
319 struct ByTransact : public PoolItemFilterFunctor
321 bool operator()( const PoolItem & p ) const
323 return p.status().transacts();
327 /** Select PoolItem by lock. */
328 struct ByLock : public PoolItemFilterFunctor
330 bool operator()( const PoolItem & p ) const
332 return p.status().isLocked();
337 ///////////////////////////////////////////////////////////////////
339 /** Select ResObject if at least one Capability with
340 * index \a index_r was found in dependency \a depType_r.
342 struct ByCapabilityIndex
344 bool operator()( const CapAndItem & /*cai*/ ) const
346 return true; // its all in the PoolImpl !
351 /** Select ResObject if at least one Capability with
352 * index \a index_r was found in dependency \a depType_r.
356 bool operator()( const CapAndItem & cai ) const
358 return cai.cap.matches( _cap ) == CapMatch::yes;
360 ByCapMatch( const Capability & cap_r )
363 const Capability & _cap;
367 /** Select PoolItem by uninstalled. */
368 struct ByCaIUninstalled
370 bool operator()( const CapAndItem & cai ) const
372 return cai.item.status().isUninstalled();
376 /** Select PoolItem by installed. */
377 struct ByCaIInstalled
379 bool operator()( const CapAndItem & cai ) const
381 return cai.item.status().isInstalled();
385 /** Select PoolItem by transact. */
388 bool operator()( const CapAndItem & cai ) const
390 return cai.item.status().transacts();
394 /** Select PoolItem by not transact. */
395 struct ByCaINotTransact
397 bool operator()( const CapAndItem & cai ) const
399 return !(cai.item.status().transacts());
404 /** Select CapAndItem by kind. */
407 ByCaIKind( const ResObject::Kind & kind_r )
411 bool operator()( const CapAndItem & cai ) const
413 return cai.item->kind() == _kind;
416 ResObject::Kind _kind;
421 inline ByCaIKind byCaIKind()
422 { return ByCaIKind( ResTraits<_Res>::kind ); }
424 ///////////////////////////////////////////////////////////////////
427 /////////////////////////////////////////////////////////////////
428 } // namespace resfilter
429 ///////////////////////////////////////////////////////////////////
430 /////////////////////////////////////////////////////////////////
432 ///////////////////////////////////////////////////////////////////
433 #endif // ZYPP_RESFILTERS_H