done LookupAttr, added ArrayAttr container to retrieve list attributes.
[platform/upstream/libzypp.git] / zypp / sat / LookupAttr.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/sat/LookupAttr.h
10  *
11 */
12 #ifndef ZYPP_SAT_LOOKUPATTR_H
13 #define ZYPP_SAT_LOOKUPATTR_H
14
15 extern "C"
16 {
17 struct _Dataiterator;
18 }
19 #include <iosfwd>
20
21 #include "zypp/base/PtrTypes.h"
22 #include "zypp/base/DefaultIntegral.h"
23
24 #include "zypp/sat/Pool.h"
25
26 ///////////////////////////////////////////////////////////////////
27 namespace zypp
28 { /////////////////////////////////////////////////////////////////
29   ///////////////////////////////////////////////////////////////////
30   namespace sat
31   { /////////////////////////////////////////////////////////////////
32
33     ///////////////////////////////////////////////////////////////////
34     //
35     //  CLASS NAME : LookupAttr
36     //
37     /** Lightweight attribute value lookup.
38      *
39      * Search for an attribute in \ref Pool, one \ref Repository
40      * or one \ref Solvable. \ref LookupAttr builds the query,
41      * \ref LookupAttr::iterator iterates over the result.
42      *
43      * Modifying the query will not affect any running
44      * iterator.
45      *
46      * Use \ref SolvAttr::allAttr to search all attributes.
47      *
48      * \code
49      *  // look for all attributes of one solvable
50      *  void ditest( sat::Solvable slv_r )
51      *  {
52      *    sat::LookupAttr q( sat::SolvAttr::allAttr, slv_r );
53      *    MIL << q << ": " << endl;
54      *    for_( it, q.begin(), q.end() )
55      *    {
56      *      MIL << "    " << it.inSolvAttr() << " = " << it.asString() << endl;
57      *    }
58      *  }
59      * \endcode
60      *
61      * \code
62      *  // look for an attribute in the pool.
63      *  sat::LookupAttr q( sat::SolvAttr("susetags:datadir") );
64      *  MIL << q << ": " << endl;
65      *  for_( it, q.begin(), q.end() )
66      *  {
67      *    MIL << "    " << it << endl;
68      *  }
69      * \endcode
70      */
71     class LookupAttr
72     {
73       public:
74         /** Default ctor finds nothing. */
75         LookupAttr()
76         {}
77         /** Lookup \ref SolvAttr in \ref Pool (all repositories). */
78         explicit
79         LookupAttr( SolvAttr attr_r )
80         : _attr( attr_r )
81         {}
82         /** Lookup \ref SolvAttr in one\ref Repository. */
83         explicit
84         LookupAttr( SolvAttr attr_r, Repository repo_r )
85         : _attr( attr_r ), _repo( repo_r )
86         {}
87         /** Lookup \ref SolvAttr in one \ref Solvable. */
88         LookupAttr( SolvAttr attr_r, Solvable solv_r )
89         : _attr( attr_r ), _solv( solv_r )
90         {}
91
92       public:
93         /** \name Search result. */
94         //@{
95         /** Result iterator. */
96         class iterator;
97
98         /** Iterator to the begin of query results. */
99         iterator begin() const;
100
101         /** Iterator behind the end of query results. */
102         iterator end() const;
103
104         /** Whether the query is empty. */
105         bool empty() const;
106
107         /** TransformIterator returning an \ref iterator vaue of type \c _ResultT. */
108         template<class _ResultT, class _AttrT> class transformIterator;
109         //@}
110
111       public:
112         /** \name What to search. */
113         //@{
114
115         /** The \ref SolvAttr to search. */
116         SolvAttr attr() const
117         { return _attr; }
118
119         /** Set the \ref SolvAttr to search. */
120         void setAttr( SolvAttr attr_r )
121         { _attr = attr_r; }
122
123         //@}
124       public:
125         /** \name Where to search. */
126         //@{
127         /** Wheter to search in \ref Pool. */
128         bool pool() const
129         { return ! (_repo || _solv); }
130
131         /** Set search in \ref Pool (all repositories). */
132         void setPool()
133         {
134           _repo = Repository::noRepository;
135           _solv = Solvable::noSolvable;
136         }
137
138         /** Wheter to search in one \ref Repository. */
139         Repository repo() const
140         { return _repo; }
141
142         /** Set search in one \ref Repository. */
143         void setRepo( Repository repo_r )
144         {
145           _repo = repo_r;
146           _solv = Solvable::noSolvable;
147         }
148
149         /** Wheter to search in one \ref Solvable. */
150         Solvable solvable() const
151         { return _solv; }
152
153         /** Set search in one \ref Solvable. */
154         void setSolvable( Solvable solv_r )
155          {
156           _repo = Repository::noRepository;
157           _solv = solv_r;
158         }
159
160         //@}
161       private:
162         SolvAttr   _attr;
163         Repository _repo;
164         Solvable   _solv;
165     };
166     ///////////////////////////////////////////////////////////////////
167
168     /** \relates LookupAttr Stream output. */
169     std::ostream & operator<<( std::ostream & str, const LookupAttr & obj );
170
171     /** \relates LookupAttr Verbose stream output including the query result. */
172     std::ostream & dumpOn( std::ostream & str, const LookupAttr & obj );
173
174     ///////////////////////////////////////////////////////////////////
175     //
176     //  CLASS NAME : LookupAttr::iterator
177     //
178     /** Result iterator.
179      * Extended iterator methods valid only if not @end.
180      * \note Implementation: Keep iterator_adaptor base and _dip in sync!
181      */
182     class LookupAttr::iterator : public boost::iterator_adaptor<
183         iterator                       // Derived
184         , ::_Dataiterator *            // Base
185         , detail::IdType               // Value
186         , boost::forward_traversal_tag // CategoryOrTraversal
187         , detail::IdType               // Reference
188     >
189     {
190       public:
191         /** \name Moving fast forward. */
192         //@{
193         /** On the next call to \ref operator++ advance to the next \ref SolvAttr. */
194         void nextSkipSolvAttr();
195
196         /** On the next call to \ref operator++ advance to the next \ref Solvable. */
197         void nextSkipSolvable();
198
199         /** On the next call to \ref operator++ advance to the next \ref Repository. */
200         void nextSkipRepo();
201
202         /** Immediately advance to the next \ref SolvAttr. */
203         void skipSolvAttr()
204         { nextSkipSolvAttr(); increment(); }
205
206         /** Immediately advance to the next \ref Solvable. */
207         void skipSolvable()
208         { nextSkipSolvable(); increment(); }
209
210         /** Immediately advance to the next \ref Repository. */
211         void skipRepo()
212         { nextSkipRepo(); increment(); }
213         //@}
214
215         /** \name Current position info. */
216         //@{
217         /** The current \ref Repository. */
218         Repository inRepo() const;
219
220         /** The current \ref Solvabele. */
221         Solvable inSolvable() const;
222
223         /** The current \ref SolvAttr. */
224         SolvAttr inSolvAttr() const;
225         //@}
226
227         /** \name Test attribute value type. */
228         //@{
229         /** The current \ref SolvAttr type. */
230         detail::IdType solvAttrType() const;
231
232         /** Whether this is a numeric attribute (incl. boolean). */
233         bool solvAttrNumeric() const;
234
235         /** Whether this is a string attribute. */
236         bool solvAttrString() const;
237
238         /** *Whether this string attribute is available as \ref IdString. */
239         bool solvAttrIdString() const;
240
241         /** Whether this is a CheckSum attribute.*/
242         bool solvAttrCheckSum() const;
243         //@}
244
245         /** \name Retrieving attribute values. */
246         //@{
247         /** Conversion to numeric types. */
248         int asInt() const;
249         /** \overload */
250         unsigned asUnsigned() const;
251         /** \overload */
252         bool asBool() const;
253
254         /** Conversion to string types. */
255         const char * c_str() const;
256         /** \overload
257          * If used with non-string types, this method tries to create
258          * some appropriate string representation.
259         */
260         std::string asString() const;
261
262         /** As \ref IdStr.
263          * This is only done for poolized string types. Large strings like
264          * summary or descriptions are not available via \ref IdStr, only
265          * via \ref c_str and \ref asString.
266          */
267         IdString idStr() const;
268
269         /** As \ref CheckSum. */
270         CheckSum asCheckSum() const;
271
272         /** Templated return type.
273          * Specialized for supported types.
274         */
275         template<class _Tp> _Tp asType() const;
276         //@}
277
278         ///////////////////////////////////////////////////////////////////
279         // internal stuff below
280         ///////////////////////////////////////////////////////////////////
281       public:
282         iterator();
283
284         iterator( const iterator & rhs );
285
286         iterator & operator=( const iterator & rhs );
287
288         ~iterator();
289
290       private:
291         friend class LookupAttr;
292         iterator( scoped_ptr< ::_Dataiterator> & dip_r, bool chain_r );
293
294         ::_Dataiterator * cloneFrom( const ::_Dataiterator * rhs );
295
296       private:
297         friend class boost::iterator_core_access;
298
299         template <class OtherDerived, class OtherIterator, class V, class C, class R, class D>
300         bool equal( const boost::iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> & rhs ) const
301         {
302           return ( bool(base()) == bool(rhs.base()) )
303               && ( ! base() || dip_equal( *base(), *rhs.base() ) );
304         }
305
306         bool dip_equal( const ::_Dataiterator & lhs, const ::_Dataiterator & rhs ) const;
307
308         detail::IdType dereference() const;
309
310         void increment();
311
312       public:
313         /** Expert backdoor. */
314         const ::_Dataiterator * get() const
315         { return _dip.get(); }
316       private:
317         scoped_ptr< ::_Dataiterator> _dip;
318         DefaultIntegral<bool,false>  _chainRepos;
319     };
320     ///////////////////////////////////////////////////////////////////
321
322     /** \relates LookupAttr::iterator Stream output. */
323     std::ostream & operator<<( std::ostream & str, const LookupAttr::iterator & obj );
324
325     template<> inline int          LookupAttr::iterator::asType<int>()          const { return asInt(); }
326     template<> inline unsigned     LookupAttr::iterator::asType<unsigned>()     const { return asUnsigned(); }
327     template<> inline bool         LookupAttr::iterator::asType<bool>()         const { return asBool(); }
328     template<> inline const char * LookupAttr::iterator::asType<const char *>() const { return c_str(); }
329     template<> inline std::string  LookupAttr::iterator::asType<std::string>()  const { return asString(); }
330     template<> inline IdString     LookupAttr::iterator::asType<IdString>()     const { return idStr(); }
331
332     ///////////////////////////////////////////////////////////////////
333     //
334     //  CLASS NAME : LookupAttr::transformIterator
335     //
336     /** TransformIterator returning an \ref iterator value of type \c _ResultT.
337      *
338      * The underlying LookupAttr::iterators value is retrieved \ref asType<_AttrT>
339      * and the returned \ref ResultT is constructed fron that value.
340      *
341      * \code
342      *   class Keywords
343      *   {
344      *     public:
345      *       Keywords( sat::Solvable solv_r )
346      *       : _q( sat::SolvAttr::keywords, solv_r )
347      *       {}
348      *
349      *     public:
350      *       typedef sat::LookupAttr::transformIterator<PackageKeyword,IdString> iterator;
351      *
352      *       iterator begin() const { return iterator( _q.begin() ); }
353      *       iterator end() const   { return iterator( _q.end() ); }
354      *
355      *     private:
356      *       sat::LookupAttr _q;
357      *   };
358      * \endcode
359      *
360      * \see \ref ArrayAttr.
361      */
362     template<class _ResultT, class _AttrT>
363     class LookupAttr::transformIterator : public boost::iterator_adaptor<
364           transformIterator<_ResultT,_AttrT> // Derived
365           , LookupAttr::iterator         // Base
366           , _ResultT                     // Value
367           , boost::forward_traversal_tag // CategoryOrTraversal
368           , _ResultT                     // Reference
369     >
370     {
371       public:
372         transformIterator()
373         {}
374
375         explicit
376         transformIterator( const LookupAttr::iterator & val_r )
377         { this->base_reference() = val_r; }
378
379       public:
380
381         /** \name Moving fast forward. */
382         //@{
383         /** On the next call to \ref operator++ advance to the next \ref SolvAttr. */
384         void nextSkipSolvAttr()
385         { this->base_reference().nextSkipSolvAttr(); }
386
387         /** On the next call to \ref operator++ advance to the next \ref Solvable. */
388         void nextSkipSolvable()
389         { this->base_reference().nextSkipSolvable(); }
390
391         /** On the next call to \ref operator++ advance to the next \ref Repository. */
392         void nextSkipRepo()
393         { this->base_reference().nextSkipRepo(); }
394
395         /** Immediately advance to the next \ref SolvAttr. */
396         void skipSolvAttr()
397         { this->base_reference().skipSolvAttr(); }
398
399         /** Immediately advance to the next \ref Solvable. */
400         void skipSolvable()
401         { this->base_reference().skipSolvable(); }
402
403         /** Immediately advance to the next \ref Repository. */
404         void skipRepo()
405         { this->base_reference().skipRepo(); }
406         //@}
407
408         /** \name Current position info. */
409         //@{
410         /** The current \ref Repository. */
411         Repository inRepo() const
412         { return this->base_reference().inRepo(); }
413
414         /** The current \ref Solvabele. */
415         Solvable inSolvable() const
416         { return this->base_reference().inSolvable(); }
417
418         /** The current \ref SolvAttr. */
419         SolvAttr inSolvAttr() const
420         { return this->base_reference().inSolvAttr(); }
421         //@}
422
423       private:
424         friend class boost::iterator_core_access;
425
426         _ResultT dereference() const
427         {
428           const LookupAttr::iterator lit( this->base_reference() );
429           return _ResultT( lit.asType<_AttrT>() );
430         }
431     };
432     ///////////////////////////////////////////////////////////////////
433
434     template<class _ResultT, class _AttrT>
435     class ArrayAttr;
436
437     template<class _ResultT, class _AttrT>
438     std::ostream & operator<<( std::ostream & str, const ArrayAttr<_ResultT,_AttrT> & obj );
439
440     ///////////////////////////////////////////////////////////////////
441     //
442     //  CLASS NAME : ArrayAttr
443     //
444     /** \ref LookupAttr::transformIterator based container to retrieve list attributes.
445      *
446      * \code
447      *  typedef ArrayAttr<PackageKeyword,IdString> Keywords;
448      *  Keywords k( sat::SolvAttr::keywords );
449      *  dumpRange( MIL << "All Keywords: ", k.begin(), k.end() ) << endl;
450      * \endcode
451      *
452      * \todo Maybe add some way to unify the result.
453      */
454     template<class _ResultT, class _AttrT>
455     class ArrayAttr
456     {
457       friend std::ostream & operator<< <_ResultT,_AttrT>( std::ostream & str, const ArrayAttr<_ResultT,_AttrT> & obj );
458
459       public:
460         ArrayAttr()
461         {}
462
463         ArrayAttr( SolvAttr attr_r )
464         : _q( attr_r )
465         {}
466
467         ArrayAttr( SolvAttr attr_r, Repository repo_r )
468         : _q( attr_r, repo_r )
469         {}
470
471         ArrayAttr( SolvAttr attr_r, Solvable solv_r )
472         : _q( attr_r, solv_r )
473         {}
474
475       public:
476         typedef sat::LookupAttr::transformIterator<_ResultT,_AttrT> iterator;
477
478         iterator begin() const
479         { return iterator( _q.begin() ); }
480
481         iterator end() const
482         { return iterator( _q.end() ); }
483
484         bool empty() const
485         { return _q.empty(); }
486
487       private:
488         sat::LookupAttr _q;
489     };
490     ///////////////////////////////////////////////////////////////////
491
492     /** \relates LookupAttr::iterator Stream output. */
493     template<class _ResultT, class _AttrT>
494     inline std::ostream & operator<<( std::ostream & str, const ArrayAttr<_ResultT,_AttrT> & obj )
495     { return dumpOn( str, obj._q); }
496
497     /////////////////////////////////////////////////////////////////
498   } // namespace sat
499   ///////////////////////////////////////////////////////////////////
500   /////////////////////////////////////////////////////////////////
501 } // namespace zypp
502 ///////////////////////////////////////////////////////////////////
503 #endif // ZYPP_SAT_LOOKUPATTR_H