Discourage using SafeBool in favor of explicit operator bool
[platform/upstream/libzypp.git] / zypp / sat / Solvable.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/sat/Solvable.h
10  *
11 */
12 #ifndef ZYPP_SAT_SOLVABLE_H
13 #define ZYPP_SAT_SOLVABLE_H
14
15 #include <iosfwd>
16
17 #include "zypp/sat/detail/PoolMember.h"
18 #include "zypp/sat/SolvAttr.h"
19 #include "zypp/ResTraits.h"
20 #include "zypp/IdString.h"
21 #include "zypp/Edition.h"
22 #include "zypp/Arch.h"
23 #include "zypp/Dep.h"
24 #include "zypp/Capabilities.h"
25 #include "zypp/Capability.h"
26 #include "zypp/Locale.h"
27
28 ///////////////////////////////////////////////////////////////////
29 namespace zypp
30 { /////////////////////////////////////////////////////////////////
31
32   class CheckSum;
33   class OnMediaLocation;
34
35   ///////////////////////////////////////////////////////////////////
36   namespace sat
37   { /////////////////////////////////////////////////////////////////
38
39     ///////////////////////////////////////////////////////////////////
40     //
41     //  CLASS NAME : Solvable
42     //
43     /** A \ref Solvable object within the sat \ref Pool.
44      *
45      * \note Unfortunately libsolv combines the objects kind and
46      * name in a single identifier \c "pattern:kde_multimedia",
47      * \b except for packages and source packes. They are not prefixed
48      * by any kind string. Instead the architecture is abused to store
49      * \c "src" and \c "nosrc" values.
50      *
51      * \ref Solvable will hide this inconsistency by treating source
52      * packages as an own kind of solvable and map their arch to
53      * \ref Arch_noarch.
54      */
55     class Solvable : protected detail::PoolMember
56     {
57       public:
58         typedef sat::detail::SolvableIdType IdType;
59
60       public:
61         /** Default ctor creates \ref noSolvable.*/
62         Solvable()
63         : _id( detail::noSolvableId ) {}
64
65         /** \ref PoolImpl ctor. */
66         explicit Solvable( IdType id_r )
67         : _id( id_r ) {}
68
69       public:
70         /** Represents no \ref Solvable. */
71         static const Solvable noSolvable;
72
73         /** Evaluate \ref Solvable in a boolean context (\c != \c noSolvable). */
74         explicit operator bool() const
75         { return get(); }
76
77         /** Return whether this \ref Solvable belongs to the system repo.
78          * \note This includes the otherwise hidden systemSolvable.
79          */
80         bool isSystem() const;
81
82         /** Whether this is known to be installed on behalf of a user request.
83          * \note This is a hint guessed by evaluating an available install history.
84          * Returns \c false for non-system (uninstalled) solvables, or if no history
85          * is available.
86          */
87         bool onSystemByUser() const;
88
89         /** The \ref Repository this \ref Solvable belongs to. */
90         Repository repository() const;
91
92       public:
93
94         /** \name Attribute lookup.
95          * \see \ref LookupAttr and  \ref ArrayAttr providing a general, more
96          * query like interface for attribute retrieval.
97         */
98         //@{
99         /**
100          * returns the string attribute value for \ref attr
101          * or an empty string if it does not exists.
102          */
103         std::string lookupStrAttribute( const SolvAttr & attr ) const;
104         /** \overload Trying to look up a translated string attribute.
105          *
106          * Returns the translation for \c lang_r.
107          *
108          * Passing an empty \ref Locale will return the string for the
109          * current default locale (\see \ref ZConfig::TextLocale),
110          * \b considering all fallback locales.
111          *
112          * Returns an empty string if no translation is available.
113         */
114         std::string lookupStrAttribute( const SolvAttr & attr, const Locale & lang_r ) const;
115
116         /**
117          * returns the numeric attribute value for \ref attr
118          * or 0 if it does not exists.
119          */
120         unsigned long long lookupNumAttribute( const SolvAttr & attr ) const;
121
122         /**
123          * returns the boolean attribute value for \ref attr
124          * or \c false if it does not exists.
125          */
126         bool lookupBoolAttribute( const SolvAttr & attr ) const;
127
128        /**
129          * returns the id attribute value for \ref attr
130          * or \ref detail::noId if it does not exists.
131          */
132         detail::IdType lookupIdAttribute( const SolvAttr & attr ) const;
133
134        /**
135          * returns the CheckSum attribute value for \ref attr
136          * or an empty CheckSum if ir does not exist.
137          */
138         CheckSum lookupCheckSumAttribute( const SolvAttr & attr ) const;
139
140         /**
141          * returns OnMediaLocation data: This is everything we need to
142          * download e.g. an rpm (path, checksum, downloadsize, etc.).
143          */
144         OnMediaLocation lookupLocation() const;
145
146         //@}
147       public:
148         /** The identifier.
149          * This is the solvables \ref name, \b except for packages and
150          * source packes, prefixed by it's \ref kind.
151          */
152         IdString     ident()    const;
153
154         ResKind      kind()     const;
155         /** Test whether a Solvable is of a certain \ref ResKind.
156          * The test is far cheaper than actually retriveing and
157          * comparing the \ref kind.
158          */
159         bool isKind( const ResKind & kind_r ) const;
160         /** \overload */
161         template<class _Res>
162         bool isKind() const
163         { return isKind( resKind<_Res>() ); }
164         /** \overload Extend the test to a range of \ref ResKind. */
165         template<class _Iterator>
166         bool isKind( _Iterator begin, _Iterator end )
167         { for_( it, begin, end ) if ( isKind( *it ) ) return true; return false; }
168
169         std::string  name()     const;
170         Edition      edition()  const;
171         Arch         arch()     const;
172
173         IdString     vendor()   const;
174
175         /** Whether different versions of this package can be installed at the same time.
176          * Per default \c false. \see also \ref ZConfig::multiversion.
177          */
178         bool         multiversionInstall() const;
179
180         /** String representation <tt>"ident-edition.arch"</tt> or \c "noSolvable"
181          * \code
182          *   product:openSUSE-11.1.x86_64
183          *   autoyast2-2.16.19-0.1.src
184          *   noSolvable
185          * \endcode
186         */
187         std::string asString() const;
188
189         /** Test whether two Solvables have the same content.
190          * Basically the same name, edition, arch, vendor and buildtime.
191          */
192         bool identical( Solvable rhs ) const;
193
194         /** Test for same name-version-release.arch */
195         bool sameNVRA( Solvable rhs ) const
196         { return( ident() == rhs.ident() && edition() == rhs.edition() && arch() == rhs.arch() ); }
197
198      public:
199
200         /** \name Access to the \ref Solvable dependencies.
201          *
202          * \note Prerequires are a subset of requires.
203          */
204         //@{
205         Capabilities operator[]( Dep which_r ) const;
206
207         Capabilities provides()    const;
208         Capabilities requires()    const;
209         Capabilities conflicts()   const;
210         Capabilities obsoletes()   const;
211         Capabilities recommends()  const;
212         Capabilities suggests()    const;
213         Capabilities enhances()    const;
214         Capabilities supplements() const;
215         Capabilities prerequires() const;
216
217         /** Return the namespaced provides <tt>'namespace([value])[ op edition]'</tt> of this Solvable. */
218         CapabilitySet providesNamespace( const std::string & namespace_r ) const;
219
220         /** Return <tt>'value[ op edition]'</tt> for namespaced provides <tt>'namespace(value)[ op edition]'</tt>.
221          * Similar to \ref providesNamespace, but the namespace is stripped from the
222          * dependencies. This is convenient if the namespace denotes packages that
223          * should be looked up. E.g. the \c weakremover namespace used in a products
224          * release package denotes the packages that were dropped from the distribution.
225          * \see \ref Product::droplist
226          */
227         CapabilitySet valuesOfNamespace( const std::string & namespace_r ) const;
228         //@}
229
230       public:
231         /** \name Locale support. */
232         //@{
233         /** Whether this \c Solvable claims to support locales. */
234         bool supportsLocales() const;
235         /** Whether this \c Solvable supports a specific \ref Locale. */
236         bool supportsLocale( const Locale & locale_r ) const;
237         /** Whether this \c Solvable supports at least one of the specified locales. */
238         bool supportsLocale( const LocaleSet & locales_r ) const;
239         /** Whether this \c Solvable supports at least one requested locale.
240          * \see \ref Pool::setRequestedLocales
241         */
242         bool supportsRequestedLocales() const;
243         /** Return the supported locales via locales_r. */
244         void getSupportedLocales( LocaleSet & locales_r ) const;
245         /** \overload */
246         LocaleSet getSupportedLocales() const
247         { LocaleSet ret; getSupportedLocales( ret ); return ret; }
248         //@}
249
250       public:
251         /** Return next Solvable in \ref Pool (or \ref noSolvable). */
252         Solvable nextInPool() const;
253         /** Return next Solvable in \ref Repo (or \ref noSolvable). */
254         Solvable nextInRepo() const;
255
256         /** Helper that splits an identifier into kind and name or vice versa.
257          * \note In case \c name_r is preceded by a well known kind spec, the
258          * \c kind_r argument is ignored, and kind is derived from name.
259          * \see \ref ident
260          */
261         class SplitIdent
262         {
263           public:
264             SplitIdent() {}
265             SplitIdent( IdString ident_r );
266             SplitIdent( const char * ident_r );
267             SplitIdent( const std::string & ident_r );
268             SplitIdent( ResKind kind_r, IdString name_r );
269             SplitIdent( ResKind kind_r, const C_Str & name_r );
270
271             IdString ident() const { return _ident; }
272             ResKind  kind()  const { return _kind; }
273             IdString name()  const { return _name; }
274
275             /** Return an idents explicit kind prefix, or \ref ResKind() if none.
276              * Mainly to detect wheter a given ident string is explicitly prefixed
277              * by a known kind (e.g \c pattern:foo or \c package:foo).
278              */
279             static ResKind explicitKind( IdString ident_r )             { return explicitKind( ident_r.c_str() );  }
280             static ResKind explicitKind( const char * ident_r );
281             static ResKind explicitKind( const std::string & ident_r )  { return explicitKind( ident_r.c_str() );  }
282
283           private:
284             IdString  _ident;
285             ResKind   _kind;
286             IdString  _name;
287         };
288
289       public:
290         /** Expert backdoor. */
291         ::_Solvable * get() const;
292         /** Expert backdoor. */
293         IdType id() const { return _id; }
294
295       private:
296         IdType _id;
297     };
298     ///////////////////////////////////////////////////////////////////
299
300     /** \relates Solvable Stream output */
301     std::ostream & operator<<( std::ostream & str, const Solvable & obj );
302
303     /** \relates Solvable More verbose stream output including dependencies */
304     std::ostream & dumpOn( std::ostream & str, const Solvable & obj );
305
306     /** \relates Solvable */
307     inline bool operator==( const Solvable & lhs, const Solvable & rhs )
308     { return lhs.get() == rhs.get(); }
309
310     /** \relates Solvable */
311     inline bool operator!=( const Solvable & lhs, const Solvable & rhs )
312     { return lhs.get() != rhs.get(); }
313
314     /** \relates Solvable */
315     inline bool operator<( const Solvable & lhs, const Solvable & rhs )
316     { return lhs.get() < rhs.get(); }
317
318     /** \relates Solvable Test for same content. */
319     inline bool identical( Solvable lhs, Solvable rhs )
320     { return lhs.identical( rhs ); }
321
322     /** \relates Solvable Test for same name version release and arch. */
323     inline bool sameNVRA( Solvable lhs, Solvable rhs )
324     { return lhs.sameNVRA( rhs ); }
325
326     ///////////////////////////////////////////////////////////////////
327     namespace detail
328     { /////////////////////////////////////////////////////////////////
329       ///////////////////////////////////////////////////////////////////
330       //
331       //        CLASS NAME : SolvableIterator
332       //
333       /** */
334       class SolvableIterator : public boost::iterator_adaptor<
335           SolvableIterator                   // Derived
336           , ::_Solvable*                     // Base
337           , const Solvable                   // Value
338           , boost::forward_traversal_tag     // CategoryOrTraversal
339           , const Solvable                   // Reference
340           >
341       {
342         public:
343           SolvableIterator()
344           : SolvableIterator::iterator_adaptor_( 0 )
345           {}
346
347           explicit SolvableIterator( const Solvable & val_r )
348           : SolvableIterator::iterator_adaptor_( 0 )
349           { assignVal( val_r ); }
350
351           explicit SolvableIterator( SolvableIdType id_r )
352           : SolvableIterator::iterator_adaptor_( 0 )
353           { assignVal( Solvable( id_r ) ); }
354
355         private:
356           friend class boost::iterator_core_access;
357
358           Solvable dereference() const
359           { return _val; }
360
361           void increment()
362           { assignVal( _val.nextInPool() ); }
363
364         private:
365           void assignVal( const Solvable & val_r )
366           { _val = val_r; base_reference() = _val.get(); }
367
368           Solvable _val;
369       };
370       ///////////////////////////////////////////////////////////////////
371       /////////////////////////////////////////////////////////////////
372     } // namespace detail
373     ///////////////////////////////////////////////////////////////////
374
375     /////////////////////////////////////////////////////////////////
376   } // namespace sat
377   ///////////////////////////////////////////////////////////////////
378
379   /** \relates sat::Solvable Test whether a \ref sat::Solvable is of a certain Kind. */
380   template<class _Res>
381   inline bool isKind( const sat::Solvable & solvable_r )
382   { return solvable_r.isKind( ResTraits<_Res>::kind ); }
383
384   class PoolItem;
385   ///////////////////////////////////////////////////////////////////
386   namespace sat
387   { /////////////////////////////////////////////////////////////////
388     /** To Solvable transform functor.
389      * \relates Solvable
390      * \relates sat::SolvIterMixin
391      */
392     struct asSolvable
393     {
394       typedef Solvable result_type;
395
396       Solvable operator()( Solvable solv_r ) const
397       { return solv_r; }
398
399       Solvable operator()( const PoolItem & pi_r ) const;
400
401       Solvable operator()( const ResObject_constPtr & res_r ) const;
402     };
403     /////////////////////////////////////////////////////////////////
404   } // namespace sat
405   ///////////////////////////////////////////////////////////////////
406
407   /////////////////////////////////////////////////////////////////
408 } // namespace zypp
409 ///////////////////////////////////////////////////////////////////
410
411 ZYPP_DEFINE_ID_HASHABLE( ::zypp::sat::Solvable );
412
413 #endif // ZYPP_SAT_SOLVABLE_H