1 #include <iostream>
2 #include <vector>
3 #include <memory>
4 #include <thread>
5 #include <type_traits>
6 #include <typeinfo>
7 #include <sstream>
8 #include <utility>
9
10
11 class StrVec
12 {
13 friend std::ostream &operator<<(std::ostream &os, const StrVec &rhs);
14
15 private:
16 std::string *elemnets_;
17 std::string *memry_free;
18 std::string *cap;
19 std::allocator<std::string> alloc;//为所有StrVec分配内存
20
21 //申请2倍范围空间,并把范围移动到新空间
22 std::pair<std::string *, std::string *> alloc_n_copy(const std::string *beg, const std::string *end)
23 {
24 auto new_memry = alloc.allocate(end - beg);
25 return {new_memry, std::uninitialized_copy(beg, end, new_memry)};
26 };
27
28
29 void free() //释放目前申请的内存
30 {
31 for (auto ptr = memry_free; ptr != elemnets_;)
32 {
33 alloc.destroy(--ptr);
34 }
35
36 alloc.deallocate(elemnets_, memry_free - elemnets_);
37 }
38
39 void realloctor() //重新申请大于目前2倍空间;
40 {
41 auto newcapacity = size() ? 2 * size() : 1;
42 auto newmemery = alloc.allocate(newcapacity);
43 auto dest = newmemery;
44 auto elem = elemnets_;//指向当前对象的头
45 for (size_t i = 0; i != size(); ++i)
46 {
47 //move会让elem指向的string对象放弃自己的内存管理权并返回,然后construct使用string的移动构造函数构建dest指向的地址
48 alloc.construct(dest++, std::move(*elem++));
49 }
50 free();
51 elemnets_ = newmemery;
52 memry_free = dest;
53 cap = elemnets_ + newcapacity;
54 };
55
56 void Chk_n_alloc()
57 {
58 if (size() == capacity())
59 realloctor();
60 }
61
62 public:
63 StrVec() : elemnets_(nullptr), memry_free(nullptr), cap(nullptr)
64 {}
65
66 StrVec(std::initializer_list<std::string> li)
67 {
68 auto newadress = alloc_n_copy(li.begin(), li.end());
69 elemnets_ = newadress.first;
70 cap = memry_free = newadress.second;
71 }
72
73 //只是构造(每次想着释放- -)
74 StrVec(const StrVec &rhs)
75 {
76 auto newadress = alloc_n_copy(rhs.begin(), rhs.end());
77 elemnets_ = newadress.first;
78 cap = memry_free = newadress.second;
79 }
80
81 StrVec(StrVec &&rhs)
82 : elemnets_(rhs.elemnets_), memry_free(rhs.memry_free), cap(rhs.cap)
83 {
84 //置空
85 rhs.elemnets_ = rhs.cap = rhs.memry_free = nullptr;
86 }
87
88 StrVec &operator=(const StrVec &rhs)
89 {
90 if (&rhs != this)
91 {
92 auto newadress = alloc_n_copy(rhs.begin(), rhs.end());
93 free();
94 elemnets_ = newadress.first;
95 memry_free = cap = newadress.second;
96 }
97 return *this;
98 }
99
100 StrVec &operator=(StrVec &&rhs)
101 {
102 if (&rhs != this)
103 {
104 elemnets_ = rhs.elemnets_;
105 memry_free = rhs.memry_free;
106 cap = rhs.cap;
107 rhs.elemnets_ = rhs.cap = rhs.memry_free = nullptr;
108 }
109 return *this;
110 }
111
112 //列表赋值初始化
113 StrVec &operator=(std::initializer_list<std::string> li)
114 {
115 auto newadress = alloc_n_copy(li.begin(), li.end());
116 free();
117 elemnets_ = newadress.first;
118 memry_free = cap = newadress.second;
119
120 return *this;
121 }
122
123
124 std::string &operator[](std::size_t size_)
125 {
126 return elemnets_[size_];
127 }
128
129 std::string &operator[](std::size_t size) const
130 {
131 return elemnets_[size];
132
133 }
134
135
136 bool operator==(const StrVec &s)
137 {
138 if (size() != s.size())
139 return false;
140 auto it = elemnets_, its = s.elemnets_;
141 while (it != memry_free)
142 {
143 if (*it++ != *its++)
144 return false;
145 }
146 return true;
147 }
148
149
150 bool operator<(const StrVec &rhs)
151 {
152 if (this->size() < rhs.size())
153 {
154 return true;
155 } else if (this->size() > rhs.size())
156 {
157 return false;
158 }
159
160 auto rhs_elemte = rhs.elemnets_;
161 for (auto iter_ptr = elemnets_; iter_ptr != memry_free;)
162 {
163 if (*iter_ptr++ > *rhs_elemte++)
164 {
165 return false;
166 } else
167 {
168 return true;
169 }
170 }
171 return false;
172 }
173
174 bool operator>(const StrVec &rhs)
175 {
176 return !(*this < rhs) && (this != &rhs);
177 }
178
179 bool operator!=(const StrVec &rhs)
180 {
181 return !(*this == rhs);
182 }
183
184
185 public:
186 template<typename ...Args>
187 void emplace_back(Args &&... paracage)
188 {
189 Chk_n_alloc();
190 alloc.construct(memry_free++, std::forward<Args>(paracage)...);
191 }
192
193 void push_back(const std::string &s)
194 {
195 Chk_n_alloc();//确保空间剩余
196 alloc.construct(memry_free++, s);//在尾后构建一个s(s的拷贝构造函数构造),并把尾后指针first_free指向下一个
197 }
198
199 void pop_back()
200 {
201 if (memry_free != elemnets_)
202 {
203 alloc.destroy(--memry_free);
204 }
205 }
206
207
208 std::size_t size() const
209 {
210 return memry_free - elemnets_;
211 }
212
213 std::size_t capacity() const
214 {
215 return cap - elemnets_;
216 }
217
218 std::string *begin() const
219 {
220 return elemnets_;
221 }
222
223 std::string *end() const
224 {
225 return memry_free;
226 }
227 };
228
229
230 std::ostream &operator<<(std::ostream &os, const StrVec &rhs)
231 {
232 for (auto ptr = rhs.elemnets_; ptr != rhs.memry_free;)
233 {
234 os << *ptr++ << "\n";
235 }
236
237 return os;
238 }
239
240
241 int main(int argc, char *argv[])
242 {
243
244 StrVec strvec{"Hello", "World", "this", "std::string", "vector<std::string>"};
245 std::cout << strvec;
246 std::cout << strvec[3] << std::endl;
247 strvec.push_back("你好");
248 std::cout << strvec[5] << std::endl;
249
250 std::cout << "------------" << std::endl;
251 std::cout << strvec;
252 strvec.pop_back();
253 strvec.pop_back();
254 strvec.pop_back();
255 strvec.pop_back();
256 std::cout << "------------" << std::endl;
257 std::cout<<strvec;
258 std::cout << "------------" << std::endl;
259 strvec.emplace_back("其实emeplace通过参数包转发给std::string的构造");
260 strvec.emplace_back(10,'c');
261 std::cout<<strvec;
262
263 return 0;
264 }