1
by Thomas-Karl Pietrowski
first import |
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 |
{
|
|
8
by Thomas-Karl Pietrowski
syncing with "changes 15.13.0 (11)" #9a0aca7e3a21d768491b141a8ae86ef0c3fbc227 |
162 |
ByName() |
163 |
{}
|
|
164 |
||
1
by Thomas-Karl Pietrowski
first import |
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 |