]> git.saurik.com Git - apt.git/blob - apt-pkg/cacheset.h
pkgCacheGenerator::StoreString: Move the string into the map
[apt.git] / apt-pkg / cacheset.h
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 /** \file cacheset.h
4 Wrappers around std::set to have set::iterators which behave
5 similar to the Iterators of the cache structures.
6
7 Provides also a few helper methods which work with these sets */
8 /*}}}*/
9 #ifndef APT_CACHESET_H
10 #define APT_CACHESET_H
11 // Include Files /*{{{*/
12 #include <fstream>
13 #include <map>
14 #include <set>
15 #if __cplusplus >= 201103L
16 #include <unordered_set>
17 #include <forward_list>
18 #include <initializer_list>
19 #endif
20 #include <list>
21 #include <deque>
22 #include <vector>
23 #include <string>
24 #include <iterator>
25 #include <algorithm>
26
27 #include <stddef.h>
28
29 #include <apt-pkg/error.h>
30 #include <apt-pkg/pkgcache.h>
31 #include <apt-pkg/cacheiterators.h>
32 #include <apt-pkg/macros.h>
33
34 #ifndef APT_8_CLEANER_HEADERS
35 #include <apt-pkg/cachefile.h>
36 #endif
37 #ifndef APT_10_CLEANER_HEADERS
38 #include <iostream>
39 #endif
40 /*}}}*/
41
42 class pkgCacheFile;
43
44 namespace APT {
45 class PackageContainerInterface;
46 class VersionContainerInterface;
47
48 class CacheSetHelper { /*{{{*/
49 /** \class APT::CacheSetHelper
50 Simple base class with a lot of virtual methods which can be overridden
51 to alter the behavior or the output of the CacheSets.
52
53 This helper is passed around by the static methods in the CacheSets and
54 used every time they hit an error condition or something could be
55 printed out.
56 */
57 public: /*{{{*/
58 CacheSetHelper(bool const ShowError = true,
59 GlobalError::MsgType ErrorType = GlobalError::ERROR);
60 virtual ~CacheSetHelper();
61
62 enum PkgSelector { UNKNOWN, REGEX, TASK, FNMATCH, PACKAGENAME, STRING };
63
64 virtual bool PackageFrom(enum PkgSelector const select, PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &pattern);
65
66 virtual bool PackageFromCommandLine(PackageContainerInterface * const pci, pkgCacheFile &Cache, const char **cmdline);
67
68 struct PkgModifier {
69 enum Position { NONE, PREFIX, POSTFIX };
70 unsigned short ID;
71 const char * const Alias;
72 Position Pos;
73 PkgModifier (unsigned short const &id, const char * const alias, Position const &pos) : ID(id), Alias(alias), Pos(pos) {}
74 };
75 virtual bool PackageFromModifierCommandLine(unsigned short &modID, PackageContainerInterface * const pci,
76 pkgCacheFile &Cache, const char * cmdline,
77 std::list<PkgModifier> const &mods);
78
79 APT_DEPRECATED_MSG("use .PackageFrom(PACKAGENAME, …) instead") pkgCache::PkgIterator PackageFromName(pkgCacheFile &Cache, std::string const &pattern);
80
81 /** \brief be notified about the package being selected via pattern
82 *
83 * Main use is probably to show a message to the user what happened
84 *
85 * \param pkg is the package which was selected
86 * \param select is the selection method which choose the package
87 * \param pattern is the string used by the selection method to pick the package
88 */
89 virtual void showPackageSelection(pkgCache::PkgIterator const &pkg, PkgSelector const select, std::string const &pattern);
90 // use the method above instead, react only on the type you need and let the base handle the rest if need be
91 // this allows us to add new selection methods without breaking the ABI constantly with new virtual methods
92 APT_DEPRECATED_MSG("override .showPackageSelection and select with switch") virtual void showTaskSelection(pkgCache::PkgIterator const &pkg, std::string const &pattern);
93 APT_DEPRECATED_MSG("override .showPackageSelection and select with switch") virtual void showRegExSelection(pkgCache::PkgIterator const &pkg, std::string const &pattern);
94 APT_DEPRECATED_MSG("override .showPackageSelection and select with switch") virtual void showFnmatchSelection(pkgCache::PkgIterator const &pkg, std::string const &pattern);
95
96 /** \brief be notified if a package can't be found via pattern
97 *
98 * Can be used to show a message as well as to try something else to make it match
99 *
100 * \param select is the method tried for selection
101 * \param pci is the container the package should be inserted in
102 * \param Cache is the package universe available
103 * \param pattern is the string not matching anything
104 */
105 virtual void canNotFindPackage(enum PkgSelector const select, PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &pattern);
106 // same as above for showPackageSelection
107 APT_DEPRECATED_MSG("override .canNotFindPackage and select with switch") virtual void canNotFindTask(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern);
108 APT_DEPRECATED_MSG("override .canNotFindPackage and select with switch") virtual void canNotFindRegEx(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern);
109 APT_DEPRECATED_MSG("override .canNotFindPackage and select with switch") virtual void canNotFindFnmatch(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern);
110 APT_DEPRECATED_MSG("override .canNotFindPackage and select with switch") virtual void canNotFindPackage(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &str);
111
112 /** \brief specifies which version(s) we want to refer to */
113 enum VerSelector {
114 /** by release string */
115 RELEASE,
116 /** by version number string */
117 VERSIONNUMBER,
118 /** All versions */
119 ALL,
120 /** Candidate and installed version */
121 CANDANDINST,
122 /** Candidate version */
123 CANDIDATE,
124 /** Installed version */
125 INSTALLED,
126 /** Candidate or if non installed version */
127 CANDINST,
128 /** Installed or if non candidate version */
129 INSTCAND,
130 /** Newest version */
131 NEWEST
132 };
133
134 /** \brief be notified about the version being selected via pattern
135 *
136 * Main use is probably to show a message to the user what happened
137 * Note that at the moment this method is only called for RELEASE
138 * and VERSION selections, not for the others.
139 *
140 * \param Pkg is the package which was selected for
141 * \param Ver is the version selected
142 * \param select is the selection method which choose the version
143 * \param pattern is the string used by the selection method to pick the version
144 */
145 virtual void showVersionSelection(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const &Ver,
146 enum VerSelector const select, std::string const &pattern);
147 APT_DEPRECATED_MSG("use .showVersionSelection instead, similar to .showPackageSelection") virtual void showSelectedVersion(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const Ver,
148 std::string const &ver, bool const verIsRel);
149
150 /** \brief be notified if a version can't be found for a package
151 *
152 * Main use is probably to show a message to the user what happened
153 *
154 * \param select is the method tried for selection
155 * \param vci is the container the version should be inserted in
156 * \param Cache is the package universe available
157 * \param Pkg is the package we wanted a version from
158 */
159 virtual void canNotFindVersion(enum VerSelector const select, VersionContainerInterface * const vci, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg);
160 APT_DEPRECATED_MSG("override .canNotFindVersion and select via switch") virtual void canNotFindAllVer(VersionContainerInterface * const vci, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg);
161 APT_DEPRECATED_MSG("override .canNotFindVersion and select via switch") virtual void canNotFindInstCandVer(VersionContainerInterface * const vci, pkgCacheFile &Cache,
162 pkgCache::PkgIterator const &Pkg);
163 APT_DEPRECATED_MSG("override .canNotFindVersion and select via switch") virtual void canNotFindCandInstVer(VersionContainerInterface * const vci,
164 pkgCacheFile &Cache,
165 pkgCache::PkgIterator const &Pkg);
166
167 // the difference between canNotFind and canNotGet is that the later is more low-level
168 // and called from other places: In this case looking into the code is the only real answer…
169 virtual pkgCache::VerIterator canNotGetVersion(enum VerSelector const select, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg);
170 APT_DEPRECATED_MSG("override .canNotGetVersion and select via switch") virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache,
171 pkgCache::PkgIterator const &Pkg);
172 APT_DEPRECATED_MSG("override .canNotGetVersion and select via switch") virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache,
173 pkgCache::PkgIterator const &Pkg);
174 APT_DEPRECATED_MSG("override .canNotGetVersion and select via switch") virtual pkgCache::VerIterator canNotFindInstalledVer(pkgCacheFile &Cache,
175 pkgCache::PkgIterator const &Pkg);
176
177 virtual pkgCache::PkgIterator canNotFindPkgName(pkgCacheFile &Cache, std::string const &str);
178
179 bool showErrors() const { return ShowError; }
180 bool showErrors(bool const newValue) { if (ShowError == newValue) return ShowError; else return ((ShowError = newValue) == false); }
181 GlobalError::MsgType errorType() const { return ErrorType; }
182 GlobalError::MsgType errorType(GlobalError::MsgType const &newValue)
183 {
184 if (ErrorType == newValue) return ErrorType;
185 else {
186 GlobalError::MsgType const &oldValue = ErrorType;
187 ErrorType = newValue;
188 return oldValue;
189 }
190 }
191
192 /*}}}*/
193 protected:
194 bool ShowError;
195 GlobalError::MsgType ErrorType;
196
197 pkgCache::VerIterator canNotGetInstCandVer(pkgCacheFile &Cache,
198 pkgCache::PkgIterator const &Pkg);
199 pkgCache::VerIterator canNotGetCandInstVer(pkgCacheFile &Cache,
200 pkgCache::PkgIterator const &Pkg);
201
202 bool PackageFromTask(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern);
203 bool PackageFromRegEx(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern);
204 bool PackageFromFnmatch(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern);
205 bool PackageFromPackageName(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern);
206 bool PackageFromString(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &pattern);
207 private:
208 void * const d;
209 }; /*}}}*/
210 // Iterator templates for our Containers /*{{{*/
211 template<typename Interface, typename Master, typename iterator_type, typename container_iterator, typename container_value> class Container_iterator_base :
212 public std::iterator<typename std::iterator_traits<container_iterator>::iterator_category, container_value>,
213 public Interface::template iterator_base<iterator_type>
214 {
215 protected:
216 container_iterator _iter;
217 public:
218 explicit Container_iterator_base(container_iterator i) : _iter(i) {}
219 inline container_value operator*(void) const { return static_cast<iterator_type const*>(this)->getType(); };
220 operator container_iterator(void) const { return _iter; }
221 inline iterator_type& operator++() { ++_iter; return static_cast<iterator_type&>(*this); }
222 inline iterator_type operator++(int) { iterator_type tmp(*this); operator++(); return tmp; }
223 inline iterator_type operator+(typename container_iterator::difference_type const &n) { return iterator_type(_iter + n); }
224 inline iterator_type operator+=(typename container_iterator::difference_type const &n) { _iter += n; return static_cast<iterator_type&>(*this); }
225 inline iterator_type& operator--() { --_iter;; return static_cast<iterator_type&>(*this); }
226 inline iterator_type operator--(int) { iterator_type tmp(*this); operator--(); return tmp; }
227 inline iterator_type operator-(typename container_iterator::difference_type const &n) { return iterator_type(_iter - n); }
228 inline typename container_iterator::difference_type operator-(iterator_type const &b) { return (_iter - b._iter); }
229 inline iterator_type operator-=(typename container_iterator::difference_type const &n) { _iter -= n; return static_cast<iterator_type&>(*this); }
230 inline bool operator!=(iterator_type const &i) const { return _iter != i._iter; }
231 inline bool operator==(iterator_type const &i) const { return _iter == i._iter; }
232 inline bool operator<(iterator_type const &i) const { return _iter < i._iter; }
233 inline bool operator>(iterator_type const &i) const { return _iter > i._iter; }
234 inline bool operator<=(iterator_type const &i) const { return _iter <= i._iter; }
235 inline bool operator>=(iterator_type const &i) const { return _iter >= i._iter; }
236 inline typename container_iterator::reference operator[](typename container_iterator::difference_type const &n) const { return _iter[n]; }
237
238 friend std::ostream& operator<<(std::ostream& out, iterator_type i) { return operator<<(out, *i); }
239 friend Master;
240 };
241 template<class Interface, class Container, class Master> class Container_const_iterator :
242 public Container_iterator_base<Interface, Master, Container_const_iterator<Interface, Container, Master>, typename Container::const_iterator, typename Container::value_type>
243 {
244 typedef Container_const_iterator<Interface, Container, Master> iterator_type;
245 typedef typename Container::const_iterator container_iterator;
246 public:
247 explicit Container_const_iterator(container_iterator i) :
248 Container_iterator_base<Interface, Master, iterator_type, container_iterator, typename Container::value_type>(i) {}
249
250 inline typename Container::value_type getType(void) const { return *this->_iter; }
251 };
252 template<class Interface, class Container, class Master> class Container_iterator :
253 public Container_iterator_base<Interface, Master, Container_iterator<Interface, Container, Master>, typename Container::iterator, typename Container::value_type>
254 {
255 typedef Container_iterator<Interface, Container, Master> iterator_type;
256 typedef typename Container::iterator container_iterator;
257 public:
258 explicit Container_iterator(container_iterator i) :
259 Container_iterator_base<Interface, Master, iterator_type, container_iterator, typename Container::value_type>(i) {}
260
261 operator typename Master::const_iterator() { return typename Master::const_iterator(this->_iter); }
262 inline iterator_type& operator=(iterator_type const &i) { this->_iter = i._iter; return static_cast<iterator_type&>(*this); }
263 inline iterator_type& operator=(container_iterator const &i) { this->_iter = i; return static_cast<iterator_type&>(*this); }
264 inline typename Container::iterator::reference operator*(void) const { return *this->_iter; }
265
266 inline typename Container::value_type getType(void) const { return *this->_iter; }
267 };
268 template<class Interface, class Container, class Master> class Container_const_reverse_iterator :
269 public Container_iterator_base<Interface, Master, Container_const_reverse_iterator<Interface, Container, Master>, typename Container::const_reverse_iterator, typename Container::value_type>
270 {
271 typedef Container_const_reverse_iterator<Interface, Container, Master> iterator_type;
272 typedef typename Container::const_reverse_iterator container_iterator;
273 public:
274 explicit Container_const_reverse_iterator(container_iterator i) :
275 Container_iterator_base<Interface, Master, iterator_type, container_iterator, typename Container::value_type>(i) {}
276
277 inline typename Container::value_type getType(void) const { return *this->_iter; }
278 };
279 template<class Interface, class Container, class Master> class Container_reverse_iterator :
280 public Container_iterator_base<Interface, Master, Container_reverse_iterator<Interface, Container, Master>, typename Container::reverse_iterator, typename Container::value_type>
281 {
282 typedef Container_reverse_iterator<Interface, Container, Master> iterator_type;
283 typedef typename Container::reverse_iterator container_iterator;
284 public:
285 explicit Container_reverse_iterator(container_iterator i) :
286 Container_iterator_base<Interface, Master, iterator_type, container_iterator, typename Container::value_type>(i) {}
287
288 operator typename Master::const_iterator() { return typename Master::const_iterator(this->_iter); }
289 inline iterator_type& operator=(iterator_type const &i) { this->_iter = i._iter; return static_cast<iterator_type&>(*this); }
290 inline iterator_type& operator=(container_iterator const &i) { this->_iter = i; return static_cast<iterator_type&>(*this); }
291 inline typename Container::reverse_iterator::reference operator*(void) const { return *this->_iter; }
292
293 inline typename Container::value_type getType(void) const { return *this->_iter; }
294 };
295 /*}}}*/
296 class PackageContainerInterface { /*{{{*/
297 /** \class PackageContainerInterface
298
299 * Interface ensuring that all operations can be executed on the yet to
300 * define concrete PackageContainer - access to all methods is possible,
301 * but in general the wrappers provided by the PackageContainer template
302 * are nicer to use.
303
304 * This class mostly protects use from the need to write all implementation
305 * of the methods working on containers in the template */
306 public:
307 template<class Itr> class iterator_base { /*{{{*/
308 pkgCache::PkgIterator getType() const { return static_cast<Itr const*>(this)->getType(); };
309 public:
310 operator pkgCache::PkgIterator(void) const { return getType(); }
311
312 inline const char *Name() const {return getType().Name(); }
313 inline std::string FullName(bool const Pretty) const { return getType().FullName(Pretty); }
314 inline std::string FullName() const { return getType().FullName(); }
315 APT_DEPRECATED_MSG("Use the .Section method of VerIterator instead") inline const char *Section() const {
316 APT_IGNORE_DEPRECATED_PUSH
317 return getType().Section();
318 APT_IGNORE_DEPRECATED_POP
319 }
320 inline bool Purge() const {return getType().Purge(); }
321 inline const char *Arch() const {return getType().Arch(); }
322 inline pkgCache::GrpIterator Group() const { return getType().Group(); }
323 inline pkgCache::VerIterator VersionList() const { return getType().VersionList(); }
324 inline pkgCache::VerIterator CurrentVer() const { return getType().CurrentVer(); }
325 inline pkgCache::DepIterator RevDependsList() const { return getType().RevDependsList(); }
326 inline pkgCache::PrvIterator ProvidesList() const { return getType().ProvidesList(); }
327 inline pkgCache::PkgIterator::OkState State() const { return getType().State(); }
328 inline const char *CandVersion() const { return getType().CandVersion(); }
329 inline const char *CurVersion() const { return getType().CurVersion(); }
330 inline pkgCache *Cache() const { return getType().Cache(); }
331 inline unsigned long Index() const {return getType().Index();}
332 // we have only valid iterators here
333 inline bool end() const { return false; }
334
335 inline pkgCache::Package const * operator->() const {return &*getType();}
336 };
337 /*}}}*/
338
339 virtual bool insert(pkgCache::PkgIterator const &P) = 0;
340 virtual bool empty() const = 0;
341 virtual void clear() = 0;
342 virtual size_t size() const = 0;
343
344 enum APT_DEPRECATED_MSG("Use CacheSetHelper::PkgSelector instead") Constructor { UNKNOWN = CacheSetHelper::UNKNOWN,
345 REGEX = CacheSetHelper::REGEX,
346 TASK = CacheSetHelper::TASK,
347 FNMATCH = CacheSetHelper::FNMATCH };
348 APT_IGNORE_DEPRECATED_PUSH
349 void setConstructor(Constructor const by) { ConstructedBy = (CacheSetHelper::PkgSelector)by; }
350 APT_IGNORE_DEPRECATED_POP
351
352 void setConstructor(CacheSetHelper::PkgSelector const by) { ConstructedBy = by; }
353 CacheSetHelper::PkgSelector getConstructor() const { return ConstructedBy; }
354 PackageContainerInterface();
355 explicit PackageContainerInterface(CacheSetHelper::PkgSelector const by);
356 PackageContainerInterface& operator=(PackageContainerInterface const &other);
357 virtual ~PackageContainerInterface();
358
359 APT_DEPRECATED_MSG("Use helper.PackageFrom(CacheSetHelper::TASK, …) instead") static bool FromTask(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) {
360 return helper.PackageFrom(CacheSetHelper::TASK, pci, Cache, pattern); }
361 APT_DEPRECATED_MSG("Use helper.PackageFrom(CacheSetHelper::REGEX, …) instead") static bool FromRegEx(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) {
362 return helper.PackageFrom(CacheSetHelper::REGEX, pci, Cache, pattern); }
363 APT_DEPRECATED_MSG("Use helper.PackageFrom(CacheSetHelper::FNMATCH, …) instead") static bool FromFnmatch(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) {
364 return helper.PackageFrom(CacheSetHelper::FNMATCH, pci, Cache, pattern); }
365 APT_DEPRECATED_MSG("Use helper.PackageFrom(CacheSetHelper::PACKAGENAME, …) instead") static bool FromGroup(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) {
366 return helper.PackageFrom(CacheSetHelper::PACKAGENAME, pci, Cache, pattern); }
367 APT_DEPRECATED_MSG("Use helper.PackageFrom(CacheSetHelper::STRING, …) instead") static bool FromString(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper) {
368 return helper.PackageFrom(CacheSetHelper::STRING, pci, Cache, pattern); }
369 APT_DEPRECATED_MSG("Use helper.PackageFromCommandLine instead") static bool FromCommandLine(PackageContainerInterface * const pci, pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper) {
370 return helper.PackageFromCommandLine(pci, Cache, cmdline); }
371
372 APT_DEPRECATED_MSG("enum moved to CacheSetHelper::PkgModifier") typedef CacheSetHelper::PkgModifier Modifier;
373
374 APT_IGNORE_DEPRECATED_PUSH
375 APT_DEPRECATED_MSG("Use helper.PackageFromName instead") static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper) {
376 return helper.PackageFromName(Cache, pattern); }
377 APT_DEPRECATED_MSG("Use helper.PackageFromModifierCommandLine instead") static bool FromModifierCommandLine(unsigned short &modID, PackageContainerInterface * const pci,
378 pkgCacheFile &Cache, const char * cmdline,
379 std::list<Modifier> const &mods, CacheSetHelper &helper) {
380 return helper.PackageFromModifierCommandLine(modID, pci, Cache, cmdline, mods); }
381 APT_IGNORE_DEPRECATED_POP
382
383 private:
384 CacheSetHelper::PkgSelector ConstructedBy;
385 void * const d;
386 };
387 /*}}}*/
388 template<class Container> class PackageContainer : public PackageContainerInterface {/*{{{*/
389 /** \class APT::PackageContainer
390
391 Simple wrapper around a container class like std::set to provide a similar
392 interface to a set of packages as to the complete set of all packages in the
393 pkgCache. */
394 Container _cont;
395 public: /*{{{*/
396 /** \brief smell like a pkgCache::PkgIterator */
397 typedef Container_const_iterator<PackageContainerInterface, Container, PackageContainer> const_iterator;
398 typedef Container_iterator<PackageContainerInterface, Container, PackageContainer> iterator;
399 typedef Container_const_reverse_iterator<PackageContainerInterface, Container, PackageContainer> const_reverse_iterator;
400 typedef Container_reverse_iterator<PackageContainerInterface, Container, PackageContainer> reverse_iterator;
401 typedef typename Container::value_type value_type;
402 typedef typename Container::pointer pointer;
403 typedef typename Container::const_pointer const_pointer;
404 typedef typename Container::reference reference;
405 typedef typename Container::const_reference const_reference;
406 typedef typename Container::difference_type difference_type;
407 typedef typename Container::size_type size_type;
408 typedef typename Container::allocator_type allocator_type;
409
410 bool insert(pkgCache::PkgIterator const &P) APT_OVERRIDE { if (P.end() == true) return false; _cont.insert(P); return true; }
411 template<class Cont> void insert(PackageContainer<Cont> const &pkgcont) { _cont.insert((typename Cont::const_iterator)pkgcont.begin(), (typename Cont::const_iterator)pkgcont.end()); }
412 void insert(const_iterator begin, const_iterator end) { _cont.insert(begin, end); }
413
414 bool empty() const APT_OVERRIDE { return _cont.empty(); }
415 void clear() APT_OVERRIDE { return _cont.clear(); }
416 size_t size() const APT_OVERRIDE { return _cont.size(); }
417 #if __GNUC__ >= 5 || (__GNUC_MINOR__ >= 9 && __GNUC__ >= 4)
418 iterator erase( const_iterator pos ) { return iterator(_cont.erase(pos._iter)); }
419 iterator erase( const_iterator first, const_iterator last ) { return iterator(_cont.erase(first._iter, last._iter)); }
420 #else
421 iterator erase( iterator pos ) { return iterator(_cont.erase(pos._iter)); }
422 iterator erase( iterator first, iterator last ) { return iterator(_cont.erase(first._iter, last._iter)); }
423 #endif
424 const_iterator begin() const { return const_iterator(_cont.begin()); }
425 const_iterator end() const { return const_iterator(_cont.end()); }
426 const_reverse_iterator rbegin() const { return const_reverse_iterator(_cont.rbegin()); }
427 const_reverse_iterator rend() const { return const_reverse_iterator(_cont.rend()); }
428 #if __cplusplus >= 201103L
429 const_iterator cbegin() const { return const_iterator(_cont.cbegin()); }
430 const_iterator cend() const { return const_iterator(_cont.cend()); }
431 const_reverse_iterator crbegin() const { return const_reverse_iterator(_cont.crbegin()); }
432 const_reverse_iterator crend() const { return const_reverse_iterator(_cont.crend()); }
433 #endif
434 iterator begin() { return iterator(_cont.begin()); }
435 iterator end() { return iterator(_cont.end()); }
436 reverse_iterator rbegin() { return reverse_iterator(_cont.rbegin()); }
437 reverse_iterator rend() { return reverse_iterator(_cont.rend()); }
438 const_iterator find(pkgCache::PkgIterator const &P) const { return const_iterator(_cont.find(P)); }
439
440 PackageContainer() : PackageContainerInterface(CacheSetHelper::UNKNOWN) {}
441 explicit PackageContainer(CacheSetHelper::PkgSelector const &by) : PackageContainerInterface(by) {}
442 APT_IGNORE_DEPRECATED_PUSH
443 APT_DEPRECATED_MSG("Construct with a CacheSetHelper::PkgSelector instead") explicit PackageContainer(Constructor const &by) : PackageContainerInterface((CacheSetHelper::PkgSelector)by) {}
444 APT_IGNORE_DEPRECATED_POP
445 template<typename Itr> PackageContainer(Itr first, Itr last) : PackageContainerInterface(CacheSetHelper::UNKNOWN), _cont(first, last) {}
446 #if __cplusplus >= 201103L
447 PackageContainer(std::initializer_list<value_type> list) : PackageContainerInterface(CacheSetHelper::UNKNOWN), _cont(list) {}
448 void push_back(value_type&& P) { _cont.emplace_back(std::move(P)); }
449 template<typename... Args> void emplace_back(Args&&... args) { _cont.emplace_back(std::forward<Args>(args)...); }
450 #endif
451 void push_back(const value_type& P) { _cont.push_back(P); }
452
453 /** \brief sort all included versions with given comparer
454
455 Some containers are sorted by default, some are not and can't be,
456 but a few like std::vector can be sorted if need be, so this can be
457 specialized in later on. The default is that this will fail though.
458 Specifically, already sorted containers like std::set will return
459 false as well as there is no easy way to check that the given comparer
460 would sort in the same way the set is currently sorted
461
462 \return \b true if the set was sorted, \b false if not. */
463 template<class Compare> bool sort(Compare /*Comp*/) { return false; }
464
465 /** \brief returns all packages in the cache who belong to the given task
466
467 A simple helper responsible for search for all members of a task
468 in the cache. Optional it prints a a notice about the
469 packages chosen cause of the given task.
470 \param Cache the packages are in
471 \param pattern name of the task
472 \param helper responsible for error and message handling */
473 static PackageContainer FromTask(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper) {
474 PackageContainer cont(CacheSetHelper::TASK);
475 helper.PackageFrom(CacheSetHelper::TASK, &cont, Cache, pattern);
476 return cont;
477 }
478 static PackageContainer FromTask(pkgCacheFile &Cache, std::string const &pattern) {
479 CacheSetHelper helper;
480 return FromTask(Cache, pattern, helper);
481 }
482
483 /** \brief returns all packages in the cache whose name matchs a given pattern
484
485 A simple helper responsible for executing a regular expression on all
486 package names in the cache. Optional it prints a a notice about the
487 packages chosen cause of the given package.
488 \param Cache the packages are in
489 \param pattern regular expression for package names
490 \param helper responsible for error and message handling */
491 static PackageContainer FromRegEx(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper) {
492 PackageContainer cont(CacheSetHelper::REGEX);
493 helper.PackageFrom(CacheSetHelper::REGEX, &cont, Cache, pattern);
494 return cont;
495 }
496
497 static PackageContainer FromRegEx(pkgCacheFile &Cache, std::string const &pattern) {
498 CacheSetHelper helper;
499 return FromRegEx(Cache, pattern, helper);
500 }
501
502 static PackageContainer FromFnmatch(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper) {
503 PackageContainer cont(CacheSetHelper::FNMATCH);
504 helper.PackageFrom(CacheSetHelper::FNMATCH, &cont, Cache, pattern);
505 return cont;
506 }
507 static PackageContainer FromFnMatch(pkgCacheFile &Cache, std::string const &pattern) {
508 CacheSetHelper helper;
509 return FromFnmatch(Cache, pattern, helper);
510 }
511
512 APT_IGNORE_DEPRECATED_PUSH
513 /** \brief returns a package specified by a string
514
515 \param Cache the package is in
516 \param pattern String the package name should be extracted from
517 \param helper responsible for error and message handling */
518 APT_DEPRECATED_MSG("Use helper.PackageFromName instead") static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper) {
519 return helper.PackageFromName(Cache, pattern);
520 }
521 APT_DEPRECATED_MSG("Use helper.PackageFromName instead") static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &pattern) {
522 CacheSetHelper helper;
523 return FromName(Cache, pattern, helper);
524 }
525 APT_IGNORE_DEPRECATED_POP
526
527 /** \brief returns all packages specified by a string
528
529 \param Cache the packages are in
530 \param pattern String the package name(s) should be extracted from
531 \param helper responsible for error and message handling */
532 static PackageContainer FromString(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper) {
533 PackageContainer cont;
534 helper.PackageFrom(CacheSetHelper::PACKAGENAME, &cont, Cache, pattern);
535 return cont;
536 }
537 static PackageContainer FromString(pkgCacheFile &Cache, std::string const &pattern) {
538 CacheSetHelper helper;
539 return FromString(Cache, pattern, helper);
540 }
541
542 /** \brief returns all packages specified on the commandline
543
544 Get all package names from the commandline and executes regex's if needed.
545 No special package command is supported, just plain names.
546 \param Cache the packages are in
547 \param cmdline Command line the package names should be extracted from
548 \param helper responsible for error and message handling */
549 static PackageContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper) {
550 PackageContainer cont;
551 helper.PackageFromCommandLine(&cont, Cache, cmdline);
552 return cont;
553 }
554 static PackageContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline) {
555 CacheSetHelper helper;
556 return FromCommandLine(Cache, cmdline, helper);
557 }
558
559 /** \brief group packages by a action modifiers
560
561 At some point it is needed to get from the same commandline
562 different package sets grouped by a modifier. Take
563 apt-get install apt awesome-
564 as an example.
565 \param Cache the packages are in
566 \param cmdline Command line the package names should be extracted from
567 \param mods list of modifiers the method should accept
568 \param fallback the default modifier group for a package
569 \param helper responsible for error and message handling */
570 static std::map<unsigned short, PackageContainer> GroupedFromCommandLine(
571 pkgCacheFile &Cache,
572 const char **cmdline,
573 std::list<CacheSetHelper::PkgModifier> const &mods,
574 unsigned short const &fallback,
575 CacheSetHelper &helper) {
576 std::map<unsigned short, PackageContainer> pkgsets;
577 for (const char **I = cmdline; *I != 0; ++I) {
578 unsigned short modID = fallback;
579 PackageContainer pkgset;
580 helper.PackageFromModifierCommandLine(modID, &pkgset, Cache, *I, mods);
581 pkgsets[modID].insert(pkgset);
582 }
583 return pkgsets;
584 }
585 static std::map<unsigned short, PackageContainer> GroupedFromCommandLine(
586 pkgCacheFile &Cache,
587 const char **cmdline,
588 std::list<CacheSetHelper::PkgModifier> const &mods,
589 unsigned short const &fallback) {
590 CacheSetHelper helper;
591 return GroupedFromCommandLine(Cache, cmdline,
592 mods, fallback, helper);
593 }
594 /*}}}*/
595 }; /*}}}*/
596 // various specialisations for PackageContainer /*{{{*/
597 template<> template<class Cont> void PackageContainer<std::list<pkgCache::PkgIterator> >::insert(PackageContainer<Cont> const &pkgcont) {
598 for (typename PackageContainer<Cont>::const_iterator p = pkgcont.begin(); p != pkgcont.end(); ++p)
599 _cont.push_back(*p);
600 }
601 #if __cplusplus >= 201103L
602 template<> template<class Cont> void PackageContainer<std::forward_list<pkgCache::PkgIterator> >::insert(PackageContainer<Cont> const &pkgcont) {
603 for (typename PackageContainer<Cont>::const_iterator p = pkgcont.begin(); p != pkgcont.end(); ++p)
604 _cont.push_front(*p);
605 }
606 #endif
607 template<> template<class Cont> void PackageContainer<std::deque<pkgCache::PkgIterator> >::insert(PackageContainer<Cont> const &pkgcont) {
608 for (typename PackageContainer<Cont>::const_iterator p = pkgcont.begin(); p != pkgcont.end(); ++p)
609 _cont.push_back(*p);
610 }
611 template<> template<class Cont> void PackageContainer<std::vector<pkgCache::PkgIterator> >::insert(PackageContainer<Cont> const &pkgcont) {
612 for (typename PackageContainer<Cont>::const_iterator p = pkgcont.begin(); p != pkgcont.end(); ++p)
613 _cont.push_back(*p);
614 }
615 // these are 'inline' as otherwise the linker has problems with seeing these untemplated
616 // specializations again and again - but we need to see them, so that library users can use them
617 template<> inline bool PackageContainer<std::list<pkgCache::PkgIterator> >::insert(pkgCache::PkgIterator const &P) {
618 if (P.end() == true)
619 return false;
620 _cont.push_back(P);
621 return true;
622 }
623 #if __cplusplus >= 201103L
624 template<> inline bool PackageContainer<std::forward_list<pkgCache::PkgIterator> >::insert(pkgCache::PkgIterator const &P) {
625 if (P.end() == true)
626 return false;
627 _cont.push_front(P);
628 return true;
629 }
630 #endif
631 template<> inline bool PackageContainer<std::deque<pkgCache::PkgIterator> >::insert(pkgCache::PkgIterator const &P) {
632 if (P.end() == true)
633 return false;
634 _cont.push_back(P);
635 return true;
636 }
637 template<> inline bool PackageContainer<std::vector<pkgCache::PkgIterator> >::insert(pkgCache::PkgIterator const &P) {
638 if (P.end() == true)
639 return false;
640 _cont.push_back(P);
641 return true;
642 }
643 template<> inline void PackageContainer<std::list<pkgCache::PkgIterator> >::insert(const_iterator begin, const_iterator end) {
644 for (const_iterator p = begin; p != end; ++p)
645 _cont.push_back(*p);
646 }
647 #if __cplusplus >= 201103L
648 template<> inline void PackageContainer<std::forward_list<pkgCache::PkgIterator> >::insert(const_iterator begin, const_iterator end) {
649 for (const_iterator p = begin; p != end; ++p)
650 _cont.push_front(*p);
651 }
652 #endif
653 template<> inline void PackageContainer<std::deque<pkgCache::PkgIterator> >::insert(const_iterator begin, const_iterator end) {
654 for (const_iterator p = begin; p != end; ++p)
655 _cont.push_back(*p);
656 }
657 template<> inline void PackageContainer<std::vector<pkgCache::PkgIterator> >::insert(const_iterator begin, const_iterator end) {
658 for (const_iterator p = begin; p != end; ++p)
659 _cont.push_back(*p);
660 }
661 #if APT_GCC_VERSION < 0x409
662 template<> inline PackageContainer<std::set<pkgCache::PkgIterator> >::iterator PackageContainer<std::set<pkgCache::PkgIterator> >::erase(iterator i) {
663 _cont.erase(i._iter);
664 return end();
665 }
666 template<> inline PackageContainer<std::set<pkgCache::PkgIterator> >::iterator PackageContainer<std::set<pkgCache::PkgIterator> >::erase(iterator first, iterator last) {
667 _cont.erase(first, last);
668 return end();
669 }
670 #endif
671 template<> template<class Compare> inline bool PackageContainer<std::vector<pkgCache::PkgIterator> >::sort(Compare Comp) {
672 std::sort(_cont.begin(), _cont.end(), Comp);
673 return true;
674 }
675 template<> template<class Compare> inline bool PackageContainer<std::list<pkgCache::PkgIterator> >::sort(Compare Comp) {
676 _cont.sort(Comp);
677 return true;
678 }
679 #if __cplusplus >= 201103L
680 template<> template<class Compare> inline bool PackageContainer<std::forward_list<pkgCache::PkgIterator> >::sort(Compare Comp) {
681 _cont.sort(Comp);
682 return true;
683 }
684 #endif
685 template<> template<class Compare> inline bool PackageContainer<std::deque<pkgCache::PkgIterator> >::sort(Compare Comp) {
686 std::sort(_cont.begin(), _cont.end(), Comp);
687 return true;
688 }
689 /*}}}*/
690
691 // class PackageUniverse - pkgCache as PackageContainerInterface /*{{{*/
692 /** \class PackageUniverse
693
694 Wraps around our usual pkgCache, so that it can be stuffed into methods
695 expecting a PackageContainer.
696
697 The wrapping is read-only in practice modeled by making erase and co
698 private methods. */
699 class APT_PUBLIC PackageUniverse : public PackageContainerInterface {
700 pkgCache * const _cont;
701 void * const d;
702 public:
703 class const_iterator : public APT::Container_iterator_base<APT::PackageContainerInterface, PackageUniverse, PackageUniverse::const_iterator, pkgCache::PkgIterator, pkgCache::PkgIterator>
704 {
705 public:
706 explicit const_iterator(pkgCache::PkgIterator i):
707 Container_iterator_base<APT::PackageContainerInterface, PackageUniverse, PackageUniverse::const_iterator, pkgCache::PkgIterator, pkgCache::PkgIterator>(i) {}
708
709 inline pkgCache::PkgIterator getType(void) const { return _iter; }
710 };
711 typedef const_iterator iterator;
712 typedef pkgCache::PkgIterator value_type;
713 typedef typename pkgCache::PkgIterator* pointer;
714 typedef typename pkgCache::PkgIterator const* const_pointer;
715 typedef const pkgCache::PkgIterator& const_reference;
716 typedef const_reference reference;
717 typedef const_iterator::difference_type difference_type;
718 typedef std::make_unsigned<const_iterator::difference_type>::type size_type;
719
720
721 bool empty() const APT_OVERRIDE { return false; }
722 size_t size() const APT_OVERRIDE { return _cont->Head().PackageCount; }
723
724 const_iterator begin() const { return const_iterator(_cont->PkgBegin()); }
725 const_iterator end() const { return const_iterator(_cont->PkgEnd()); }
726 const_iterator cbegin() const { return const_iterator(_cont->PkgBegin()); }
727 const_iterator cend() const { return const_iterator(_cont->PkgEnd()); }
728 iterator begin() { return iterator(_cont->PkgBegin()); }
729 iterator end() { return iterator(_cont->PkgEnd()); }
730
731 pkgCache * data() const { return _cont; }
732
733 explicit PackageUniverse(pkgCache * const Owner);
734 explicit PackageUniverse(pkgCacheFile * const Owner);
735 virtual ~PackageUniverse();
736
737 private:
738 APT_HIDDEN bool insert(pkgCache::PkgIterator const &) APT_OVERRIDE { return true; }
739 template<class Cont> APT_HIDDEN void insert(PackageContainer<Cont> const &) { }
740 APT_HIDDEN void insert(const_iterator, const_iterator) { }
741
742 APT_HIDDEN void clear() APT_OVERRIDE { }
743 APT_HIDDEN iterator erase( const_iterator pos );
744 APT_HIDDEN iterator erase( const_iterator first, const_iterator last );
745 };
746 /*}}}*/
747 typedef PackageContainer<std::set<pkgCache::PkgIterator> > PackageSet;
748 #if __cplusplus >= 201103L
749 typedef PackageContainer<std::unordered_set<pkgCache::PkgIterator> > PackageUnorderedSet;
750 typedef PackageContainer<std::forward_list<pkgCache::PkgIterator> > PackageForwardList;
751 #endif
752 typedef PackageContainer<std::list<pkgCache::PkgIterator> > PackageList;
753 typedef PackageContainer<std::deque<pkgCache::PkgIterator> > PackageDeque;
754 typedef PackageContainer<std::vector<pkgCache::PkgIterator> > PackageVector;
755
756 class VersionContainerInterface { /*{{{*/
757 /** \class APT::VersionContainerInterface
758
759 Same as APT::PackageContainerInterface, just for Versions */
760 public:
761 /** \brief smell like a pkgCache::VerIterator */
762 template<class Itr> class iterator_base { /*{{{*/
763 pkgCache::VerIterator getType() const { return static_cast<Itr const*>(this)->getType(); };
764 public:
765 operator pkgCache::VerIterator(void) { return getType(); }
766
767 inline pkgCache *Cache() const { return getType().Cache(); }
768 inline unsigned long Index() const {return getType().Index();}
769 inline int CompareVer(const pkgCache::VerIterator &B) const { return getType().CompareVer(B); }
770 inline const char *VerStr() const { return getType().VerStr(); }
771 inline const char *Section() const { return getType().Section(); }
772 inline const char *Arch() const { return getType().Arch(); }
773 inline pkgCache::PkgIterator ParentPkg() const { return getType().ParentPkg(); }
774 inline pkgCache::DescIterator DescriptionList() const { return getType().DescriptionList(); }
775 inline pkgCache::DescIterator TranslatedDescription() const { return getType().TranslatedDescription(); }
776 inline pkgCache::DepIterator DependsList() const { return getType().DependsList(); }
777 inline pkgCache::PrvIterator ProvidesList() const { return getType().ProvidesList(); }
778 inline pkgCache::VerFileIterator FileList() const { return getType().FileList(); }
779 inline bool Downloadable() const { return getType().Downloadable(); }
780 inline const char *PriorityType() const { return getType().PriorityType(); }
781 inline std::string RelStr() const { return getType().RelStr(); }
782 inline bool Automatic() const { return getType().Automatic(); }
783 inline pkgCache::VerFileIterator NewestFile() const { return getType().NewestFile(); }
784 // we have only valid iterators here
785 inline bool end() const { return false; }
786
787 inline pkgCache::Version const * operator->() const { return &*getType(); }
788 };
789 /*}}}*/
790
791 virtual bool insert(pkgCache::VerIterator const &V) = 0;
792 virtual bool empty() const = 0;
793 virtual void clear() = 0;
794 virtual size_t size() const = 0;
795
796 /** \brief specifies which version(s) will be returned if non is given */
797 enum APT_DEPRECATED_MSG("enum moved to CacheSetHelper::VerSelector instead") Version {
798 ALL = CacheSetHelper::ALL,
799 CANDANDINST = CacheSetHelper::CANDANDINST,
800 CANDIDATE = CacheSetHelper::CANDIDATE,
801 INSTALLED = CacheSetHelper::INSTALLED,
802 CANDINST = CacheSetHelper::CANDINST,
803 INSTCAND = CacheSetHelper::INSTCAND,
804 NEWEST = CacheSetHelper::NEWEST
805 };
806
807 struct Modifier {
808 unsigned short const ID;
809 const char * const Alias;
810 enum Position { NONE, PREFIX, POSTFIX } const Pos;
811 enum CacheSetHelper::VerSelector const SelectVersion;
812 Modifier (unsigned short const &id, const char * const alias, Position const &pos,
813 enum CacheSetHelper::VerSelector const select) : ID(id), Alias(alias), Pos(pos),
814 SelectVersion(select) {}
815 APT_IGNORE_DEPRECATED_PUSH
816 APT_DEPRECATED_MSG("Construct with a CacheSetHelper::VerSelector instead") Modifier(unsigned short const &id, const char * const alias, Position const &pos,
817 Version const &select) : ID(id), Alias(alias), Pos(pos),
818 SelectVersion((CacheSetHelper::VerSelector)select) {}
819 APT_IGNORE_DEPRECATED_POP
820 };
821
822 static bool FromCommandLine(VersionContainerInterface * const vci, pkgCacheFile &Cache,
823 const char **cmdline, CacheSetHelper::VerSelector const fallback,
824 CacheSetHelper &helper);
825 APT_IGNORE_DEPRECATED_PUSH
826 APT_DEPRECATED_MSG("Use CacheSetHelper::VerSelector as fallback selector") static bool FromCommandLine(VersionContainerInterface * const vci, pkgCacheFile &Cache,
827 const char **cmdline, Version const &fallback,
828 CacheSetHelper &helper) {
829 return FromCommandLine(vci, Cache, cmdline, (CacheSetHelper::VerSelector)fallback, helper);
830 }
831 APT_IGNORE_DEPRECATED_POP
832
833 static bool FromString(VersionContainerInterface * const vci, pkgCacheFile &Cache,
834 std::string pkg, CacheSetHelper::VerSelector const fallback, CacheSetHelper &helper,
835 bool const onlyFromName = false);
836 APT_IGNORE_DEPRECATED_PUSH
837 APT_DEPRECATED_MSG("Use CacheSetHelper::VerSelector as fallback selector") static bool FromString(VersionContainerInterface * const vci, pkgCacheFile &Cache,
838 std::string pkg, Version const &fallback, CacheSetHelper &helper,
839 bool const onlyFromName = false) {
840 return FromString(vci, Cache, pkg, (CacheSetHelper::VerSelector)fallback, helper, onlyFromName);
841 }
842 APT_IGNORE_DEPRECATED_POP
843
844 static bool FromPackage(VersionContainerInterface * const vci, pkgCacheFile &Cache,
845 pkgCache::PkgIterator const &P, CacheSetHelper::VerSelector const fallback,
846 CacheSetHelper &helper);
847 APT_IGNORE_DEPRECATED_PUSH
848 APT_DEPRECATED_MSG("Use CacheSetHelper::VerSelector as fallback selector") static bool FromPackage(VersionContainerInterface * const vci, pkgCacheFile &Cache,
849 pkgCache::PkgIterator const &P, Version const &fallback,
850 CacheSetHelper &helper) {
851 return FromPackage(vci, Cache, P, (CacheSetHelper::VerSelector)fallback, helper);
852 }
853 APT_IGNORE_DEPRECATED_POP
854
855 static bool FromModifierCommandLine(unsigned short &modID,
856 VersionContainerInterface * const vci,
857 pkgCacheFile &Cache, const char * cmdline,
858 std::list<Modifier> const &mods,
859 CacheSetHelper &helper);
860
861
862 static bool FromDependency(VersionContainerInterface * const vci,
863 pkgCacheFile &Cache,
864 pkgCache::DepIterator const &D,
865 CacheSetHelper::VerSelector const selector,
866 CacheSetHelper &helper);
867 APT_IGNORE_DEPRECATED_PUSH
868 APT_DEPRECATED_MSG("Use CacheSetHelper::VerSelector as fallback selector") static bool FromDependency(VersionContainerInterface * const vci,
869 pkgCacheFile &Cache,
870 pkgCache::DepIterator const &D,
871 Version const &selector,
872 CacheSetHelper &helper) {
873 return FromDependency(vci, Cache, D, (CacheSetHelper::VerSelector)selector, helper);
874 }
875 APT_IGNORE_DEPRECATED_POP
876
877 VersionContainerInterface();
878 VersionContainerInterface& operator=(VersionContainerInterface const &other);
879 virtual ~VersionContainerInterface();
880 private:
881 void * const d;
882
883 protected: /*{{{*/
884
885 /** \brief returns the candidate version of the package
886
887 \param Cache to be used to query for information
888 \param Pkg we want the candidate version from this package
889 \param helper used in this container instance */
890 static pkgCache::VerIterator getCandidateVer(pkgCacheFile &Cache,
891 pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper);
892
893 /** \brief returns the installed version of the package
894
895 \param Cache to be used to query for information
896 \param Pkg we want the installed version from this package
897 \param helper used in this container instance */
898 static pkgCache::VerIterator getInstalledVer(pkgCacheFile &Cache,
899 pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper);
900 /*}}}*/
901 };
902 /*}}}*/
903 template<class Container> class VersionContainer : public VersionContainerInterface {/*{{{*/
904 /** \class APT::VersionContainer
905
906 Simple wrapper around a container class like std::set to provide a similar
907 interface to a set of versions as to the complete set of all versions in the
908 pkgCache. */
909 Container _cont;
910 public: /*{{{*/
911
912 typedef Container_const_iterator<VersionContainerInterface, Container, VersionContainer> const_iterator;
913 typedef Container_iterator<VersionContainerInterface, Container, VersionContainer> iterator;
914 typedef Container_const_reverse_iterator<VersionContainerInterface, Container, VersionContainer> const_reverse_iterator;
915 typedef Container_reverse_iterator<VersionContainerInterface, Container, VersionContainer> reverse_iterator;
916 typedef typename Container::value_type value_type;
917 typedef typename Container::pointer pointer;
918 typedef typename Container::const_pointer const_pointer;
919 typedef typename Container::reference reference;
920 typedef typename Container::const_reference const_reference;
921 typedef typename Container::difference_type difference_type;
922 typedef typename Container::size_type size_type;
923 typedef typename Container::allocator_type allocator_type;
924
925 bool insert(pkgCache::VerIterator const &V) APT_OVERRIDE { if (V.end() == true) return false; _cont.insert(V); return true; }
926 template<class Cont> void insert(VersionContainer<Cont> const &vercont) { _cont.insert((typename Cont::const_iterator)vercont.begin(), (typename Cont::const_iterator)vercont.end()); }
927 void insert(const_iterator begin, const_iterator end) { _cont.insert(begin, end); }
928 bool empty() const APT_OVERRIDE { return _cont.empty(); }
929 void clear() APT_OVERRIDE { return _cont.clear(); }
930 size_t size() const APT_OVERRIDE { return _cont.size(); }
931 #if APT_GCC_VERSION >= 0x409
932 iterator erase( const_iterator pos ) { return iterator(_cont.erase(pos._iter)); }
933 iterator erase( const_iterator first, const_iterator last ) { return iterator(_cont.erase(first._iter, last._iter)); }
934 #else
935 iterator erase( iterator pos ) { return iterator(_cont.erase(pos._iter)); }
936 iterator erase( iterator first, iterator last ) { return iterator(_cont.erase(first._iter, last._iter)); }
937 #endif
938 const_iterator begin() const { return const_iterator(_cont.begin()); }
939 const_iterator end() const { return const_iterator(_cont.end()); }
940 const_reverse_iterator rbegin() const { return const_reverse_iterator(_cont.rbegin()); }
941 const_reverse_iterator rend() const { return const_reverse_iterator(_cont.rend()); }
942 #if __cplusplus >= 201103L
943 const_iterator cbegin() const { return const_iterator(_cont.cbegin()); }
944 const_iterator cend() const { return const_iterator(_cont.cend()); }
945 const_reverse_iterator crbegin() const { return const_reverse_iterator(_cont.crbegin()); }
946 const_reverse_iterator crend() const { return const_reverse_iterator(_cont.crend()); }
947 #endif
948 iterator begin() { return iterator(_cont.begin()); }
949 iterator end() { return iterator(_cont.end()); }
950 reverse_iterator rbegin() { return reverse_iterator(_cont.rbegin()); }
951 reverse_iterator rend() { return reverse_iterator(_cont.rend()); }
952 const_iterator find(pkgCache::VerIterator const &V) const { return const_iterator(_cont.find(V)); }
953
954 VersionContainer() : VersionContainerInterface() {}
955 template<typename Itr> VersionContainer(Itr first, Itr last) : VersionContainerInterface(), _cont(first, last) {}
956 #if __cplusplus >= 201103L
957 VersionContainer(std::initializer_list<value_type> list) : VersionContainerInterface(), _cont(list) {}
958 void push_back(value_type&& P) { _cont.emplace_back(std::move(P)); }
959 template<typename... Args> void emplace_back(Args&&... args) { _cont.emplace_back(std::forward<Args>(args)...); }
960 #endif
961 void push_back(const value_type& P) { _cont.push_back(P); }
962
963 /** \brief sort all included versions with given comparer
964
965 Some containers are sorted by default, some are not and can't be,
966 but a few like std::vector can be sorted if need be, so this can be
967 specialized in later on. The default is that this will fail though.
968 Specifically, already sorted containers like std::set will return
969 false as well as there is no easy way to check that the given comparer
970 would sort in the same way the set is currently sorted
971
972 \return \b true if the set was sorted, \b false if not. */
973 template<class Compare> bool sort(Compare /*Comp*/) { return false; }
974
975 /** \brief returns all versions specified on the commandline
976
977 Get all versions from the commandline, uses given default version if
978 non specifically requested and executes regex's if needed on names.
979 \param Cache the packages and versions are in
980 \param cmdline Command line the versions should be extracted from
981 \param fallback version specification
982 \param helper responsible for error and message handling */
983 static VersionContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline,
984 CacheSetHelper::VerSelector const fallback, CacheSetHelper &helper) {
985 VersionContainer vercon;
986 VersionContainerInterface::FromCommandLine(&vercon, Cache, cmdline, fallback, helper);
987 return vercon;
988 }
989 static VersionContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline,
990 CacheSetHelper::VerSelector const fallback) {
991 CacheSetHelper helper;
992 return FromCommandLine(Cache, cmdline, fallback, helper);
993 }
994 static VersionContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline) {
995 return FromCommandLine(Cache, cmdline, CacheSetHelper::CANDINST);
996 }
997 static VersionContainer FromString(pkgCacheFile &Cache, std::string const &pkg,
998 CacheSetHelper::VerSelector const fallback, CacheSetHelper &helper,
999 bool const /*onlyFromName = false*/) {
1000 VersionContainer vercon;
1001 VersionContainerInterface::FromString(&vercon, Cache, pkg, fallback, helper);
1002 return vercon;
1003 }
1004 static VersionContainer FromString(pkgCacheFile &Cache, std::string pkg,
1005 CacheSetHelper::VerSelector const fallback) {
1006 CacheSetHelper helper;
1007 return FromString(Cache, pkg, fallback, helper);
1008 }
1009 static VersionContainer FromString(pkgCacheFile &Cache, std::string pkg) {
1010 return FromString(Cache, pkg, CacheSetHelper::CANDINST);
1011 }
1012 APT_IGNORE_DEPRECATED_PUSH
1013 static VersionContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline,
1014 Version const &fallback, CacheSetHelper &helper) {
1015 VersionContainer vercon;
1016 VersionContainerInterface::FromCommandLine(&vercon, Cache, cmdline, (CacheSetHelper::VerSelector)fallback, helper);
1017 return vercon;
1018 }
1019 static VersionContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline,
1020 Version const &fallback) {
1021 CacheSetHelper helper;
1022 return FromCommandLine(Cache, cmdline, (CacheSetHelper::VerSelector)fallback, helper);
1023 }
1024 static VersionContainer FromString(pkgCacheFile &Cache, std::string const &pkg,
1025 Version const &fallback, CacheSetHelper &helper,
1026 bool const /*onlyFromName = false*/) {
1027 VersionContainer vercon;
1028 VersionContainerInterface::FromString(&vercon, Cache, pkg, (CacheSetHelper::VerSelector)fallback, helper);
1029 return vercon;
1030 }
1031 static VersionContainer FromString(pkgCacheFile &Cache, std::string pkg,
1032 Version const &fallback) {
1033 CacheSetHelper helper;
1034 return FromString(Cache, pkg, (CacheSetHelper::VerSelector)fallback, helper);
1035 }
1036 APT_IGNORE_DEPRECATED_POP
1037
1038 /** \brief returns all versions specified for the package
1039
1040 \param Cache the package and versions are in
1041 \param P the package in question
1042 \param fallback the version(s) you want to get
1043 \param helper the helper used for display and error handling */
1044 static VersionContainer FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P,
1045 CacheSetHelper::VerSelector const fallback, CacheSetHelper &helper) {
1046 VersionContainer vercon;
1047 VersionContainerInterface::FromPackage(&vercon, Cache, P, fallback, helper);
1048 return vercon;
1049 }
1050 static VersionContainer FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P,
1051 CacheSetHelper::VerSelector const fallback) {
1052 CacheSetHelper helper;
1053 return FromPackage(Cache, P, fallback, helper);
1054 }
1055 APT_IGNORE_DEPRECATED_PUSH
1056 static VersionContainer FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P,
1057 Version const &fallback, CacheSetHelper &helper) {
1058 VersionContainer vercon;
1059 VersionContainerInterface::FromPackage(&vercon, Cache, P, (CacheSetHelper::VerSelector)fallback, helper);
1060 return vercon;
1061 }
1062 static VersionContainer FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P,
1063 Version const &fallback) {
1064 CacheSetHelper helper;
1065 return FromPackage(Cache, P, (CacheSetHelper::VerSelector)fallback, helper);
1066 }
1067 APT_IGNORE_DEPRECATED_POP
1068 static VersionContainer FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P) {
1069 return FromPackage(Cache, P, CacheSetHelper::CANDIDATE);
1070 }
1071
1072 static std::map<unsigned short, VersionContainer> GroupedFromCommandLine(
1073 pkgCacheFile &Cache,
1074 const char **cmdline,
1075 std::list<Modifier> const &mods,
1076 unsigned short const fallback,
1077 CacheSetHelper &helper) {
1078 std::map<unsigned short, VersionContainer> versets;
1079 for (const char **I = cmdline; *I != 0; ++I) {
1080 unsigned short modID = fallback;
1081 VersionContainer verset;
1082 VersionContainerInterface::FromModifierCommandLine(modID, &verset, Cache, *I, mods, helper);
1083 versets[modID].insert(verset);
1084 }
1085 return versets;
1086
1087 }
1088 static std::map<unsigned short, VersionContainer> GroupedFromCommandLine(
1089 pkgCacheFile &Cache, const char **cmdline,
1090 std::list<Modifier> const &mods,
1091 unsigned short const fallback) {
1092 CacheSetHelper helper;
1093 return GroupedFromCommandLine(Cache, cmdline,
1094 mods, fallback, helper);
1095 }
1096
1097 static VersionContainer FromDependency(pkgCacheFile &Cache, pkgCache::DepIterator const &D,
1098 CacheSetHelper::VerSelector const selector, CacheSetHelper &helper) {
1099 VersionContainer vercon;
1100 VersionContainerInterface::FromDependency(&vercon, Cache, D, selector, helper);
1101 return vercon;
1102 }
1103 static VersionContainer FromDependency(pkgCacheFile &Cache, pkgCache::DepIterator const &D,
1104 CacheSetHelper::VerSelector const selector) {
1105 CacheSetHelper helper;
1106 return FromDependency(Cache, D, selector, helper);
1107 }
1108 APT_IGNORE_DEPRECATED_PUSH
1109 static VersionContainer FromDependency(pkgCacheFile &Cache, pkgCache::DepIterator const &D,
1110 Version const &selector, CacheSetHelper &helper) {
1111 VersionContainer vercon;
1112 VersionContainerInterface::FromDependency(&vercon, Cache, D, (CacheSetHelper::VerSelector)selector, helper);
1113 return vercon;
1114 }
1115 static VersionContainer FromDependency(pkgCacheFile &Cache, pkgCache::DepIterator const &D,
1116 Version const &selector) {
1117 CacheSetHelper helper;
1118 return FromDependency(Cache, D, (CacheSetHelper::VerSelector)selector, helper);
1119 }
1120 APT_IGNORE_DEPRECATED_POP
1121 static VersionContainer FromDependency(pkgCacheFile &Cache, pkgCache::DepIterator const &D) {
1122 return FromDependency(Cache, D, CacheSetHelper::CANDIDATE);
1123 }
1124 /*}}}*/
1125 }; /*}}}*/
1126 // various specialisations for VersionContainer /*{{{*/
1127 template<> template<class Cont> void VersionContainer<std::list<pkgCache::VerIterator> >::insert(VersionContainer<Cont> const &vercont) {
1128 for (typename VersionContainer<Cont>::const_iterator v = vercont.begin(); v != vercont.end(); ++v)
1129 _cont.push_back(*v);
1130 }
1131 #if __cplusplus >= 201103L
1132 template<> template<class Cont> void VersionContainer<std::forward_list<pkgCache::VerIterator> >::insert(VersionContainer<Cont> const &vercont) {
1133 for (typename VersionContainer<Cont>::const_iterator v = vercont.begin(); v != vercont.end(); ++v)
1134 _cont.push_front(*v);
1135 }
1136 #endif
1137 template<> template<class Cont> void VersionContainer<std::deque<pkgCache::VerIterator> >::insert(VersionContainer<Cont> const &vercont) {
1138 for (typename VersionContainer<Cont>::const_iterator v = vercont.begin(); v != vercont.end(); ++v)
1139 _cont.push_back(*v);
1140 }
1141 template<> template<class Cont> void VersionContainer<std::vector<pkgCache::VerIterator> >::insert(VersionContainer<Cont> const &vercont) {
1142 for (typename VersionContainer<Cont>::const_iterator v = vercont.begin(); v != vercont.end(); ++v)
1143 _cont.push_back(*v);
1144 }
1145 // these are 'inline' as otherwise the linker has problems with seeing these untemplated
1146 // specializations again and again - but we need to see them, so that library users can use them
1147 template<> inline bool VersionContainer<std::list<pkgCache::VerIterator> >::insert(pkgCache::VerIterator const &V) {
1148 if (V.end() == true)
1149 return false;
1150 _cont.push_back(V);
1151 return true;
1152 }
1153 #if __cplusplus >= 201103L
1154 template<> inline bool VersionContainer<std::forward_list<pkgCache::VerIterator> >::insert(pkgCache::VerIterator const &V) {
1155 if (V.end() == true)
1156 return false;
1157 _cont.push_front(V);
1158 return true;
1159 }
1160 #endif
1161 template<> inline bool VersionContainer<std::deque<pkgCache::VerIterator> >::insert(pkgCache::VerIterator const &V) {
1162 if (V.end() == true)
1163 return false;
1164 _cont.push_back(V);
1165 return true;
1166 }
1167 template<> inline bool VersionContainer<std::vector<pkgCache::VerIterator> >::insert(pkgCache::VerIterator const &V) {
1168 if (V.end() == true)
1169 return false;
1170 _cont.push_back(V);
1171 return true;
1172 }
1173 template<> inline void VersionContainer<std::list<pkgCache::VerIterator> >::insert(const_iterator begin, const_iterator end) {
1174 for (const_iterator v = begin; v != end; ++v)
1175 _cont.push_back(*v);
1176 }
1177 #if __cplusplus >= 201103L
1178 template<> inline void VersionContainer<std::forward_list<pkgCache::VerIterator> >::insert(const_iterator begin, const_iterator end) {
1179 for (const_iterator v = begin; v != end; ++v)
1180 _cont.push_front(*v);
1181 }
1182 #endif
1183 template<> inline void VersionContainer<std::deque<pkgCache::VerIterator> >::insert(const_iterator begin, const_iterator end) {
1184 for (const_iterator v = begin; v != end; ++v)
1185 _cont.push_back(*v);
1186 }
1187 template<> inline void VersionContainer<std::vector<pkgCache::VerIterator> >::insert(const_iterator begin, const_iterator end) {
1188 for (const_iterator v = begin; v != end; ++v)
1189 _cont.push_back(*v);
1190 }
1191 #if APT_GCC_VERSION < 0x409
1192 template<> inline VersionContainer<std::set<pkgCache::VerIterator> >::iterator VersionContainer<std::set<pkgCache::VerIterator> >::erase(iterator i) {
1193 _cont.erase(i._iter);
1194 return end();
1195 }
1196 template<> inline VersionContainer<std::set<pkgCache::VerIterator> >::iterator VersionContainer<std::set<pkgCache::VerIterator> >::erase(iterator first, iterator last) {
1197 _cont.erase(first, last);
1198 return end();
1199 }
1200 #endif
1201 template<> template<class Compare> inline bool VersionContainer<std::vector<pkgCache::VerIterator> >::sort(Compare Comp) {
1202 std::sort(_cont.begin(), _cont.end(), Comp);
1203 return true;
1204 }
1205 template<> template<class Compare> inline bool VersionContainer<std::list<pkgCache::VerIterator> >::sort(Compare Comp) {
1206 _cont.sort(Comp);
1207 return true;
1208 }
1209 #if __cplusplus >= 201103L
1210 template<> template<class Compare> inline bool VersionContainer<std::forward_list<pkgCache::VerIterator> >::sort(Compare Comp) {
1211 _cont.sort(Comp);
1212 return true;
1213 }
1214 #endif
1215 template<> template<class Compare> inline bool VersionContainer<std::deque<pkgCache::VerIterator> >::sort(Compare Comp) {
1216 std::sort(_cont.begin(), _cont.end(), Comp);
1217 return true;
1218 }
1219 /*}}}*/
1220
1221 typedef VersionContainer<std::set<pkgCache::VerIterator> > VersionSet;
1222 #if __cplusplus >= 201103L
1223 typedef VersionContainer<std::unordered_set<pkgCache::VerIterator> > VersionUnorderedSet;
1224 typedef VersionContainer<std::forward_list<pkgCache::VerIterator> > VersionForwardList;
1225 #endif
1226 typedef VersionContainer<std::list<pkgCache::VerIterator> > VersionList;
1227 typedef VersionContainer<std::deque<pkgCache::VerIterator> > VersionDeque;
1228 typedef VersionContainer<std::vector<pkgCache::VerIterator> > VersionVector;
1229 }
1230 #endif