]> git.saurik.com Git - apt.git/blame_incremental - apt-pkg/cacheset.h
add specialisations for std::vector
[apt.git] / apt-pkg / cacheset.h
... / ...
CommitLineData
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#include <list>
16#include <vector>
17#include <string>
18#include <iterator>
19#include <algorithm>
20
21#include <stddef.h>
22
23#include <apt-pkg/error.h>
24#include <apt-pkg/pkgcache.h>
25#include <apt-pkg/cacheiterators.h>
26
27#ifndef APT_8_CLEANER_HEADERS
28#include <apt-pkg/cachefile.h>
29#endif
30#ifndef APT_10_CLEANER_HEADERS
31#include <iostream>
32#endif
33 /*}}}*/
34
35class pkgCacheFile;
36
37namespace APT {
38class PackageContainerInterface;
39class VersionContainerInterface;
40
41class CacheSetHelper { /*{{{*/
42/** \class APT::CacheSetHelper
43 Simple base class with a lot of virtual methods which can be overridden
44 to alter the behavior or the output of the CacheSets.
45
46 This helper is passed around by the static methods in the CacheSets and
47 used every time they hit an error condition or something could be
48 printed out.
49*/
50public: /*{{{*/
51 CacheSetHelper(bool const ShowError = true,
52 GlobalError::MsgType ErrorType = GlobalError::ERROR) :
53 ShowError(ShowError), ErrorType(ErrorType) {}
54 virtual ~CacheSetHelper() {}
55
56 virtual void showTaskSelection(pkgCache::PkgIterator const &pkg, std::string const &pattern);
57 virtual void showRegExSelection(pkgCache::PkgIterator const &pkg, std::string const &pattern);
58#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
59 virtual void showFnmatchSelection(pkgCache::PkgIterator const &pkg, std::string const &pattern);
60#endif
61 virtual void showSelectedVersion(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const Ver,
62 std::string const &ver, bool const verIsRel);
63
64 virtual void canNotFindTask(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern);
65 virtual void canNotFindRegEx(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern);
66#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
67 virtual void canNotFindFnmatch(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern);
68#endif
69 virtual void canNotFindPackage(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &str);
70
71 virtual void canNotFindAllVer(VersionContainerInterface * const vci, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg);
72 virtual void canNotFindInstCandVer(VersionContainerInterface * const vci, pkgCacheFile &Cache,
73 pkgCache::PkgIterator const &Pkg);
74 virtual void canNotFindCandInstVer(VersionContainerInterface * const vci,
75 pkgCacheFile &Cache,
76 pkgCache::PkgIterator const &Pkg);
77
78 virtual pkgCache::PkgIterator canNotFindPkgName(pkgCacheFile &Cache, std::string const &str);
79 virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache,
80 pkgCache::PkgIterator const &Pkg);
81 virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache,
82 pkgCache::PkgIterator const &Pkg);
83 virtual pkgCache::VerIterator canNotFindInstalledVer(pkgCacheFile &Cache,
84 pkgCache::PkgIterator const &Pkg);
85
86 bool showErrors() const { return ShowError; }
87 bool showErrors(bool const newValue) { if (ShowError == newValue) return ShowError; else return ((ShowError = newValue) == false); }
88 GlobalError::MsgType errorType() const { return ErrorType; }
89 GlobalError::MsgType errorType(GlobalError::MsgType const &newValue)
90 {
91 if (ErrorType == newValue) return ErrorType;
92 else {
93 GlobalError::MsgType const &oldValue = ErrorType;
94 ErrorType = newValue;
95 return oldValue;
96 }
97 }
98
99 /*}}}*/
100protected:
101 bool ShowError;
102 GlobalError::MsgType ErrorType;
103}; /*}}}*/
104
105class PackageContainerInterface { /*{{{*/
106/** \class PackageContainerInterface
107
108 * Interface ensuring that all operations can be executed on the yet to
109 * define concrete PackageContainer - access to all methods is possible,
110 * but in general the wrappers provided by the PackageContainer template
111 * are nicer to use.
112
113 * This class mostly protects use from the need to write all implementation
114 * of the methods working on containers in the template */
115public:
116 class const_iterator { /*{{{*/
117 public:
118 virtual pkgCache::PkgIterator getPkg() const = 0;
119 operator pkgCache::PkgIterator(void) const { return getPkg(); }
120
121 inline const char *Name() const {return getPkg().Name(); }
122 inline std::string FullName(bool const Pretty) const { return getPkg().FullName(Pretty); }
123 inline std::string FullName() const { return getPkg().FullName(); }
124 APT_DEPRECATED inline const char *Section() const {
125#if __GNUC__ >= 4
126 #pragma GCC diagnostic push
127 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
128#endif
129 return getPkg().Section();
130#if __GNUC__ >= 4
131 #pragma GCC diagnostic pop
132#endif
133 }
134 inline bool Purge() const {return getPkg().Purge(); }
135 inline const char *Arch() const {return getPkg().Arch(); }
136 inline pkgCache::GrpIterator Group() const { return getPkg().Group(); }
137 inline pkgCache::VerIterator VersionList() const { return getPkg().VersionList(); }
138 inline pkgCache::VerIterator CurrentVer() const { return getPkg().CurrentVer(); }
139 inline pkgCache::DepIterator RevDependsList() const { return getPkg().RevDependsList(); }
140 inline pkgCache::PrvIterator ProvidesList() const { return getPkg().ProvidesList(); }
141 inline pkgCache::PkgIterator::OkState State() const { return getPkg().State(); }
142 inline const char *CandVersion() const { return getPkg().CandVersion(); }
143 inline const char *CurVersion() const { return getPkg().CurVersion(); }
144 inline pkgCache *Cache() const { return getPkg().Cache(); }
145 inline unsigned long Index() const {return getPkg().Index();}
146 // we have only valid iterators here
147 inline bool end() const { return false; }
148
149 inline pkgCache::Package const * operator->() const {return &*getPkg();}
150 };
151 /*}}}*/
152
153 virtual bool insert(pkgCache::PkgIterator const &P) = 0;
154 virtual bool empty() const = 0;
155 virtual void clear() = 0;
156
157 enum Constructor { UNKNOWN, REGEX, TASK, FNMATCH };
158 virtual void setConstructor(Constructor const &con) = 0;
159 virtual Constructor getConstructor() const = 0;
160
161 static bool FromTask(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
162 static bool FromRegEx(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
163 static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper);
164 static bool FromFnmatch(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
165 static bool FromGroup(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
166 static bool FromString(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper);
167 static bool FromCommandLine(PackageContainerInterface * const pci, pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper);
168
169 struct Modifier {
170 enum Position { NONE, PREFIX, POSTFIX };
171 unsigned short ID;
172 const char * const Alias;
173 Position Pos;
174 Modifier (unsigned short const &id, const char * const alias, Position const &pos) : ID(id), Alias(alias), Pos(pos) {}
175 };
176
177 static bool FromModifierCommandLine(unsigned short &modID, PackageContainerInterface * const pci,
178 pkgCacheFile &Cache, const char * cmdline,
179 std::list<Modifier> const &mods, CacheSetHelper &helper);
180};
181 /*}}}*/
182template<class Container> class PackageContainer : public PackageContainerInterface {/*{{{*/
183/** \class APT::PackageContainer
184
185 Simple wrapper around a container class like std::set to provide a similar
186 interface to a set of packages as to the complete set of all packages in the
187 pkgCache. */
188 Container _cont;
189public: /*{{{*/
190 /** \brief smell like a pkgCache::PkgIterator */
191 class const_iterator : public PackageContainerInterface::const_iterator,/*{{{*/
192 public std::iterator<std::forward_iterator_tag, typename Container::const_iterator> {
193 typename Container::const_iterator _iter;
194 public:
195 const_iterator(typename Container::const_iterator i) : _iter(i) {}
196 pkgCache::PkgIterator getPkg(void) const { return *_iter; }
197 inline pkgCache::PkgIterator operator*(void) const { return *_iter; }
198 operator typename Container::const_iterator(void) const { return _iter; }
199 inline const_iterator& operator++() { ++_iter; return *this; }
200 inline const_iterator operator++(int) { const_iterator tmp(*this); operator++(); return tmp; }
201 inline bool operator!=(const_iterator const &i) const { return _iter != i._iter; }
202 inline bool operator==(const_iterator const &i) const { return _iter == i._iter; }
203 friend std::ostream& operator<<(std::ostream& out, const_iterator i) { return operator<<(out, *i); }
204 };
205 class iterator : public PackageContainerInterface::const_iterator,
206 public std::iterator<std::forward_iterator_tag, typename Container::iterator> {
207 typename Container::iterator _iter;
208 public:
209 iterator(typename Container::iterator i) : _iter(i) {}
210 pkgCache::PkgIterator getPkg(void) const { return *_iter; }
211 inline pkgCache::PkgIterator operator*(void) const { return *_iter; }
212 operator typename Container::iterator(void) const { return _iter; }
213 operator typename PackageContainer<Container>::const_iterator() { return typename PackageContainer<Container>::const_iterator(_iter); }
214 inline iterator& operator++() { ++_iter; return *this; }
215 inline iterator operator++(int) { iterator tmp(*this); operator++(); return tmp; }
216 inline bool operator!=(iterator const &i) const { return _iter != i._iter; }
217 inline bool operator==(iterator const &i) const { return _iter == i._iter; }
218 inline iterator& operator=(iterator const &i) { _iter = i._iter; return *this; }
219 inline iterator& operator=(typename Container::iterator const &i) { _iter = i; return *this; }
220 friend std::ostream& operator<<(std::ostream& out, iterator i) { return operator<<(out, *i); }
221 };
222 /*}}}*/
223
224 bool insert(pkgCache::PkgIterator const &P) { if (P.end() == true) return false; _cont.insert(P); return true; }
225 template<class Cont> void insert(PackageContainer<Cont> const &pkgcont) { _cont.insert((typename Cont::const_iterator)pkgcont.begin(), (typename Cont::const_iterator)pkgcont.end()); }
226 void insert(const_iterator begin, const_iterator end) { _cont.insert(begin, end); }
227
228 bool empty() const { return _cont.empty(); }
229 void clear() { return _cont.clear(); }
230 //FIXME: on ABI break, replace the first with the second without bool
231 void erase(iterator position) { _cont.erase((typename Container::iterator)position); }
232 iterator& erase(iterator &position, bool) { return position = _cont.erase((typename Container::iterator)position); }
233 size_t erase(const pkgCache::PkgIterator x) { return _cont.erase(x); }
234 void erase(iterator first, iterator last) { _cont.erase(first, last); }
235 size_t size() const { return _cont.size(); }
236
237 const_iterator begin() const { return const_iterator(_cont.begin()); }
238 const_iterator end() const { return const_iterator(_cont.end()); }
239 iterator begin() { return iterator(_cont.begin()); }
240 iterator end() { return iterator(_cont.end()); }
241 const_iterator find(pkgCache::PkgIterator const &P) const { return const_iterator(_cont.find(P)); }
242
243 void setConstructor(Constructor const &by) { ConstructedBy = by; }
244 Constructor getConstructor() const { return ConstructedBy; }
245
246 PackageContainer() : ConstructedBy(UNKNOWN) {}
247 PackageContainer(Constructor const &by) : ConstructedBy(by) {}
248
249 /** \brief sort all included versions with given comparer
250
251 Some containers are sorted by default, some are not and can't be,
252 but a few like std::vector can be sorted if need be, so this can be
253 specialized in later on. The default is that this will fail though.
254 Specifically, already sorted containers like std::set will return
255 false as well as there is no easy way to check that the given comparer
256 would sort in the same way the set is currently sorted
257
258 \return \b true if the set was sorted, \b false if not. */
259 template<class Compare> bool sort(Compare /*Comp*/) { return false; }
260
261 /** \brief returns all packages in the cache who belong to the given task
262
263 A simple helper responsible for search for all members of a task
264 in the cache. Optional it prints a a notice about the
265 packages chosen cause of the given task.
266 \param Cache the packages are in
267 \param pattern name of the task
268 \param helper responsible for error and message handling */
269 static PackageContainer FromTask(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper) {
270 PackageContainer cont(TASK);
271 PackageContainerInterface::FromTask(&cont, Cache, pattern, helper);
272 return cont;
273 }
274 static PackageContainer FromTask(pkgCacheFile &Cache, std::string const &pattern) {
275 CacheSetHelper helper;
276 return FromTask(Cache, pattern, helper);
277 }
278
279 /** \brief returns all packages in the cache whose name matchs a given pattern
280
281 A simple helper responsible for executing a regular expression on all
282 package names in the cache. Optional it prints a a notice about the
283 packages chosen cause of the given package.
284 \param Cache the packages are in
285 \param pattern regular expression for package names
286 \param helper responsible for error and message handling */
287 static PackageContainer FromRegEx(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) {
288 PackageContainer cont(REGEX);
289 PackageContainerInterface::FromRegEx(&cont, Cache, pattern, helper);
290 return cont;
291 }
292
293 static PackageContainer FromRegEx(pkgCacheFile &Cache, std::string const &pattern) {
294 CacheSetHelper helper;
295 return FromRegEx(Cache, pattern, helper);
296 }
297
298 static PackageContainer FromFnmatch(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) {
299 PackageContainer cont(FNMATCH);
300 PackageContainerInterface::FromFnmatch(&cont, Cache, pattern, helper);
301 return cont;
302 }
303 static PackageContainer FromFnMatch(pkgCacheFile &Cache, std::string const &pattern) {
304 CacheSetHelper helper;
305 return FromFnmatch(Cache, pattern, helper);
306 }
307
308 /** \brief returns a package specified by a string
309
310 \param Cache the package is in
311 \param pattern String the package name should be extracted from
312 \param helper responsible for error and message handling */
313 static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper) {
314 return PackageContainerInterface::FromName(Cache, pattern, helper);
315 }
316 static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &pattern) {
317 CacheSetHelper helper;
318 return PackageContainerInterface::FromName(Cache, pattern, helper);
319 }
320
321 /** \brief returns all packages specified by a string
322
323 \param Cache the packages are in
324 \param pattern String the package name(s) should be extracted from
325 \param helper responsible for error and message handling */
326 static PackageContainer FromString(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper) {
327 PackageContainer cont;
328 PackageContainerInterface::FromString(&cont, Cache, pattern, helper);
329 return cont;
330 }
331 static PackageContainer FromString(pkgCacheFile &Cache, std::string const &pattern) {
332 CacheSetHelper helper;
333 return FromString(Cache, pattern, helper);
334 }
335
336 /** \brief returns all packages specified on the commandline
337
338 Get all package names from the commandline and executes regex's if needed.
339 No special package command is supported, just plain names.
340 \param Cache the packages are in
341 \param cmdline Command line the package names should be extracted from
342 \param helper responsible for error and message handling */
343 static PackageContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper) {
344 PackageContainer cont;
345 PackageContainerInterface::FromCommandLine(&cont, Cache, cmdline, helper);
346 return cont;
347 }
348 static PackageContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline) {
349 CacheSetHelper helper;
350 return FromCommandLine(Cache, cmdline, helper);
351 }
352
353 /** \brief group packages by a action modifiers
354
355 At some point it is needed to get from the same commandline
356 different package sets grouped by a modifier. Take
357 apt-get install apt awesome-
358 as an example.
359 \param Cache the packages are in
360 \param cmdline Command line the package names should be extracted from
361 \param mods list of modifiers the method should accept
362 \param fallback the default modifier group for a package
363 \param helper responsible for error and message handling */
364 static std::map<unsigned short, PackageContainer> GroupedFromCommandLine(
365 pkgCacheFile &Cache,
366 const char **cmdline,
367 std::list<Modifier> const &mods,
368 unsigned short const &fallback,
369 CacheSetHelper &helper) {
370 std::map<unsigned short, PackageContainer> pkgsets;
371 for (const char **I = cmdline; *I != 0; ++I) {
372 unsigned short modID = fallback;
373 PackageContainer pkgset;
374 PackageContainerInterface::FromModifierCommandLine(modID, &pkgset, Cache, *I, mods, helper);
375 pkgsets[modID].insert(pkgset);
376 }
377 return pkgsets;
378 }
379 static std::map<unsigned short, PackageContainer> GroupedFromCommandLine(
380 pkgCacheFile &Cache,
381 const char **cmdline,
382 std::list<Modifier> const &mods,
383 unsigned short const &fallback) {
384 CacheSetHelper helper;
385 return GroupedFromCommandLine(Cache, cmdline,
386 mods, fallback, helper);
387 }
388 /*}}}*/
389private: /*{{{*/
390 Constructor ConstructedBy;
391 /*}}}*/
392}; /*}}}*/
393// specialisations for push_back containers: std::list & std::vector /*{{{*/
394template<> template<class Cont> void PackageContainer<std::list<pkgCache::PkgIterator> >::insert(PackageContainer<Cont> const &pkgcont) {
395 for (typename PackageContainer<Cont>::const_iterator p = pkgcont.begin(); p != pkgcont.end(); ++p)
396 _cont.push_back(*p);
397}
398template<> template<class Cont> void PackageContainer<std::vector<pkgCache::PkgIterator> >::insert(PackageContainer<Cont> const &pkgcont) {
399 for (typename PackageContainer<Cont>::const_iterator p = pkgcont.begin(); p != pkgcont.end(); ++p)
400 _cont.push_back(*p);
401}
402// these two are 'inline' as otherwise the linker has problems with seeing these untemplated
403// specializations again and again - but we need to see them, so that library users can use them
404template<> inline bool PackageContainer<std::list<pkgCache::PkgIterator> >::insert(pkgCache::PkgIterator const &P) {
405 if (P.end() == true)
406 return false;
407 _cont.push_back(P);
408 return true;
409}
410template<> inline bool PackageContainer<std::vector<pkgCache::PkgIterator> >::insert(pkgCache::PkgIterator const &P) {
411 if (P.end() == true)
412 return false;
413 _cont.push_back(P);
414 return true;
415}
416template<> inline void PackageContainer<std::list<pkgCache::PkgIterator> >::insert(const_iterator begin, const_iterator end) {
417 for (const_iterator p = begin; p != end; ++p)
418 _cont.push_back(*p);
419}
420template<> inline void PackageContainer<std::vector<pkgCache::PkgIterator> >::insert(const_iterator begin, const_iterator end) {
421 for (const_iterator p = begin; p != end; ++p)
422 _cont.push_back(*p);
423}
424 /*}}}*/
425
426template<> template<class Compare> inline bool PackageContainer<std::vector<pkgCache::PkgIterator> >::sort(Compare Comp) {
427 std::sort(_cont.begin(), _cont.end(), Comp);
428 return true;
429}
430
431typedef PackageContainer<std::set<pkgCache::PkgIterator> > PackageSet;
432typedef PackageContainer<std::list<pkgCache::PkgIterator> > PackageList;
433typedef PackageContainer<std::vector<pkgCache::PkgIterator> > PackageVector;
434
435class VersionContainerInterface { /*{{{*/
436/** \class APT::VersionContainerInterface
437
438 Same as APT::PackageContainerInterface, just for Versions */
439public:
440 /** \brief smell like a pkgCache::VerIterator */
441 class const_iterator { /*{{{*/
442 public:
443 virtual pkgCache::VerIterator getVer() const = 0;
444 operator pkgCache::VerIterator(void) { return getVer(); }
445
446 inline pkgCache *Cache() const { return getVer().Cache(); }
447 inline unsigned long Index() const {return getVer().Index();}
448 inline int CompareVer(const pkgCache::VerIterator &B) const { return getVer().CompareVer(B); }
449 inline const char *VerStr() const { return getVer().VerStr(); }
450 inline const char *Section() const { return getVer().Section(); }
451 inline const char *Arch() const { return getVer().Arch(); }
452 inline pkgCache::PkgIterator ParentPkg() const { return getVer().ParentPkg(); }
453 inline pkgCache::DescIterator DescriptionList() const { return getVer().DescriptionList(); }
454 inline pkgCache::DescIterator TranslatedDescription() const { return getVer().TranslatedDescription(); }
455 inline pkgCache::DepIterator DependsList() const { return getVer().DependsList(); }
456 inline pkgCache::PrvIterator ProvidesList() const { return getVer().ProvidesList(); }
457 inline pkgCache::VerFileIterator FileList() const { return getVer().FileList(); }
458 inline bool Downloadable() const { return getVer().Downloadable(); }
459 inline const char *PriorityType() const { return getVer().PriorityType(); }
460 inline std::string RelStr() const { return getVer().RelStr(); }
461 inline bool Automatic() const { return getVer().Automatic(); }
462 inline pkgCache::VerFileIterator NewestFile() const { return getVer().NewestFile(); }
463 // we have only valid iterators here
464 inline bool end() const { return false; }
465
466 inline pkgCache::Version const * operator->() const { return &*getVer(); }
467 };
468 /*}}}*/
469
470 virtual bool insert(pkgCache::VerIterator const &V) = 0;
471 virtual bool empty() const = 0;
472 virtual void clear() = 0;
473
474 /** \brief specifies which version(s) will be returned if non is given */
475 enum Version {
476 /** All versions */
477 ALL,
478 /** Candidate and installed version */
479 CANDANDINST,
480 /** Candidate version */
481 CANDIDATE,
482 /** Installed version */
483 INSTALLED,
484 /** Candidate or if non installed version */
485 CANDINST,
486 /** Installed or if non candidate version */
487 INSTCAND,
488 /** Newest version */
489 NEWEST
490 };
491
492 struct Modifier {
493 enum Position { NONE, PREFIX, POSTFIX };
494 unsigned short ID;
495 const char * const Alias;
496 Position Pos;
497 Version SelectVersion;
498 Modifier (unsigned short const &id, const char * const alias, Position const &pos,
499 Version const &select) : ID(id), Alias(alias), Pos(pos),
500 SelectVersion(select) {}
501 };
502
503 static bool FromCommandLine(VersionContainerInterface * const vci, pkgCacheFile &Cache,
504 const char **cmdline, Version const &fallback,
505 CacheSetHelper &helper);
506
507 static bool FromString(VersionContainerInterface * const vci, pkgCacheFile &Cache,
508 std::string pkg, Version const &fallback, CacheSetHelper &helper,
509 bool const onlyFromName = false);
510
511 static bool FromPackage(VersionContainerInterface * const vci, pkgCacheFile &Cache,
512 pkgCache::PkgIterator const &P, Version const &fallback,
513 CacheSetHelper &helper);
514
515 static bool FromModifierCommandLine(unsigned short &modID,
516 VersionContainerInterface * const vci,
517 pkgCacheFile &Cache, const char * cmdline,
518 std::list<Modifier> const &mods,
519 CacheSetHelper &helper);
520
521
522 static bool FromDependency(VersionContainerInterface * const vci,
523 pkgCacheFile &Cache,
524 pkgCache::DepIterator const &D,
525 Version const &selector,
526 CacheSetHelper &helper);
527
528protected: /*{{{*/
529
530 /** \brief returns the candidate version of the package
531
532 \param Cache to be used to query for information
533 \param Pkg we want the candidate version from this package
534 \param helper used in this container instance */
535 static pkgCache::VerIterator getCandidateVer(pkgCacheFile &Cache,
536 pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper);
537
538 /** \brief returns the installed version of the package
539
540 \param Cache to be used to query for information
541 \param Pkg we want the installed version from this package
542 \param helper used in this container instance */
543 static pkgCache::VerIterator getInstalledVer(pkgCacheFile &Cache,
544 pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper);
545 /*}}}*/
546};
547 /*}}}*/
548template<class Container> class VersionContainer : public VersionContainerInterface {/*{{{*/
549/** \class APT::VersionContainer
550
551 Simple wrapper around a container class like std::set to provide a similar
552 interface to a set of versions as to the complete set of all versions in the
553 pkgCache. */
554 Container _cont;
555public: /*{{{*/
556 /** \brief smell like a pkgCache::VerIterator */
557 class const_iterator : public VersionContainerInterface::const_iterator,
558 public std::iterator<std::forward_iterator_tag, typename Container::const_iterator> {/*{{{*/
559 typename Container::const_iterator _iter;
560 public:
561 const_iterator(typename Container::const_iterator i) : _iter(i) {}
562 pkgCache::VerIterator getVer(void) const { return *_iter; }
563 inline pkgCache::VerIterator operator*(void) const { return *_iter; }
564 operator typename Container::const_iterator(void) const { return _iter; }
565 inline const_iterator& operator++() { ++_iter; return *this; }
566 inline const_iterator operator++(int) { const_iterator tmp(*this); operator++(); return tmp; }
567 inline bool operator!=(const_iterator const &i) const { return _iter != i._iter; }
568 inline bool operator==(const_iterator const &i) const { return _iter == i._iter; }
569 friend std::ostream& operator<<(std::ostream& out, const_iterator i) { return operator<<(out, *i); }
570 };
571 class iterator : public VersionContainerInterface::const_iterator,
572 public std::iterator<std::forward_iterator_tag, typename Container::iterator> {
573 typename Container::iterator _iter;
574 public:
575 iterator(typename Container::iterator i) : _iter(i) {}
576 pkgCache::VerIterator getVer(void) const { return *_iter; }
577 inline pkgCache::VerIterator operator*(void) const { return *_iter; }
578 operator typename Container::iterator(void) const { return _iter; }
579 operator typename VersionContainer<Container>::const_iterator() { return typename VersionContainer<Container>::const_iterator(_iter); }
580 inline iterator& operator++() { ++_iter; return *this; }
581 inline iterator operator++(int) { iterator tmp(*this); operator++(); return tmp; }
582 inline bool operator!=(iterator const &i) const { return _iter != i._iter; }
583 inline bool operator==(iterator const &i) const { return _iter == i._iter; }
584 inline iterator& operator=(iterator const &i) { _iter = i._iter; return *this; }
585 inline iterator& operator=(typename Container::iterator const &i) { _iter = i; return *this; }
586 friend std::ostream& operator<<(std::ostream& out, iterator i) { return operator<<(out, *i); }
587 };
588 /*}}}*/
589
590 bool insert(pkgCache::VerIterator const &V) { if (V.end() == true) return false; _cont.insert(V); return true; }
591 template<class Cont> void insert(VersionContainer<Cont> const &vercont) { _cont.insert((typename Cont::const_iterator)vercont.begin(), (typename Cont::const_iterator)vercont.end()); }
592 void insert(const_iterator begin, const_iterator end) { _cont.insert(begin, end); }
593 bool empty() const { return _cont.empty(); }
594 void clear() { return _cont.clear(); }
595 //FIXME: on ABI break, replace the first with the second without bool
596 void erase(iterator position) { _cont.erase((typename Container::iterator)position); }
597 iterator& erase(iterator &position, bool) { return position = _cont.erase((typename Container::iterator)position); }
598 size_t erase(const pkgCache::VerIterator x) { return _cont.erase(x); }
599 void erase(iterator first, iterator last) { _cont.erase(first, last); }
600 size_t size() const { return _cont.size(); }
601
602 const_iterator begin() const { return const_iterator(_cont.begin()); }
603 const_iterator end() const { return const_iterator(_cont.end()); }
604 iterator begin() { return iterator(_cont.begin()); }
605 iterator end() { return iterator(_cont.end()); }
606 const_iterator find(pkgCache::VerIterator const &V) const { return const_iterator(_cont.find(V)); }
607
608 /** \brief sort all included versions with given comparer
609
610 Some containers are sorted by default, some are not and can't be,
611 but a few like std::vector can be sorted if need be, so this can be
612 specialized in later on. The default is that this will fail though.
613 Specifically, already sorted containers like std::set will return
614 false as well as there is no easy way to check that the given comparer
615 would sort in the same way the set is currently sorted
616
617 \return \b true if the set was sorted, \b false if not. */
618 template<class Compare> bool sort(Compare /*Comp*/) { return false; }
619
620 /** \brief returns all versions specified on the commandline
621
622 Get all versions from the commandline, uses given default version if
623 non specifically requested and executes regex's if needed on names.
624 \param Cache the packages and versions are in
625 \param cmdline Command line the versions should be extracted from
626 \param fallback version specification
627 \param helper responsible for error and message handling */
628 static VersionContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline,
629 Version const &fallback, CacheSetHelper &helper) {
630 VersionContainer vercon;
631 VersionContainerInterface::FromCommandLine(&vercon, Cache, cmdline, fallback, helper);
632 return vercon;
633 }
634 static VersionContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline,
635 Version const &fallback) {
636 CacheSetHelper helper;
637 return FromCommandLine(Cache, cmdline, fallback, helper);
638 }
639 static VersionContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline) {
640 return FromCommandLine(Cache, cmdline, CANDINST);
641 }
642
643 static VersionContainer FromString(pkgCacheFile &Cache, std::string const &pkg,
644 Version const &fallback, CacheSetHelper &helper,
645 bool const /*onlyFromName = false*/) {
646 VersionContainer vercon;
647 VersionContainerInterface::FromString(&vercon, Cache, pkg, fallback, helper);
648 return vercon;
649 }
650 static VersionContainer FromString(pkgCacheFile &Cache, std::string pkg,
651 Version const &fallback) {
652 CacheSetHelper helper;
653 return FromString(Cache, pkg, fallback, helper);
654 }
655 static VersionContainer FromString(pkgCacheFile &Cache, std::string pkg) {
656 return FromString(Cache, pkg, CANDINST);
657 }
658
659 /** \brief returns all versions specified for the package
660
661 \param Cache the package and versions are in
662 \param P the package in question
663 \param fallback the version(s) you want to get
664 \param helper the helper used for display and error handling */
665 static VersionContainer FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P,
666 Version const &fallback, CacheSetHelper &helper) {
667 VersionContainer vercon;
668 VersionContainerInterface::FromPackage(&vercon, Cache, P, fallback, helper);
669 return vercon;
670 }
671 static VersionContainer FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P,
672 Version const &fallback) {
673 CacheSetHelper helper;
674 return FromPackage(Cache, P, fallback, helper);
675 }
676 static VersionContainer FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P) {
677 return FromPackage(Cache, P, CANDIDATE);
678 }
679
680 static std::map<unsigned short, VersionContainer> GroupedFromCommandLine(
681 pkgCacheFile &Cache,
682 const char **cmdline,
683 std::list<Modifier> const &mods,
684 unsigned short const fallback,
685 CacheSetHelper &helper) {
686 std::map<unsigned short, VersionContainer> versets;
687 for (const char **I = cmdline; *I != 0; ++I) {
688 unsigned short modID = fallback;
689 VersionContainer verset;
690 VersionContainerInterface::FromModifierCommandLine(modID, &verset, Cache, *I, mods, helper);
691 versets[modID].insert(verset);
692 }
693 return versets;
694
695 }
696 static std::map<unsigned short, VersionContainer> GroupedFromCommandLine(
697 pkgCacheFile &Cache, const char **cmdline,
698 std::list<Modifier> const &mods,
699 unsigned short const fallback) {
700 CacheSetHelper helper;
701 return GroupedFromCommandLine(Cache, cmdline,
702 mods, fallback, helper);
703 }
704
705 static VersionContainer FromDependency(pkgCacheFile &Cache, pkgCache::DepIterator const &D,
706 Version const &selector, CacheSetHelper &helper) {
707 VersionContainer vercon;
708 VersionContainerInterface::FromDependency(&vercon, Cache, D, selector, helper);
709 return vercon;
710 }
711 static VersionContainer FromDependency(pkgCacheFile &Cache, pkgCache::DepIterator const &D,
712 Version const &selector) {
713 CacheSetHelper helper;
714 return FromPackage(Cache, D, selector, helper);
715 }
716 static VersionContainer FromDependency(pkgCacheFile &Cache, pkgCache::DepIterator const &D) {
717 return FromPackage(Cache, D, CANDIDATE);
718 }
719 /*}}}*/
720}; /*}}}*/
721// specialisations for push_back containers: std::list & std::vector /*{{{*/
722template<> template<class Cont> void VersionContainer<std::list<pkgCache::VerIterator> >::insert(VersionContainer<Cont> const &vercont) {
723 for (typename VersionContainer<Cont>::const_iterator v = vercont.begin(); v != vercont.end(); ++v)
724 _cont.push_back(*v);
725}
726template<> template<class Cont> void VersionContainer<std::vector<pkgCache::VerIterator> >::insert(VersionContainer<Cont> const &vercont) {
727 for (typename VersionContainer<Cont>::const_iterator v = vercont.begin(); v != vercont.end(); ++v)
728 _cont.push_back(*v);
729}
730// these two are 'inline' as otherwise the linker has problems with seeing these untemplated
731// specializations again and again - but we need to see them, so that library users can use them
732template<> inline bool VersionContainer<std::list<pkgCache::VerIterator> >::insert(pkgCache::VerIterator const &V) {
733 if (V.end() == true)
734 return false;
735 _cont.push_back(V);
736 return true;
737}
738template<> inline bool VersionContainer<std::vector<pkgCache::VerIterator> >::insert(pkgCache::VerIterator const &V) {
739 if (V.end() == true)
740 return false;
741 _cont.push_back(V);
742 return true;
743}
744template<> inline void VersionContainer<std::list<pkgCache::VerIterator> >::insert(const_iterator begin, const_iterator end) {
745 for (const_iterator v = begin; v != end; ++v)
746 _cont.push_back(*v);
747}
748template<> inline void VersionContainer<std::vector<pkgCache::VerIterator> >::insert(const_iterator begin, const_iterator end) {
749 for (const_iterator v = begin; v != end; ++v)
750 _cont.push_back(*v);
751}
752 /*}}}*/
753
754template<> template<class Compare> inline bool VersionContainer<std::vector<pkgCache::VerIterator> >::sort(Compare Comp) {
755 std::sort(_cont.begin(), _cont.end(), Comp);
756 return true;
757}
758
759typedef VersionContainer<std::set<pkgCache::VerIterator> > VersionSet;
760typedef VersionContainer<std::list<pkgCache::VerIterator> > VersionList;
761typedef VersionContainer<std::vector<pkgCache::VerIterator> > VersionVector;
762}
763#endif