Imported Upstream version 16.3.2
[platform/upstream/libzypp.git] / zypp / PoolQueryResult.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/PoolQueryResult.h
10  *
11 */
12 #ifndef ZYPP_POOLQUERYRESULT_H
13 #define ZYPP_POOLQUERYRESULT_H
14
15 #include <iosfwd>
16
17 #include "zypp/base/Hash.h"
18 #include "zypp/base/Exception.h"
19 #include "zypp/sat/SolvIterMixin.h"
20
21 #include "zypp/PoolItem.h"
22 #include "zypp/PoolQuery.h"
23
24 ///////////////////////////////////////////////////////////////////
25 namespace zypp
26 { /////////////////////////////////////////////////////////////////
27
28   ///////////////////////////////////////////////////////////////////
29   //
30   //    CLASS NAME : PoolQueryResult
31   //
32   /** Helper class to collect (not only) \ref PoolQuery results.
33    *
34    * \note Unfortunately \ref PoolQuery::begin might throw. Exceptions
35    * are caught and the query is treated as empty.
36    *
37    * \ref PoolQueryResult maintains a set of \ref sat::Solvable. You can
38    * add/remove solvables to/from the set defined by:
39    *
40    * \li a single \ref sat::Solvable
41    * \li a single \ref PoolItem
42    * \li a \ref PoolQuery
43    * \li an other \ref PoolQueryResult
44    * \li any iterator pair with \c value_type \ref sat::Solvable
45    *     or \ref PoolItem or \ref PoolQuery or any type that fits
46    *     \c operator+=.
47    *
48    * The class is a \ref sat::SolvIterMixin, so you can iterate the result
49    * not just as \ref sat::Solvable, but also as \ref PoolItem or
50    * \ref ui::Selectable.
51    *
52    * \code
53    *   // Constructed from PoolItem iterator pair
54    *   PoolQueryResult result( pool.byKindBegin<Package>(), pool.byKindEnd<Package>() );
55    *   MIL << result.size() << endl;
56    *
57    *   {
58    *     // Removing a PoolQuery result
59    *     PoolQuery q;
60    *     q.addAttribute( sat::SolvAttr::name, "[a-zA-Z]*" );
61    *     q.setMatchGlob();
62    *     result -= q;
63    *     MIL << result.size() << endl;
64    *   }
65    *   MIL << result << endl;
66    *
67    *   // Removing a range of sat::Solvables
68    *   sat::WhatProvides poviders( Capability("3ddiag") );
69    *   result -= PoolQueryResult( poviders.begin(), poviders.end() );
70    *
71    *   // packages not starting with a letter, except 3ddiag
72    *   MIL << result << endl;
73    * \endcode
74    */
75   class PoolQueryResult : public sat::SolvIterMixin<PoolQueryResult,std::unordered_set<sat::Solvable>::const_iterator>
76   {
77     public:
78       typedef std::unordered_set<sat::Solvable> ResultSet;
79       typedef ResultSet::size_type                      size_type;
80       typedef ResultSet::const_iterator                 const_iterator;
81
82     public:
83       /** Default ctor (empty result) */
84       PoolQueryResult()
85       {}
86
87       /** Ctor adding one \ref sat::Solvable. */
88       explicit PoolQueryResult( sat::Solvable result_r )
89       { operator+=( result_r ); }
90
91       /** Ctor adding one \ref PoolItem. */
92       explicit PoolQueryResult( const PoolItem & result_r )
93       { operator+=( result_r ); }
94
95       /** Ctor adding one \ref PoolQuery result. */
96       explicit PoolQueryResult( const PoolQuery & query_r )
97       { operator+=( query_r ); }
98
99       /** Ctor adding a range of items for which \ref operator+= is defined. */
100       template<class TQueryResultIter>
101       PoolQueryResult( TQueryResultIter begin_r, TQueryResultIter end_r )
102       {
103         for_( it, begin_r, end_r )
104         {
105           operator+=( *it );
106         }
107       }
108
109     public:
110       /** Whether the result is empty. */
111       bool empty() const
112       { return _result.empty(); }
113       /** The number of \ref sat::Solvables. */
114       size_type size() const
115       { return _result.size(); }
116       /** */
117       const_iterator begin() const
118       { return _result.begin(); }
119       /** */
120       const_iterator end() const
121       { return _result.end(); }
122
123       /** Test whether some item is in the result set. */
124       bool contains(sat::Solvable result_r ) const
125       { return( _result.find( result_r ) != _result.end() ); }
126       /** \overload */
127       bool contains( const PoolItem & result_r ) const
128       { return contains( result_r.satSolvable() ); }
129
130     public:
131       /** Clear the result. */
132       void clear()
133       { _result.clear(); }
134
135       /** Add items to the result. */
136       PoolQueryResult & operator+=( const PoolQueryResult & query_r )
137       {
138         if ( ! query_r.empty() )
139           _result.insert( query_r.begin(), query_r.end() );
140         return *this;
141       }
142       /** \overload */
143       PoolQueryResult & operator+=( const PoolQuery & query_r )
144       {
145         try
146         {
147           for_( it, query_r.begin(), query_r.end() )
148             _result.insert( *it );
149         }
150         catch ( const Exception & )
151         {}
152         return *this;
153       }
154       /** \overload */
155       PoolQueryResult & operator+=( sat::Solvable result_r )
156       {
157         _result.insert( result_r );
158         return *this;
159       }
160       /** \overload */
161       PoolQueryResult & operator+=( const PoolItem & result_r )
162       {
163         _result.insert( result_r.satSolvable() );
164         return *this;
165       }
166
167       /** Remove Items from the result. */
168       PoolQueryResult & operator-=( const PoolQueryResult & query_r )
169       {
170         if ( &query_r == this ) // catch self removal!
171           clear();
172         else
173           for_( it, query_r.begin(), query_r.end() )
174             _result.erase( *it );
175         return *this;
176       }
177       /** \overload */
178       PoolQueryResult & operator-=( const PoolQuery & query_r )
179       {
180         try
181         {
182           for_( it, query_r.begin(), query_r.end() )
183             _result.erase( *it );
184         }
185         catch ( const Exception & )
186         {}
187         return *this;
188       }
189       /** \overload */
190       PoolQueryResult & operator-=( sat::Solvable result_r )
191       {
192         _result.erase( result_r );
193         return *this;
194       }
195       /** \overload */
196       PoolQueryResult & operator-=( const PoolItem & result_r )
197       {
198         _result.erase( result_r.satSolvable() );
199         return *this;
200       }
201
202     public:
203       /** Combine results. */
204       PoolQueryResult operator+( const PoolQueryResult & query_r ) const
205       { return PoolQueryResult(*this) += query_r; }
206       /** \overload */
207       PoolQueryResult operator+( const PoolQuery & query_r ) const
208       { return PoolQueryResult(*this) += query_r; }
209       /** \overload */
210       PoolQueryResult operator+( sat::Solvable result_r ) const
211       { return PoolQueryResult(*this) += result_r; }
212
213       /** Intersect results. */
214       PoolQueryResult operator-( const PoolQueryResult & query_r ) const
215       { return PoolQueryResult(*this) -= query_r; }
216       /** \overload */
217       PoolQueryResult operator-( const PoolQuery & query_r ) const
218       { return PoolQueryResult(*this) -= query_r; }
219       /** \overload */
220       PoolQueryResult operator-( sat::Solvable result_r ) const
221       { return PoolQueryResult(*this) -= result_r; }
222
223     private:
224       ResultSet _result;
225   };
226   ///////////////////////////////////////////////////////////////////
227
228   /** \relates PoolQueryResult Stream output */
229   std::ostream & operator<<( std::ostream & str, const PoolQueryResult & obj );
230
231   /////////////////////////////////////////////////////////////////
232 } // namespace zypp
233 ///////////////////////////////////////////////////////////////////
234 #endif // ZYPP_POOLQUERYRESULT_H