Fix Werrors with GCC-14.1.0
[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         class 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       friend std::ostream & operator<<( std::ostream & str, const WhatProvidesIterator & obj );
155       public:
156         WhatProvidesIterator()
157         : iterator_adaptor_( 0 ), _baseRef( 0 ), _offset( 0 )
158         {}
159
160         /** Ctor with pointer to 1st elemment of an array.
161          * Use otherwise unused base as pointer for _baseRef.
162          */
163         explicit WhatProvidesIterator( const detail::IdType *const base_r, unsigned offset_r = 0 )
164         : iterator_adaptor_( base_r ), _baseRef( base_r ? &base_reference() : 0 ), _offset( offset_r )
165         {}
166
167         /** Ctor with pointer to pointer to 1st elemment of an array.
168          * Required for arrays that might be relocated while iterating.
169          */
170         explicit WhatProvidesIterator( const detail::IdType *const* baseRef_r, unsigned offset_r )
171         : iterator_adaptor_( 0 ), _baseRef( baseRef_r ), _offset( offset_r )
172         {}
173
174         /** Copy-ctor required to keep _baseRef adjusted. */
175         WhatProvidesIterator( const WhatProvidesIterator & rhs )
176         : iterator_adaptor_( rhs.base_reference() )
177         , _baseRef( base_reference() ? &base_reference() : rhs._baseRef )
178         , _offset( rhs._offset )
179         {}
180
181         /** Assignment operator required to keep _baseRef adjusted. */
182         WhatProvidesIterator & operator=( const WhatProvidesIterator & rhs )
183         {
184           if ( this != &rhs ) // no self assign
185           {
186             base_reference() = rhs.base_reference();
187             _baseRef = ( base_reference() ? &base_reference() : rhs._baseRef );
188             _offset = rhs._offset;
189           }
190           return *this;
191         }
192
193       private:
194         friend class boost::iterator_core_access;
195
196         reference dereference() const
197         { return Solvable( getId() ); }
198 #if 0
199         template <class OtherDerived, class OtherIterator, class V, class C, class R, class D>
200         bool equal( const boost::iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> & rhs ) const
201 #endif
202         bool equal( const WhatProvidesIterator & rhs ) const
203         {
204           if ( ! ( getId() || rhs.getId() ) )
205             return true; // both @end
206           if ( _offset != rhs._offset )
207             return false;
208           if ( base_reference() )
209             return( base_reference() == rhs.base_reference() );
210           return( _baseRef == rhs._baseRef );
211         }
212
213         void increment()
214         { ++_offset; }
215
216         detail::IdType getId() const
217         { return _baseRef ? (*_baseRef)[_offset] : detail::noId; }
218
219       private:
220         const detail::IdType *const* _baseRef;
221         unsigned                     _offset;
222     };
223     ///////////////////////////////////////////////////////////////////
224     }
225
226     inline WhatProvides::const_iterator WhatProvides::end() const
227     { return const_iterator(); }
228
229     /////////////////////////////////////////////////////////////////
230   } // namespace sat
231   ///////////////////////////////////////////////////////////////////
232   /////////////////////////////////////////////////////////////////
233 } // namespace zypp
234 ///////////////////////////////////////////////////////////////////
235 #endif // ZYPP_SAT_WHATPROVIDES_H