- Extend sat::WhatProvides to allow to query for possible providers
[platform/upstream/libzypp.git] / zypp / sat / WhatProvides.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/sat/.h
10  *
11 */
12 #ifndef ZYPP_SAT_WHATPROVIDES_H
13 #define ZYPP_SAT_WHATPROVIDES_H
14
15 #include <iosfwd>
16 #include <vector>
17
18 #include "zypp/base/PtrTypes.h"
19 #include "zypp/sat/detail/PoolMember.h"
20 #include "zypp/sat/Solvable.h"
21
22 ///////////////////////////////////////////////////////////////////
23 namespace zypp
24 { /////////////////////////////////////////////////////////////////
25   ///////////////////////////////////////////////////////////////////
26   namespace sat
27   { /////////////////////////////////////////////////////////////////
28
29     ///////////////////////////////////////////////////////////////////
30     //
31     //  CLASS NAME : WhatProvides
32     //
33     /** Container of \ref Solvable providing a \ref Capability (read only).
34      *
35      * \code
36      * Capability cap("amarok < 1.13");
37      *
38      * WhatProvides q( cap );
39      * Solvable firstMatch;
40      *
41      * if ( ! q.empty() )
42      * {
43      *   cout << "Found " << q.size() << " matches for " << cap << ":" << endl;
44      *   firstMatch = *q.begin();
45      *
46      *   for_( it, q.begin(), q.end() )
47      *     cout << *it << endl;
48      * }
49      *
50      * if ( firstMatch )
51      * {
52      *   WhatProvides req( firstMatch.requires() );
53      *   if ( ! req.empty() )
54      *   {
55      *      cout << "Found " << req.size() << " items providing requirements of " << firstMatch << ":" << endl;
56      *   }
57      * }
58      * \endcode
59      *
60      * \note Note that there are capabilities which are not provided by any \ref Solvable,
61      * but are system properties. For example:
62      * \code
63      *   rpmlib(PayloadIsBzip2) <= 3.0.5-1
64      * \endcode
65      * In that case a \ref Solvable::noSolvable is returned, which has \c isSystem set \c true, although
66      * there should never be a \ref Solvable::noSolvable returned with \c isSystem set \c false. If so,
67      * please file a bugreport.
68      * \code
69      * WhatProvides q( Capability("rpmlib(PayloadIsBzip2) <= 3.0.5-1") );
70      * for_( it, q.begin(), q.end() )
71      * {
72      *   if ( *it )
73      *     cout << "Capability is provided by package " << *it << endl;
74      *   else if ( it->isSystem() )
75      *     cout << "Capability is a system property" << endl;
76      *   else
77      *     ; // never reaching this \c else
78      * }
79      * \endcode
80      */
81     class WhatProvides : protected detail::PoolMember
82     {
83       public:
84         typedef Solvable  value_type;
85         typedef unsigned  size_type;
86
87       public:
88         /** Default ctor */
89         WhatProvides()
90         : _begin( 0 )
91         {}
92
93         /** Ctor from \ref Capability. */
94         explicit
95         WhatProvides( Capability cap_r );
96
97         /** Ctor collecting all providers of capabilities in \c caps_r. */
98         explicit
99         WhatProvides( Capabilities caps_r );
100
101         /** Ctor collecting all providers of capabilities in \c caps_r. */
102         explicit
103         WhatProvides( const CapabilitySet & caps_r );
104
105      public:
106         /** Whether the container is empty. */
107         bool empty() const
108         { return ! ( _begin && *_begin ); }
109
110         /** Number of solvables inside. */
111         size_type size() const;
112
113       public:
114         class const_iterator;
115
116         /** Iterator pointing to the first \ref Solvable. */
117         const_iterator begin() const;
118
119         /** Iterator pointing behind the last \ref Solvable. */
120         const_iterator end() const;
121
122       private:
123         const sat::detail::IdType * _begin;
124         shared_ptr<void> _private;
125     };
126     ///////////////////////////////////////////////////////////////////
127
128     /** \relates WhatProvides Stream output */
129     std::ostream & operator<<( std::ostream & str, const WhatProvides & obj );
130
131     ///////////////////////////////////////////////////////////////////
132     //
133     //  CLASS NAME : WhatProvides::const_iterator
134     //
135     /** \ref WhatProvides iterator.
136      */
137     class WhatProvides::const_iterator : public boost::iterator_adaptor<
138           const_iterator               // Derived
139         , const detail::IdType *       // Base
140         , const Solvable               // Value
141         , boost::forward_traversal_tag // CategoryOrTraversal
142         , const Solvable               // Reference
143         >
144     {
145       public:
146         const_iterator()
147         : const_iterator::iterator_adaptor_( 0 )
148         {}
149
150         explicit const_iterator( const sat::detail::IdType * _idx )
151         : const_iterator::iterator_adaptor_( _idx )
152         {}
153
154       private:
155         friend class boost::iterator_core_access;
156
157         reference dereference() const
158         { return ( base() ) ? Solvable( *base() ) : Solvable::noSolvable; }
159
160         template <class OtherDerived, class OtherIterator, class V, class C, class R, class D>
161         bool equal( const boost::iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> & rhs ) const
162         { // NULL pointer is eqal pointer to Id 0
163           return ( base() == rhs.base() // includes both NULL...
164               || ( !rhs.base() && !*base()     )
165               || ( !base()     && !*rhs.base() ) );
166         }
167
168         void increment()
169         { ++base_reference(); }
170     };
171     ///////////////////////////////////////////////////////////////////
172
173     inline WhatProvides::const_iterator WhatProvides::begin() const
174     { return const_iterator( _begin ); }
175
176     inline WhatProvides::const_iterator WhatProvides::end() const
177     { return const_iterator( 0 ); }
178
179     /////////////////////////////////////////////////////////////////
180   } // namespace sat
181   ///////////////////////////////////////////////////////////////////
182   /////////////////////////////////////////////////////////////////
183 } // namespace zypp
184 ///////////////////////////////////////////////////////////////////
185 #endif // ZYPP_SAT_WHATPROVIDES_H