]> git.saurik.com Git - apt.git/blame - apt-pkg/cacheset.h
add specialisations for std::vector
[apt.git] / apt-pkg / cacheset.h
CommitLineData
e1dbde8d
DK
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
7959c5ed
DK
3/** \file cacheset.h
4 Wrappers around std::set to have set::iterators which behave
5 similar to the Iterators of the cache structures.
e1dbde8d 6
7959c5ed 7 Provides also a few helper methods which work with these sets */
e1dbde8d 8 /*}}}*/
7959c5ed
DK
9#ifndef APT_CACHESET_H
10#define APT_CACHESET_H
e1dbde8d 11// Include Files /*{{{*/
ffee1c2b 12#include <fstream>
9cc83a6f 13#include <map>
ffee1c2b 14#include <set>
c4cca791 15#include <list>
5c8c7321 16#include <vector>
e1dbde8d 17#include <string>
15fc8636 18#include <iterator>
5c8c7321 19#include <algorithm>
ffee1c2b 20
453b82a3
DK
21#include <stddef.h>
22
472ff00e 23#include <apt-pkg/error.h>
e1dbde8d 24#include <apt-pkg/pkgcache.h>
453b82a3 25#include <apt-pkg/cacheiterators.h>
b9dadc24
DK
26
27#ifndef APT_8_CLEANER_HEADERS
28#include <apt-pkg/cachefile.h>
453b82a3
DK
29#endif
30#ifndef APT_10_CLEANER_HEADERS
31#include <iostream>
b9dadc24 32#endif
e1dbde8d 33 /*}}}*/
472ff00e
DK
34
35class pkgCacheFile;
36
e1dbde8d 37namespace APT {
15fc8636
DK
38class PackageContainerInterface;
39class VersionContainerInterface;
40
70e706ad
DK
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: /*{{{*/
15fc8636 51 CacheSetHelper(bool const ShowError = true,
cd7bbc47 52 GlobalError::MsgType ErrorType = GlobalError::ERROR) :
d3e8fbb3
DK
53 ShowError(ShowError), ErrorType(ErrorType) {}
54 virtual ~CacheSetHelper() {}
70e706ad 55
15fc8636
DK
56 virtual void showTaskSelection(pkgCache::PkgIterator const &pkg, std::string const &pattern);
57 virtual void showRegExSelection(pkgCache::PkgIterator const &pkg, std::string const &pattern);
16724b66
MV
58#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
59 virtual void showFnmatchSelection(pkgCache::PkgIterator const &pkg, std::string const &pattern);
60#endif
70e706ad 61 virtual void showSelectedVersion(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const Ver,
15fc8636 62 std::string const &ver, bool const verIsRel);
70e706ad 63
15fc8636
DK
64 virtual void canNotFindTask(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern);
65 virtual void canNotFindRegEx(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern);
16724b66
MV
66#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
67 virtual void canNotFindFnmatch(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern);
68#endif
15fc8636
DK
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,
70e706ad 73 pkgCache::PkgIterator const &Pkg);
15fc8636
DK
74 virtual void canNotFindCandInstVer(VersionContainerInterface * const vci,
75 pkgCacheFile &Cache,
cf28bcad 76 pkgCache::PkgIterator const &Pkg);
15fc8636
DK
77
78 virtual pkgCache::PkgIterator canNotFindPkgName(pkgCacheFile &Cache, std::string const &str);
70e706ad
DK
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
d3e8fbb3
DK
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; }
cd7bbc47
DK
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 }
d3e8fbb3 97 }
cd7bbc47 98
70e706ad
DK
99 /*}}}*/
100protected:
101 bool ShowError;
cd7bbc47 102 GlobalError::MsgType ErrorType;
70e706ad 103}; /*}}}*/
5c8c7321 104
15fc8636
DK
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 { /*{{{*/
e1dbde8d 117 public:
15fc8636
DK
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(); }
7a669774
DK
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 }
15fc8636
DK
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(); }
d3e8fbb3
DK
144 inline pkgCache *Cache() const { return getPkg().Cache(); }
145 inline unsigned long Index() const {return getPkg().Index();}
78c32596 146 // we have only valid iterators here
d3e8fbb3 147 inline bool end() const { return false; }
e1dbde8d 148
d3e8fbb3 149 inline pkgCache::Package const * operator->() const {return &*getPkg();}
15fc8636
DK
150 };
151 /*}}}*/
152
153 virtual bool insert(pkgCache::PkgIterator const &P) = 0;
154 virtual bool empty() const = 0;
155 virtual void clear() = 0;
156
b9179170 157 enum Constructor { UNKNOWN, REGEX, TASK, FNMATCH };
15fc8636
DK
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);
b9179170 164 static bool FromFnmatch(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
2f0d4029 165 static bool FromGroup(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
15fc8636
DK
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;
d3e8fbb3 174 Modifier (unsigned short const &id, const char * const alias, Position const &pos) : ID(id), Alias(alias), Pos(pos) {}
15fc8636
DK
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
e1dbde8d 184
15fc8636
DK
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 */
c4cca791
DK
191 class const_iterator : public PackageContainerInterface::const_iterator,/*{{{*/
192 public std::iterator<std::forward_iterator_tag, typename Container::const_iterator> {
15fc8636
DK
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; }
d3e8fbb3 197 inline pkgCache::PkgIterator operator*(void) const { return *_iter; }
15fc8636 198 operator typename Container::const_iterator(void) const { return _iter; }
63b70b21
DK
199 inline const_iterator& operator++() { ++_iter; return *this; }
200 inline const_iterator operator++(int) { const_iterator tmp(*this); operator++(); return tmp; }
d3e8fbb3
DK
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; }
15fc8636 203 friend std::ostream& operator<<(std::ostream& out, const_iterator i) { return operator<<(out, *i); }
e1dbde8d 204 };
c4cca791
DK
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; }
d3e8fbb3 211 inline pkgCache::PkgIterator operator*(void) const { return *_iter; }
c4cca791 212 operator typename Container::iterator(void) const { return _iter; }
bce0e0ff 213 operator typename PackageContainer<Container>::const_iterator() { return typename PackageContainer<Container>::const_iterator(_iter); }
63b70b21
DK
214 inline iterator& operator++() { ++_iter; return *this; }
215 inline iterator operator++(int) { iterator tmp(*this); operator++(); return tmp; }
d3e8fbb3
DK
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; }
c4cca791
DK
220 friend std::ostream& operator<<(std::ostream& out, iterator i) { return operator<<(out, *i); }
221 };
dc0f01f7 222 /*}}}*/
ffee1c2b 223
d3e8fbb3
DK
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); }
c4cca791 227
d3e8fbb3
DK
228 bool empty() const { return _cont.empty(); }
229 void clear() { return _cont.clear(); }
5eb9a474 230 //FIXME: on ABI break, replace the first with the second without bool
d3e8fbb3
DK
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(); }
15fc8636 236
d3e8fbb3
DK
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)); }
15fc8636 242
d3e8fbb3
DK
243 void setConstructor(Constructor const &by) { ConstructedBy = by; }
244 Constructor getConstructor() const { return ConstructedBy; }
15fc8636 245
d3e8fbb3
DK
246 PackageContainer() : ConstructedBy(UNKNOWN) {}
247 PackageContainer(Constructor const &by) : ConstructedBy(by) {}
c45f2d19 248
5c8c7321
DK
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
dc0f01f7
DK
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
c8db3fff 268 \param helper responsible for error and message handling */
15fc8636
DK
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) {
70e706ad 275 CacheSetHelper helper;
446bbcf4 276 return FromTask(Cache, pattern, helper);
dc0f01f7
DK
277 }
278
ffee1c2b
DK
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
c8db3fff 286 \param helper responsible for error and message handling */
15fc8636
DK
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) {
70e706ad 294 CacheSetHelper helper;
446bbcf4 295 return FromRegEx(Cache, pattern, helper);
ffee1c2b
DK
296 }
297
b9179170
MV
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
15fc8636 308 /** \brief returns a package specified by a string
856d3b06 309
15fc8636
DK
310 \param Cache the package is in
311 \param pattern String the package name should be extracted from
c8db3fff 312 \param helper responsible for error and message handling */
15fc8636
DK
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) {
70e706ad 317 CacheSetHelper helper;
15fc8636 318 return PackageContainerInterface::FromName(Cache, pattern, helper);
856d3b06
DK
319 }
320
15fc8636 321 /** \brief returns all packages specified by a string
bd631595 322
15fc8636
DK
323 \param Cache the packages are in
324 \param pattern String the package name(s) should be extracted from
c8db3fff 325 \param helper responsible for error and message handling */
15fc8636
DK
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) {
bd631595 332 CacheSetHelper helper;
15fc8636 333 return FromString(Cache, pattern, helper);
bd631595
DK
334 }
335
78c32596
DK
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
c8db3fff 342 \param helper responsible for error and message handling */
15fc8636
DK
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) {
70e706ad 349 CacheSetHelper helper;
446bbcf4 350 return FromCommandLine(Cache, cmdline, helper);
78c32596 351 }
9cc83a6f 352
c8db3fff
DK
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 */
15fc8636
DK
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) {
70e706ad 384 CacheSetHelper helper;
446bbcf4 385 return GroupedFromCommandLine(Cache, cmdline,
70e706ad 386 mods, fallback, helper);
9cc83a6f 387 }
c8db3fff
DK
388 /*}}}*/
389private: /*{{{*/
390 Constructor ConstructedBy;
d4489d49
DK
391 /*}}}*/
392}; /*}}}*/
5c8c7321 393// specialisations for push_back containers: std::list & std::vector /*{{{*/
c4cca791
DK
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);
d3e8fbb3 397}
5c8c7321
DK
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}
c4cca791
DK
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;
d3e8fbb3 409}
5c8c7321
DK
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}
c4cca791
DK
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);
d3e8fbb3 419}
5c8c7321
DK
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
15fc8636 431typedef PackageContainer<std::set<pkgCache::PkgIterator> > PackageSet;
c4cca791 432typedef PackageContainer<std::list<pkgCache::PkgIterator> > PackageList;
5c8c7321 433typedef PackageContainer<std::vector<pkgCache::PkgIterator> > PackageVector;
78c32596 434
15fc8636
DK
435class VersionContainerInterface { /*{{{*/
436/** \class APT::VersionContainerInterface
437
438 Same as APT::PackageContainerInterface, just for Versions */
439public:
d4489d49 440 /** \brief smell like a pkgCache::VerIterator */
15fc8636 441 class const_iterator { /*{{{*/
d4489d49 442 public:
15fc8636
DK
443 virtual pkgCache::VerIterator getVer() const = 0;
444 operator pkgCache::VerIterator(void) { return getVer(); }
445
d3e8fbb3
DK
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(); }
d4489d49 463 // we have only valid iterators here
d3e8fbb3 464 inline bool end() const { return false; }
d4489d49 465
d3e8fbb3 466 inline pkgCache::Version const * operator->() const { return &*getVer(); }
d4489d49 467 };
dc0f01f7 468 /*}}}*/
78c32596 469
15fc8636
DK
470 virtual bool insert(pkgCache::VerIterator const &V) = 0;
471 virtual bool empty() const = 0;
472 virtual void clear() = 0;
c45f2d19 473
856d3b06
DK
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
15fc8636
DK
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),
d3e8fbb3 500 SelectVersion(select) {}
15fc8636
DK
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
c4cca791
DK
521
522 static bool FromDependency(VersionContainerInterface * const vci,
523 pkgCacheFile &Cache,
524 pkgCache::DepIterator const &D,
525 Version const &selector,
526 CacheSetHelper &helper);
527
15fc8636
DK
528protected: /*{{{*/
529
530 /** \brief returns the candidate version of the package
531
532 \param Cache to be used to query for information
255c9e4b
DK
533 \param Pkg we want the candidate version from this package
534 \param helper used in this container instance */
15fc8636
DK
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
255c9e4b
DK
541 \param Pkg we want the installed version from this package
542 \param helper used in this container instance */
15fc8636
DK
543 static pkgCache::VerIterator getInstalledVer(pkgCacheFile &Cache,
544 pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper);
545 /*}}}*/
546};
547 /*}}}*/
548template<class Container> class VersionContainer : public VersionContainerInterface {/*{{{*/
c4cca791 549/** \class APT::VersionContainer
15fc8636
DK
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; }
d3e8fbb3 563 inline pkgCache::VerIterator operator*(void) const { return *_iter; }
15fc8636 564 operator typename Container::const_iterator(void) const { return _iter; }
63b70b21
DK
565 inline const_iterator& operator++() { ++_iter; return *this; }
566 inline const_iterator operator++(int) { const_iterator tmp(*this); operator++(); return tmp; }
d3e8fbb3
DK
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; }
15fc8636
DK
569 friend std::ostream& operator<<(std::ostream& out, const_iterator i) { return operator<<(out, *i); }
570 };
c4cca791
DK
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; }
d3e8fbb3 577 inline pkgCache::VerIterator operator*(void) const { return *_iter; }
c4cca791 578 operator typename Container::iterator(void) const { return _iter; }
bce0e0ff 579 operator typename VersionContainer<Container>::const_iterator() { return typename VersionContainer<Container>::const_iterator(_iter); }
63b70b21
DK
580 inline iterator& operator++() { ++_iter; return *this; }
581 inline iterator operator++(int) { iterator tmp(*this); operator++(); return tmp; }
d3e8fbb3
DK
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; }
c4cca791
DK
586 friend std::ostream& operator<<(std::ostream& out, iterator i) { return operator<<(out, *i); }
587 };
15fc8636
DK
588 /*}}}*/
589
d3e8fbb3
DK
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(); }
5eb9a474 595 //FIXME: on ABI break, replace the first with the second without bool
d3e8fbb3
DK
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)); }
15fc8636 607
5c8c7321
DK
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
856d3b06
DK
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
255c9e4b 626 \param fallback version specification
c8db3fff 627 \param helper responsible for error and message handling */
15fc8636
DK
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) {
70e706ad 636 CacheSetHelper helper;
446bbcf4 637 return FromCommandLine(Cache, cmdline, fallback, helper);
856d3b06 638 }
15fc8636 639 static VersionContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline) {
446bbcf4 640 return FromCommandLine(Cache, cmdline, CANDINST);
856d3b06 641 }
55c59998 642
15fc8636
DK
643 static VersionContainer FromString(pkgCacheFile &Cache, std::string const &pkg,
644 Version const &fallback, CacheSetHelper &helper,
80624be7 645 bool const /*onlyFromName = false*/) {
15fc8636
DK
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) {
70e706ad 652 CacheSetHelper helper;
446bbcf4 653 return FromString(Cache, pkg, fallback, helper);
55c59998 654 }
15fc8636 655 static VersionContainer FromString(pkgCacheFile &Cache, std::string pkg) {
446bbcf4 656 return FromString(Cache, pkg, CANDINST);
55c59998
DK
657 }
658
fb83c1d0
DK
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 */
15fc8636
DK
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) {
c8db3fff 673 CacheSetHelper helper;
446bbcf4 674 return FromPackage(Cache, P, fallback, helper);
c8db3fff 675 }
15fc8636 676 static VersionContainer FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P) {
c4cca791 677 return FromPackage(Cache, P, CANDIDATE);
c8db3fff 678 }
fb83c1d0 679
15fc8636
DK
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;
55c59998 694
15fc8636
DK
695 }
696 static std::map<unsigned short, VersionContainer> GroupedFromCommandLine(
55c59998 697 pkgCacheFile &Cache, const char **cmdline,
15fc8636
DK
698 std::list<Modifier> const &mods,
699 unsigned short const fallback) {
70e706ad 700 CacheSetHelper helper;
446bbcf4 701 return GroupedFromCommandLine(Cache, cmdline,
70e706ad 702 mods, fallback, helper);
55c59998 703 }
c4cca791
DK
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 }
856d3b06 719 /*}}}*/
d4489d49 720}; /*}}}*/
5c8c7321 721// specialisations for push_back containers: std::list & std::vector /*{{{*/
c4cca791
DK
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);
d3e8fbb3 725}
5c8c7321
DK
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}
c4cca791
DK
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;
d3e8fbb3 737}
5c8c7321
DK
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}
c4cca791
DK
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);
d3e8fbb3 747}
5c8c7321
DK
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
15fc8636 759typedef VersionContainer<std::set<pkgCache::VerIterator> > VersionSet;
c4cca791 760typedef VersionContainer<std::list<pkgCache::VerIterator> > VersionList;
5c8c7321 761typedef VersionContainer<std::vector<pkgCache::VerIterator> > VersionVector;
e1dbde8d
DK
762}
763#endif