1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/CapMatchHelper.h
12 #ifndef ZYPP_CAPMATCHHELPER_H
13 #define ZYPP_CAPMATCHHELPER_H
15 #include "zypp/base/Algorithm.h"
16 #include "zypp/base/Function.h"
17 #include "zypp/ResPool.h"
19 ///////////////////////////////////////////////////////////////////
21 { /////////////////////////////////////////////////////////////////
23 /** Functor testing whether argument matches a certain Capability.
27 class MatchesCapability
30 MatchesCapability( const Capability & lhs_r )
34 bool operator()( const CapAndItem & capitem_r ) const
35 { return operator()( capitem_r.cap ); }
37 bool operator()( const Capability & rhs_r ) const
38 { return( _lhs.matches( rhs_r ) == CapMatch::yes ); }
41 const Capability & _lhs;
44 /** \defgroup CAPMATCHHELPER Find matching Capabilities.
45 * \ingroup g_Algorithm
49 /** Algorithm invoking \c action_r on each \ref CapSet entry
50 * that matches a given \ref Capability.
52 inline int forEachMatchIn( CapSet::const_iterator begin_r,
53 CapSet::const_iterator end_r,
54 const Capability & lhs_r,
55 function<bool(const Capability &)> action_r )
57 std::string index( lhs_r.index() );
58 return invokeOnEach( begin_r, end_r,
59 MatchesCapability( lhs_r ), // filter
63 /** Algorithm invoking \c action_r on each \ref CapSet entry
64 * that matches a given \ref Capability.
66 inline int forEachMatchIn( const CapSet & capset_r,
67 const Capability & lhs_r,
68 function<bool(const Capability &)> action_r )
70 return invokeOnEach( capset_r.begin(), capset_r.end(),
71 MatchesCapability( lhs_r ), // filter
75 /** Algorithm invoking \c action_r on each matching \ref Capability
79 * // Returns wheter willing to collect more items.
80 * bool consume( const CapAndItem & cai_r );
84 * // Invoke consume on all provides that match _cap
85 * forEachMatchIn( _pool, Dep::PROVIDES, _cap, consume );
89 * \see ForEachMatchInPool
91 inline int forEachMatchIn( const ResPool & pool_r, const Dep & dep_r,
92 const Capability & lhs_r,
93 function<bool(const CapAndItem &)> action_r )
95 std::string index( lhs_r.index() );
96 return invokeOnEach( pool_r.byCapabilityIndexBegin( index, dep_r ),
97 pool_r.byCapabilityIndexEnd( index, dep_r ),
98 MatchesCapability( lhs_r ), // filter
103 ///////////////////////////////////////////////////////////////////
105 /** Functor invoking \c action_r on each matching \ref Capability
108 * Functor is provided to ease using \ref forEachMatchIn as action
109 * in other algorithms (nested loop over two CapSets).
111 class ForEachMatchInCapSet
114 typedef function<bool(const Capability &, const Capability &)> Action;
117 ForEachMatchInCapSet( const CapSet & set_r, const Action & action_r )
119 , _action( action_r )
122 bool operator()( const Capability & cap_r ) const
124 return( forEachMatchIn( _set, cap_r, bind( _action, _1, cap_r ) )
125 >= 0 ); // i.e. _action did not return false
133 /** Invoke \c action_r on each matching pair of Capabilities within
135 inline int forEachMatchIn( const CapSet & lhs_r,
136 const CapSet & rhs_r,
137 function<bool(const Capability &, const Capability &)> action_r )
139 return invokeOnEach( lhs_r.begin(), lhs_r.end(),
140 ForEachMatchInCapSet( rhs_r, action_r ) );
142 ///////////////////////////////////////////////////////////////////
144 namespace capmatch_detail {
147 bool operator()( const Capability &, const Capability & ) const
149 bool operator()( const Capability & ) const
154 /** Return \c true if the CapSet contains at least one Capabilitiy
157 inline bool hasMatches( const CapSet & lhs_r, const Capability & rhs_r )
159 return( forEachMatchIn( lhs_r, rhs_r, capmatch_detail::AlwaysFalse() ) < 0 );
162 /** Return \c true if the CapSets contain at least one pair of
163 * Capabilities that match.
165 inline bool hasMatches( const CapSet & lhs_r, const CapSet & rhs_r )
167 return( forEachMatchIn( lhs_r, rhs_r, capmatch_detail::AlwaysFalse() ) < 0 );
170 ///////////////////////////////////////////////////////////////////
173 /** Functor invoking \c action_r on each matching \ref Capability
176 * Functor is provided to ease using \ref forEachMatchIn as action
177 * in other algorithms.
180 * bool consume( const CapAndItem & cai_r );
185 * // Invoke consume on all PoolItems obsoleted by pi.
186 * // short: forEachPoolItemMatchedBy( _pool, _pi, Dep::OBSOLETES, consume );
187 * for_each( _pi->dep(Dep::OBSOLETES).begin(),
188 * _pi->dep(Dep::OBSOLETES).end(),
189 * ForEachMatchInPool( _pool, Dep::PROVIDES, consume ) );
191 * // Invoke consume on all PoolItems obsoleting pi.
192 * // short: forEachPoolItemMatching( _pool, Dep::OBSOLETES, _pi, consume );
193 * for_each( pi->dep(Dep::PROVIDES).begin(),
194 * pi->dep(Dep::PROVIDES).end(),
195 * ForEachMatchInPool( _pool, Dep::OBSOLETES, consume ) );
200 * \ingroup CAPFILTERS
202 * \see forEachPoolItemMatchedBy
203 * \see forEachPoolItemMatching
205 class ForEachMatchInPool
208 typedef function<bool(const CapAndItem &)> Action;
211 ForEachMatchInPool( const ResPool & pool_r,
213 const Action & action_r )
216 , _action( action_r )
219 bool operator()( const Capability & cap_r ) const
221 return( forEachMatchIn( _pool, _dep, cap_r, _action )
222 >= 0 ); // i.e. _action did not return false
231 /** Find all items in a ResPool matched by a certain PoolItems
234 * Iterates <tt>poolitem_r->dep(poolitemdep_r)</tt>
235 * and invokes \c action_r on each item in \c pool_r,
236 * that provides a match.
238 * bool consume( const CapAndItem & cai_r );
243 * // Invoke consume on all PoolItems obsoleted by pi.
244 * forEachPoolItemMatchedBy( _pool, _pi, Dep::OBSOLETES, consume );
247 * \note \c action_r is invoked for each matching Capability. So if
248 * the same PoolItem provides multiple matches, \c action_r refers
249 * to the same PoolItem multiple times. It may as well be that
250 * \c poolitem_r provides a matching Capability. Use \ref OncePerPoolItem
251 * to compensate this if neccessary.
253 inline int forEachPoolItemMatchedBy( const ResPool & pool_r,
254 const PoolItem & poolitem_r,
255 const Dep & poolitemdep_r,
256 function<bool(const CapAndItem &)> action_r )
258 return invokeOnEach( poolitem_r->dep(poolitemdep_r).begin(),
259 poolitem_r->dep(poolitemdep_r).end(),
260 ForEachMatchInPool( pool_r, Dep::PROVIDES, action_r ) );
263 /** Find all items in a ResPool matching a certain PoolItem.
265 * Iterates <tt>poolitem_r->dep(Dep::PROVIDES)</tt>
266 * and invoking \c action_r on each item in \c pool_r,
267 * that provides a match.
269 * bool consume( const CapAndItem & cai_r );
274 * // Invoke consume on all PoolItems obsoleting pi.
275 * forEachPoolItemMatching( _pool, Dep::OBSOLETES, _pi, consume );
278 * \note \c action_r is invoked for each matching Capability. So if
279 * the same PoolItem provides multiple matches, \c action_r refers
280 * to the same PoolItem multiple times. It may as well be that
281 * \c poolitem_r provides a matching Capability. Use \ref OncePerPoolItem
282 * to compensate this if neccessary.
284 inline int forEachPoolItemMatching( const ResPool & pool_r,
285 const Dep & pooldep_r,
286 const PoolItem & poolitem_r,
287 function<bool(const CapAndItem &)> action_r )
289 return invokeOnEach( poolitem_r->dep(Dep::PROVIDES).begin(),
290 poolitem_r->dep(Dep::PROVIDES).end(),
291 ForEachMatchInPool( pool_r, pooldep_r, action_r ) );
294 /** Functor translating \ref CapAndItem actions into \ref PoolItem
295 * actions avoiding multiple invocations for the same \ref PoolItem.
297 * Additionally you may omit invocation of \a action_r for a
300 * Even if no _action is given, the PoolItems that would have been
301 * processed are collected in a std::set, available via
302 * \ref collectedItems.
305 * bool consume( const CapAndItem & cai_r );
306 * bool consumePi( const PoolItem & pi_r );
311 * // Invoke consume on all PoolItems obsoleted by pi.
312 * // Once for each matching Capability, thus the same PoolItem
313 * // might be involved mutiple times.
314 * forEachPoolItemMatchedBy( _pool, _pi, Dep::OBSOLETES,
317 * // Invoke consume on all PoolItems obsoleted by pi.
318 * // Once for each PoolItem, still including _pi in case
319 * // it provides a match by itself.
320 * forEachPoolItemMatchedBy( _pool, _pi, Dep::OBSOLETES,
321 * OncePerPoolItem( consumePi ) );
323 * // Invoke consume on all PoolItems obsoleted by pi.
324 * // Once for each PoolItem, omitting invokation for
325 * // _pi (in case it obsoletes itself).
326 * forEachPoolItemMatchedBy( _pool, _pi, Dep::OBSOLETES,
327 * OncePerPoolItem( consumePi, _pi ) );
330 * \ingroup CAPFILTERS
332 struct OncePerPoolItem
335 typedef function<bool(const PoolItem &)> Action;
339 OncePerPoolItem( const PoolItem & self_r = PoolItem() )
341 , _uset ( new std::set<PoolItem> )
344 OncePerPoolItem( const Action & action_r,
345 const PoolItem & self_r = PoolItem() )
346 : _action( action_r )
348 , _uset ( new std::set<PoolItem> )
351 bool operator()( const CapAndItem & cai_r ) const
353 if ( cai_r.item == _self ) // omit _self
355 // intentionally collect items in _uset even
356 // if no _action specified.
357 if ( _uset->insert( cai_r.item ).second
359 return _action( cai_r.item );
364 const std::set<PoolItem> & collectedItems() const
370 shared_ptr<std::set<PoolItem> > _uset;
376 /////////////////////////////////////////////////////////////////
378 ///////////////////////////////////////////////////////////////////
379 #endif // ZYPP_CAPMATCHHELPER_H