1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
/** \brief enumerator.h */ // -*-c++-*-
#ifndef ENUMERATOR_H
#define ENUMERATOR_H
#include <boost/shared_ptr.hpp>
namespace aptitude
{
namespace util
{
/** \brief Utility class to allow generic iteration over a list.
*
* Unlike an iterator, instantiations of this class can be used
* without the definition of the concrete object being visible to
* the user. Like Java and .NET iterators, these iterators start
* "before" the list being iterated over and must be advanced to
* the first entry.
*/
template<typename T>
class enumerator
{
public:
virtual ~enumerator() {}
typedef T value_type;
/** \brief Get the value at the current position. */
virtual T get_current() = 0;
/** \brief Advance to the next entry in the list.
*
* \return \b true if there was another entry, or \b false if we
* reached the end of the list.
*/
virtual bool advance() = 0;
};
/** \brief An enumerator over a range of STL iterators. */
template<typename ForwardIter>
class iterator_enumerator : public enumerator<typename ForwardIter::value_type>
{
ForwardIter begin, end;
bool first;
public:
iterator_enumerator(ForwardIter _begin, ForwardIter _end);
typename ForwardIter::value_type get_current();
bool advance();
};
template<typename ForwardIter>
iterator_enumerator<ForwardIter>::iterator_enumerator(ForwardIter _begin,
ForwardIter _end)
: begin(_begin), end(_end), first(true)
{
}
template<typename ForwardIter>
typename ForwardIter::value_type
iterator_enumerator<ForwardIter>::get_current()
{
return *begin;
}
template<typename ForwardIter>
bool iterator_enumerator<ForwardIter>::advance()
{
if(begin == end)
return false;
if(first)
first = false;
else
++begin;
return begin != end;
}
/** \brief An enumerator over an iterator range that holds a strong
* shared reference to an object (presumably the one containing the
* iterators).
*/
template<typename ForwardIter, typename T>
class iterator_enumerator_with_keepalive : public iterator_enumerator<ForwardIter>
{
boost::shared_ptr<T> keptalive;
public:
iterator_enumerator_with_keepalive(ForwardIter begin, ForwardIter end,
boost::shared_ptr<T> _keptalive);
};
template<typename ForwardIter, typename T>
iterator_enumerator_with_keepalive<ForwardIter, T>
::iterator_enumerator_with_keepalive(ForwardIter begin, ForwardIter end,
boost::shared_ptr<T> _keptalive)
: iterator_enumerator<ForwardIter>(begin, end),
keptalive(_keptalive)
{
}
}
}
#endif // ENUMERATOR_H
|