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