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
152 /** Return \c true if the CapSets contain at least one pair of
153 * Capabilities that match.
155 inline bool hasMatches( const CapSet & lhs_r, const CapSet & rhs_r )
157 return( forEachMatchIn( lhs_r, rhs_r, capmatch_detail::AlwaysFalse() ) < 0 );
160 ///////////////////////////////////////////////////////////////////
163 /** Functor invoking \c action_r on each matching \ref Capability
166 * Functor is provided to ease using \ref forEachMatchIn as action
167 * in other algorithms.
170 * bool consume( const CapAndItem & cai_r );
175 * // Invoke consume on all PoolItems obsoleted by pi.
176 * // short: forEachPoolItemMatchedBy( _pool, _pi, Dep::OBSOLETES, consume );
177 * for_each( _pi->dep(Dep::OBSOLETES).begin(),
178 * _pi->dep(Dep::OBSOLETES).end(),
179 * ForEachMatchInPool( _pool, Dep::PROVIDES, consume ) );
181 * // Invoke consume on all PoolItems obsoleting pi.
182 * // short: forEachPoolItemMatching( _pool, Dep::OBSOLETES, _pi, consume );
183 * for_each( pi->dep(Dep::PROVIDES).begin(),
184 * pi->dep(Dep::PROVIDES).end(),
185 * ForEachMatchInPool( _pool, Dep::OBSOLETES, consume ) );
190 * \ingroup CAPFILTERS
192 * \see forEachPoolItemMatchedBy
193 * \see forEachPoolItemMatching
195 class ForEachMatchInPool
198 typedef function<bool(const CapAndItem &)> Action;
201 ForEachMatchInPool( const ResPool & pool_r,
203 const Action & action_r )
206 , _action( action_r )
209 bool operator()( const Capability & cap_r ) const
211 return( forEachMatchIn( _pool, _dep, cap_r, _action )
212 >= 0 ); // i.e. _action did not return false
221 /** Find all items in a ResPool matched by a certain PoolItems
224 * Iterates <tt>poolitem_r->dep(poolitemdep_r)</tt>
225 * and invokes \c action_r on each item in \c pool_r,
226 * that provides a match.
228 * bool consume( const CapAndItem & cai_r );
233 * // Invoke consume on all PoolItems obsoleted by pi.
234 * forEachPoolItemMatchedBy( _pool, _pi, Dep::OBSOLETES, consume );
237 * \note \c action_r is invoked for each matching Capability. So if
238 * the same PoolItem provides multiple matches, \c action_r refers
239 * to the same PoolItem multiple times. It may as well be that
240 * \c poolitem_r provides a matching Capability. Use \ref OncePerPoolItem
241 * to compensate this if neccessary.
243 inline int forEachPoolItemMatchedBy( const ResPool & pool_r,
244 const PoolItem & poolitem_r,
245 const Dep & poolitemdep_r,
246 function<bool(const CapAndItem &)> action_r )
248 return invokeOnEach( poolitem_r->dep(poolitemdep_r).begin(),
249 poolitem_r->dep(poolitemdep_r).end(),
250 ForEachMatchInPool( pool_r, Dep::PROVIDES, action_r ) );
253 /** Find all items in a ResPool matching a certain PoolItem.
255 * Iterates <tt>poolitem_r->dep(Dep::PROVIDES)</tt>
256 * and invoking \c action_r on each item in \c pool_r,
257 * that provides a match.
259 * bool consume( const CapAndItem & cai_r );
264 * // Invoke consume on all PoolItems obsoleting pi.
265 * forEachPoolItemMatching( _pool, Dep::OBSOLETES, _pi, consume );
268 * \note \c action_r is invoked for each matching Capability. So if
269 * the same PoolItem provides multiple matches, \c action_r refers
270 * to the same PoolItem multiple times. It may as well be that
271 * \c poolitem_r provides a matching Capability. Use \ref OncePerPoolItem
272 * to compensate this if neccessary.
274 inline int forEachPoolItemMatching( const ResPool & pool_r,
275 const Dep & pooldep_r,
276 const PoolItem & poolitem_r,
277 function<bool(const CapAndItem &)> action_r )
279 return invokeOnEach( poolitem_r->dep(Dep::PROVIDES).begin(),
280 poolitem_r->dep(Dep::PROVIDES).end(),
281 ForEachMatchInPool( pool_r, pooldep_r, action_r ) );
284 /** Functor translating \ref CapAndItem actions into \ref PoolItem
285 * actions avoiding multiple invocations for the same \ref PoolItem.
287 * Additionally you may omit invocation of \a action_r for a
290 * Even if no _action is given, the PoolItems that would have been
291 * processed are collected in a std::set, available via
292 * \ref collectedItems.
295 * bool consume( const CapAndItem & cai_r );
296 * bool consumePi( const PoolItem & pi_r );
301 * // Invoke consume on all PoolItems obsoleted by pi.
302 * // Once for each matching Capability, thus the same PoolItem
303 * // might be involved mutiple times.
304 * forEachPoolItemMatchedBy( _pool, _pi, Dep::OBSOLETES,
307 * // Invoke consume on all PoolItems obsoleted by pi.
308 * // Once for each PoolItem, still including _pi in case
309 * // it provides a match by itself.
310 * forEachPoolItemMatchedBy( _pool, _pi, Dep::OBSOLETES,
311 * OncePerPoolItem( consumePi ) );
313 * // Invoke consume on all PoolItems obsoleted by pi.
314 * // Once for each PoolItem, omitting invokation for
315 * // _pi (in case it obsoletes itself).
316 * forEachPoolItemMatchedBy( _pool, _pi, Dep::OBSOLETES,
317 * OncePerPoolItem( consumePi, _pi ) );
320 * \ingroup CAPFILTERS
322 struct OncePerPoolItem
325 typedef function<bool(const PoolItem &)> Action;
329 OncePerPoolItem( const PoolItem & self_r = PoolItem() )
331 , _uset ( new std::set<PoolItem> )
334 OncePerPoolItem( const Action & action_r,
335 const PoolItem & self_r = PoolItem() )
336 : _action( action_r )
338 , _uset ( new std::set<PoolItem> )
341 bool operator()( const CapAndItem & cai_r ) const
343 if ( cai_r.item == _self ) // omit _self
345 // intentionally collect items in _uset even
346 // if no _action specified.
347 if ( _uset->insert( cai_r.item ).second
349 return _action( cai_r.item );
354 const std::set<PoolItem> & collectedItems() const
360 shared_ptr<std::set<PoolItem> > _uset;
366 /////////////////////////////////////////////////////////////////
368 ///////////////////////////////////////////////////////////////////
369 #endif // ZYPP_CAPMATCHHELPER_H