forked from bretternst/tcpppl_answers
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ex13.cpp
137 lines (119 loc) · 4.02 KB
/
ex13.cpp
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
#include <iostream>
namespace ch16
{
// This exercise is really starting to lose me. I'm going to implement only "common" functionality
// for "standard containers" which means mainly just a begin() and end() accessor for iterators.
// The goal is to have the same loop process both kinds of vectors to print out its elements.
// I don't even support [] because that is not an operation common to all "standard containers."
class Object {};
class Container : public Object
{
public:
struct Bad_op
{
const char* p;
Bad_op(const char* pp) : p(pp) {}
};
virtual Object* get() { throw Bad_op("get"); }
virtual void put(Object*) { throw Bad_op("put"); }
virtual Object*& operator[](size_t) { throw Bad_op("[]"); }
};
class Vector_16_2_2 : public Container
{
static const int DefaultCapacity = 16;
size_t sz;
size_t capacity;
Object** elements;
public:
explicit Vector_16_2_2() : sz(0), capacity(DefaultCapacity), elements(new Object*[DefaultCapacity]) {}
~Vector_16_2_2() { delete[] elements; }
Object* get() { return sz > 0 ? elements[--sz] : 0; }
void put(Object* o);
int size() { return sz; }
Object*& operator[](int idx) { return elements[idx]; }
};
void Vector_16_2_2::put(Object* o)
{
if(sz == capacity)
{
capacity *= 2;
Object** newArr = new Object*[capacity];
for(size_t i = 0; i < sz; i++) newArr[i] = elements[i];
delete[] elements;
elements = newArr;
}
elements[sz++] = o;
}
template<class T> class Vector_16_2_1
{
T* elements;
size_t sz;
public:
explicit Vector_16_2_1(size_t n) : sz(n), elements(new T[n]) {}
~Vector_16_2_1() { delete[] elements; }
T& operator[](size_t i) { return elements[i]; }
size_t size() { return sz; }
};
template<class T> class Vector_16_2_1_wrapper
{
Vector_16_2_1<T>& v;
public:
typedef T* iterator;
Vector_16_2_1_wrapper(Vector_16_2_1<T>& v) : v(v) {}
iterator begin() { return &v[0]; }
iterator end() { return &v[v.size()]; }
};
template<class T> class Vector_16_2_2_wrapper
{
Vector_16_2_2& v;
public:
class Holder : public Object
{
T x;
public:
Holder(T x) : x(x) {}
T& value() { return x; }
};
class Itor
{
Vector_16_2_2& v;
int i;
public:
Itor(Vector_16_2_2& v, int i) : v(v), i(i) {}
bool operator==(Itor& x) { return x.i == i; }
bool operator!=(Itor& x) { return !(x==*this); }
Itor& operator++(int) { i++; return *this; }
Itor& operator--(int) { i--; return *this; }
T& operator*() { Object* o = v[i]; Holder* h = static_cast<Holder*>(o); return h->value(); }
};
typedef Itor iterator;
Vector_16_2_2_wrapper(Vector_16_2_2& v) : v(v) {}
Itor begin() { return Itor(v, 0); }
Itor end() { return Itor(v, v.size()); }
};
}
int main()
{
using namespace ch16;
using namespace std;
Vector_16_2_1<int> v(3);
v[0] = 1;
v[1] = 2;
v[2] = 3;
Vector_16_2_1_wrapper<int> vw(v);
for(Vector_16_2_1_wrapper<int>::iterator i = vw.begin(); i != vw.end(); i++)
{
cout << *i << endl;
}
Vector_16_2_2 v2;
v2.put(new Vector_16_2_2_wrapper<int>::Holder(1));
v2.put(new Vector_16_2_2_wrapper<int>::Holder(2));
v2.put(new Vector_16_2_2_wrapper<int>::Holder(3));
Vector_16_2_2_wrapper<int> vw2(v2);
Vector_16_2_2_wrapper<int>::iterator end = vw2.end();
for(Vector_16_2_2_wrapper<int>::iterator i = vw2.begin(); i != end; i++)
{
cout << *i << endl;
}
return 0;
}