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
|
void StrVec::push_back(const string &s)
{
chk_n_alloc();
alloc.construct(first_free++, s);
}
pair<string *, string *>
StrVec::alloc_n_copy(const string *b, const string *e)
{
auto data = alloc.allocate(e - b);
return {data, uninitialized_copy(b, e, data)};
}
void StrVec::free()
{
if(elements)
{
for(auto p = first_free; p != elements;)
alloc.destroy(--p);
alloc.deallocate(elements, cap - elements);
}
/* for_each(elements, first_free, [this] (string &s) {alloc.destroy(&s);}); */
/* alloc.deallocate(elements, cap - elements); */
}
StrVec::StrVec(const StrVec &s)
{
auto newdata = alloc_n_copy(s.begin(), s.end());
elements = newdata.first;
first_free = cap = newdata.second;
}
StrVec::StrVec(StrVec &&s) noexcept: first_free(s.first_free), elements(s.elements), cap(s.cap)
{
s.first_free = nullptr;
s.elements = nullptr;
s.cap = nullptr;
}
StrVec::StrVec(const initializer_list<string> &is)
{
auto newdata = alloc_n_copy(is.begin(), is.end());
elements = newdata.first;
first_free = cap = newdata.second;
}
StrVec::~StrVec() {free();}
StrVec &StrVec::operator=(const StrVec &rhs)
{
auto data = alloc_n_copy(rhs.begin(), rhs.end());
free();
elements = data.first;
first_free = cap = data.second;
return *this;
}
string &StrVec::operator[](size_t n)
{
if(n >= size())
throw runtime_error("Out of range");
else
return *(elements + n);
}
const string &StrVec::operator[](size_t n) const
{
if(n >= size())
throw runtime_error("Out of range");
else
return elements[n];
}
StrVec &StrVec::operator=(StrVec &&s) noexcept
{
if(&s != this)
{
free();
first_free = s.first_free;
elements = s.elements;
cap = s.cap;
s.first_free = s.elements = s.cap = nullptr;
}
return *this;
}
StrVec &StrVec::operator=(const initializer_list<string> &il)
{
auto data = alloc_n_copy(il.begin(), il.end());
free();
elements = data.first;
first_free = cap = data.second;
return *this;
}
void StrVec::reallocate(size_t n)
{
auto newcapacity = n ? n : (size() ? 2 * size() : 1);
auto newdata = alloc.allocate(newcapacity);
auto dest = newdata;
auto elem = elements;
for(size_t i = 0; i != size(); ++i)
alloc.construct(dest++, std::move(*elem++));
free();
elements = newdata;
first_free = dest;
cap = elements + newcapacity;
}
void StrVec::reserve(size_t n)
{
if(n > capacity())
reallocate(n);
}
void StrVec::resize(size_t n, string s)
{
if(n > size() && n <= capacity())
{
uninitialized_fill(first_free, elements + n, s);
first_free = elements + n;
}
else if(n > size() && n > capacity())
{
reallocate();
uninitialized_fill(first_free, elements + n, s);
first_free = elements + n;
}
else if(n < size())
{
for(auto p = first_free; p != elements + n;)
alloc.destroy(--p);
}
}
bool operator==(const StrVec &s1, const StrVec &s2)
{
vector<string> temp1(s1.begin(), s1.end());
vector<string> temp2(s2.begin(), s2.end());
return temp1 == temp2;
}
bool operator!=(const StrVec &s1, const StrVec &s2)
{
return !(s1 == s2);
}
bool operator<(const StrVec &s1, const StrVec &s2)
{
vector<string> temp1(s1.begin(), s1.end());
vector<string> temp2(s2.begin(), s2.end());
return temp1 < temp2;
}
|