-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIterator.cpp
More file actions
149 lines (123 loc) · 3.32 KB
/
Copy pathIterator.cpp
File metadata and controls
149 lines (123 loc) · 3.32 KB
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/**
* Iterator Design Pattern
*
* Intent: Lets you traverse elements of a collection without exposing its
* underlying representation (list, stack, tree, etc.).
*/
#include <iostream>
#include <string>
#include <vector>
#include <memory>
/**
* C++ has its own implementation of iterator that works with a different
* generics containers defined by the standard library.
*/
template <typename T, typename U>
class Iterator {
public:
typedef typename std::vector<T>::iterator iter_type;
Iterator(U *p_data, bool reverse = false) : m_p_data_(p_data) {
std::cout << "Constructor Iterator" << std::endl;
m_it_ = m_p_data_->m_data_.begin();
}
~Iterator(){
std::cout << "Destructor Iterator" << std::endl;
}
void First() {
//std::cout << "First" << std::endl;
m_it_ = m_p_data_->m_data_.begin();
}
void Next() {
//std::cout << "Next" << std::endl;
m_it_++;
}
bool IsDone() {
//std::cout << "IsDone" << std::endl;
return (m_it_ == m_p_data_->m_data_.end());
}
iter_type Current() {
//std::cout << "Current" << std::endl;
return m_it_;
}
private:
U *m_p_data_;
iter_type m_it_;
};
/**
* Generic Collections/Containers provides one or several methods for retrieving
* fresh iterator instances, compatible with the collection class.
*/
template <class T>
class Container {
friend class Iterator<T, Container>;
public:
void Add(T a) {
//std::cout << "Add" << std::endl;
m_data_.push_back(a);
}
Iterator<T, Container> *CreateIterator() {
//std::cout << "CreateIterator" << std::endl;
return new Iterator<T, Container>(this);
}
Container(){
std::cout << "Constructor Container" << std::endl;
}
~Container(){
std::cout << "Destructor Container" << std::endl;
}
private:
std::vector<T> m_data_;
};
class Data {
public:
Data(int a = 0) : m_data_(a) {
std::cout << "Constructor Data" << std::endl;
}
~Data(){
std::cout << "Destructor Data" << std::endl;
}
void set_data(int a) {
std::cout << "set_data" << std::endl;
m_data_ = a;
}
int data() {
//std::cout << "data" << std::endl;
return m_data_;
}
private:
int m_data_;
};
/**
* The client code may or may not know about the Concrete Iterator or Collection
* classes, for this implementation the container is generic so you can used
* with an int or with a custom class.
*/
void ClientCode() {
std::cout << "________________Iterator with int______________________________________" << std::endl;
Container<int> cont;
for (int i = 0; i < 10; i++) {
cont.Add(i);
}
//Iterator<int, Container<int>> *it = cont.CreateIterator();
std::unique_ptr<Iterator<int, Container<int>>> it(cont.CreateIterator());
for (it->First(); !it->IsDone(); it->Next()) {
//std::cout << *it->Current() << std::endl;
}
Container<Data> cont2;
Data a(100), b(1000), c(10000);
cont2.Add(a);
cont2.Add(b);
cont2.Add(c);
std::cout << "________________Iterator with custom Class______________________________" << std::endl;
//Iterator<Data, Container<Data>> *it2 = cont2.CreateIterator();
std::unique_ptr<Iterator<Data, Container<Data>>> it2(cont2.CreateIterator());
for (it2->First(); !it2->IsDone(); it2->Next()) {
//std::cout << it2->Current()->data() << std::endl;
}
//delete it;
//delete it2;
}
int main() {
ClientCode();
return 0;
}