-
Notifications
You must be signed in to change notification settings - Fork 124
/
Copy pathStrVec.h
90 lines (84 loc) · 2.47 KB
/
StrVec.h
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
#ifndef STRVEC_H
#define STRVEC_H
#include <string>
#include <memory>
using namespace std;
// 主要是allocator的使用,一块申请到的内存,怎么去使用
class StrVec{
public:
StrVec():elements(nullptr),first_free(nullptr),cap(nullptr){}
StrVec(const StrVec&);
StrVec &operator=(const StrVec&);
~StrVec();
void push_back(const string&);
size_t size() const{ return first_free - elements;}
size_t capacity() const { return cap-elements;}
string *begin() const { return elements; }
string *end() const { return first_free;}
private:
static allocator<string> alloc; // 让这个声明在整个程序是有用的!
void chk_n_alloc() { if(size() == capacity()) reallocate();}
pair<string*, string*> alloc_n_copy(const string*,const string*);
void free();
void reallocate();
string *elements;
string *first_free;
string *cap;
};
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);
}
}
}
StrVec::StrVec(const StrVec &s){
auto newdata = alloc_n_copy(s.begin(),s.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;
}
void StrVec::reallocate(){
auto newcapacity = size()?2*size():1;
auto newdata = alloc.allocate(newcapacity);
// auto last = uninitialized_copy(make_move_iterator(begin()),make_move_iterator(end()),newdata);
// free();
// elements = newdata;
// first_free = last;
// cap = elements+newcapacity;
auto dest = newdata;
auto elem = elements;
for(size_t i = 0;i!=size();++i)
alloc.construct(dest++,move(*elem++));
free();
elements = newdata;
first_free = dest;
cap = elements+newcapacity;
}
StrVec &StrVec::operator=(StrVec &&rhs) noexcept{
if(this != &rhs){
free();
elements = rhs.elements;
first_free = rhs.first_free;
cap = rhs.cap;
rhs.elements = rhs.first_free = rhs.cap = nullptr;
}
return *this;
}
#endif STRVEC_H