1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/sat/SolvIterMixin.h
12 #ifndef ZYPP_SAT_SOLVITERMIXIN_H
13 #define ZYPP_SAT_SOLVITERMIXIN_H
17 #include "zypp/base/PtrTypes.h"
18 #include "zypp/base/Iterator.h"
19 #include "zypp/base/Tr1hash.h"
21 #include "zypp/sat/Solvable.h"
23 ///////////////////////////////////////////////////////////////////
25 { /////////////////////////////////////////////////////////////////
28 class asPoolItem; // transform functor
32 class asSelectable; // transform functor
35 ///////////////////////////////////////////////////////////////////
37 { /////////////////////////////////////////////////////////////////
40 class asSolvable; // transform functor
42 namespace solvitermixin_detail
44 /** Unify by \c ident \c (kind:name).
45 * Return true on the 1st appearance of a new \c ident. This is
46 * used in \ref SolvIterMixin when mapping a Solvable iterator
47 * to a Selectable iterator.
51 bool operator()( const Solvable & solv_r ) const;
53 typedef std::tr1::unordered_set<unsigned> Uset;
57 shared_ptr<Uset> _uset;
61 } // namespace solvitermixin_detail
64 ///////////////////////////////////////////////////////////////////
66 // CLASS NAME : SolvIterMixin<Derived,DerivedSolvable_iterator>
68 /** Base class providing common iterator types based on a \ref Solvable iterator.
70 * A class deriving from \ref SolvIterMixin must provide two methods
71 * \c begin and \c end returning iterator over \ref sat::Solvable.
73 * \ref SolvIterMixin will then provide iterators over the corresponding
74 * \ref PoolItem and \ref ui::Selectable_Ptr.
76 * \ref SolvIterMixin will also provide default implementations for \ref empty
77 * and \ref size by iterating from \c begin to \c end. In case \c Derived is
78 * able to provide a more efficient implementation, the methods should be overloaded.
80 * \note You will sometimes face the problem, that when using the \ref PoolItem
81 * iterator you hit multiple version of the same package, while when using the
82 * \ref ui::Selectable iterator the information which of the available candidates
83 * actually matched got lost. In this case class \ref PoolItemBest may help you.
84 * Use it to pick the best version only.
89 * class WhatProvidesIterator;
92 * class WhatProvides : public SolvIterMixin<WhatProvides,detail::WhatProvidesIterator>
95 * typedef detail::WhatProvidesIterator const_iterator;
97 * // Iterator pointing to the first Solvable.
98 * const_iterator begin() const;
100 * // Iterator pointing behind the last Solvable.
101 * const_iterator end() const;
107 * class WhatProvidesIterator : public boost::iterator_adaptor<
108 * WhatProvidesIterator // Derived
109 * , const detail::IdType * // Base
110 * , const Solvable // Value
111 * , boost::forward_traversal_tag // CategoryOrTraversal
112 * , const Solvable // Reference
121 template <class Derived,class DerivedSolvable_iterator>
125 typedef size_t size_type;
128 /** \name Convenience methods.
129 * In case \c Derived is able to provide a more efficient implementation,
130 * the methods should be overloaded.
133 /** Whether the collection is epmty. */
135 { return( self().begin() == self().end() ); }
137 /** Size of the collection. */
138 size_type size() const
139 { size_type s = 0; for_( it, self().begin(), self().end() ) ++s; return s;}
141 /** Whether collection contains a specific \ref Solvable. */
142 template<class _Solv>
143 bool contains( const _Solv & solv_r ) const
145 Solvable solv( asSolvable()( solv_r ) );
146 for_( it, self().begin(), self().end() )
154 /** \name Iterate as Solvable */
156 typedef DerivedSolvable_iterator Solvable_iterator;
157 Solvable_iterator solvableBegin() const
158 { return self().begin(); }
159 Solvable_iterator solvableEnd() const
160 { return self().end(); }
163 /** \name Iterate as PoolItem */
165 typedef transform_iterator<asPoolItem,Solvable_iterator> PoolItem_iterator;
166 PoolItem_iterator poolItemBegin() const
167 { return make_transform_iterator( solvableBegin(), asPoolItem() ); }
168 PoolItem_iterator poolItemEnd() const
169 { return make_transform_iterator( solvableEnd(), asPoolItem() ); }
173 typedef filter_iterator<solvitermixin_detail::UnifyByIdent,Solvable_iterator> UnifiedSolvable_iterator;
175 /** \name Iterate ui::Selectable::Ptr */
177 typedef transform_iterator<ui::asSelectable,UnifiedSolvable_iterator> Selectable_iterator;
178 Selectable_iterator selectableBegin() const
179 { return make_transform_iterator( unifiedSolvableBegin(), ui::asSelectable() ); }
180 Selectable_iterator selectableEnd() const
181 { return make_transform_iterator( unifiedSolvableEnd(), ui::asSelectable() ); }
185 /** \name Iterate unified Solbvables to be transformed into Selectable. */
187 UnifiedSolvable_iterator unifiedSolvableBegin() const
188 { return make_filter_iterator( solvitermixin_detail::UnifyByIdent(), solvableBegin(), solvableEnd() ); }
189 UnifiedSolvable_iterator unifiedSolvableEnd() const
190 { return make_filter_iterator( solvitermixin_detail::UnifyByIdent(), solvableEnd(), solvableEnd() );; }
193 const Derived & self() const
194 { return *static_cast<const Derived*>( this ); }
198 SolvIterMixin(const SolvIterMixin &) {}
199 void operator=(const SolvIterMixin &) {}
201 ///////////////////////////////////////////////////////////////////
203 /////////////////////////////////////////////////////////////////
205 ///////////////////////////////////////////////////////////////////
206 /////////////////////////////////////////////////////////////////
208 ///////////////////////////////////////////////////////////////////
209 #endif // ZYPP_SAT_SOLVITERMIXIN_H