1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/ResFilters.h
12 #ifndef ZYPP_RESFILTERS_H
13 #define ZYPP_RESFILTERS_H
17 #include "zypp/Resolvable.h"
19 ///////////////////////////////////////////////////////////////////
21 { /////////////////////////////////////////////////////////////////
22 ///////////////////////////////////////////////////////////////////
24 { /////////////////////////////////////////////////////////////////
25 /** \defgroup RESFILTERS Filter functors operating on Resolvables.
27 * A simple filter is a function or functor matching the signature:
29 * bool simplefilter( Resolvable::Ptr );
32 * \note It's not neccessary that your function or functor actually
33 * returns \c bool. Anything which is convertible into a \c bool
36 * Besides basic filter functors which actually evaluate the
37 * \c Resolvable (e.g. \ref ByKind, \ref ByName), there are some
38 * special functors to build more complex queries:
40 * \li \ref True and \ref False. No supprise, they always return
41 * \c true or \c false.
42 * \li \ref Not\<_Condition\>. _Condition is a filter functor, and
43 * it's result is inverted.
44 * \li \ref Chain\<_ACondition,_BCondition\>. \c _ACondition and \c _BCondition
45 * are filter functors, and Chain evaluates
46 * <tt>_ACondition && _BCondition</tt>
48 * As it's no fun to get and write the correct template arguments,
49 * convenience functions creating the correct functor are provided.
51 * \li \c true_c and \c false_c. (provided just to match the schema)
52 * \li \c not_c. Takes a functor as argument and returns the appropriate
54 * \li \c chain. Takes two functors and returns the appropriate
58 * // some 'action' functor, printing and counting
60 * struct PrintAndCount
62 * PrintAndCount( unsigned & counter_r )
63 * : _counter( counter_r )
66 * bool operator()( Resolvable::Ptr p ) const
73 * unsigned & _counter;
78 * unsigned counter = 0;
80 * // print and count all resolvables
81 * store.forEach( PrintAndCount(counter) );
83 * // print and count all resolvables named "kernel"
85 * store.forEach( ByName("kernel"), PrintAndCount(counter) );
87 * // print and count all Packages named "kernel"
89 * store.forEach( chain( ByKind(ResTraits<Package>::kind),
91 * PrintAndCount(counter) );
93 * // print and count all Packages not named "kernel"
95 * store.forEach( chain( ByKind(ResTraits<Package>::kind),
96 * not_c(ByName("kernel")) ),
97 * PrintAndCount(counter) );
101 * store.forEach( chain( ByKind(ResTraits<Package>::kind),
102 * chain( not_c(ByName("kernel")),
103 * PrintAndCount(counter) ) ),
107 * As you can see in the last example there is no difference in using
108 * a filter or an action functor, as both have the same signature.
109 * A difference of course is the way forEach interprets the returned
112 * Consequently you can netgate and chain actions as well. Thus
113 * <tt>PrintAndCount(counter)</tt> could be
114 * <tt>chain(Print(),Count(counter))</tt>, if these functors are
117 * \note These functors are not limited to be used with ResStore::forEach.
118 * You can use them with std::algorithms as well.
120 * \note In case you already have functions or methods which do what you
121 * want, but thet don't perfectly match the required signature: Make yourself
122 * familiar with <tt>std::ptr_fun, mem_fun, bind1st, bind2nd and compose</tt>.
123 * They are sometimes quite helpfull.
125 * \c PrintAndCount is an example how a functor can return data collected
126 * during the query. You ca easily write a collector, that takes a
127 * <tt>std:list\<Resolvable::Ptr\>\&</tt> and fills it with the matches
130 * But as a rule of thumb, a functor should be lightweight. If you
131 * want to get data out, pass references to variables in (and assert
132 * these variables live as long as the quiery lasts).
134 * Internally all functors are passed by value. Thus it would not help
135 * you to create an instance of some collecting functor, and pass it
136 * to the query. The query will then fill a copy of your functor, you
137 * won't get the data back. (Well, you probabely could, by using
140 * Why functors and not plain functions?
142 * You can use plain functions if they don't have to deliver data back to
144 * The \c C-style approach is having functions that take a <tt>void * data</tt>
145 * as last argument. This \c data pointer is then passed arround and casted
148 * If you look at a functor, you'll see that it contains both, the function
149 * to call (it's <tt>operator()</tt> ) and the data you'd otherwise pass as
150 * <tt>void * data</tt>. That's nice and safe.
153 ///////////////////////////////////////////////////////////////////
155 // Predefined filters
157 ///////////////////////////////////////////////////////////////////
161 bool operator()( Resolvable::Ptr ) const
170 ///////////////////////////////////////////////////////////////////
174 bool operator()( Resolvable::Ptr ) const
183 ///////////////////////////////////////////////////////////////////
185 template<class _Condition>
188 Not( _Condition cond_r )
191 bool operator()( Resolvable::Ptr p ) const
198 template<class _Condition>
199 Not<_Condition> not_c( _Condition cond_r )
201 return Not<_Condition>( cond_r );
204 ///////////////////////////////////////////////////////////////////
206 template<class _ACondition, class _BCondition>
209 Chain( _ACondition conda_r, _BCondition condb_r )
213 bool operator()( Resolvable::Ptr p ) const
215 return _conda( p ) && _condb( p );
221 template<class _ACondition, class _BCondition>
222 Chain<_ACondition, _BCondition> chain( _ACondition conda_r, _BCondition condb_r )
224 return Chain<_ACondition, _BCondition>( conda_r, condb_r );
227 ///////////////////////////////////////////////////////////////////
229 // Now some Resolvable attributes
231 ///////////////////////////////////////////////////////////////////
235 ByKind( const Resolvable::Kind & kind_r )
238 bool operator()( Resolvable::Ptr p ) const
240 return p->kind() == _kind;
242 Resolvable::Kind _kind;
247 ByName( const std::string & name_r )
250 bool operator()( Resolvable::Ptr p ) const
252 return p->name() == _name;
257 ///////////////////////////////////////////////////////////////////
260 /////////////////////////////////////////////////////////////////
261 } // namespace resfilter
262 ///////////////////////////////////////////////////////////////////
263 /////////////////////////////////////////////////////////////////
265 ///////////////////////////////////////////////////////////////////
266 #endif // ZYPP_RESFILTERS_H