1
+ #include " exercise13.5StrVec.h"
2
+
3
+ void StrVec::push_back (const string& s)
4
+ {
5
+ chk_n_alloc (); // 确保有足够空间容纳新元素
6
+ alloc.construct (firstfree++, s); // 构造新元素
7
+ }
8
+
9
+ pair<string*, string*> StrVec::alloc_n_copy (const string* s1, const string* s2)
10
+ {
11
+ auto data = alloc.allocate (s2-s1);
12
+ return {data, uninitialized_copy (s1, s2, data)};
13
+ }
14
+
15
+ /* *
16
+ *free()
17
+ *首先销毁元素, 然后释放所有内存
18
+ */
19
+ void StrVec::free ()
20
+ {
21
+ if (elements)
22
+ {
23
+ // for(auto p = firstfree; p!=elements;)
24
+ // alloc.destroy(--p);
25
+ for_each (elements, firstfree, [this ](string& str){alloc.destroy (&str);});
26
+ alloc.deallocate (elements, cap-elements);
27
+ }
28
+ }
29
+ StrVec::StrVec (const StrVec& str)
30
+ {
31
+ auto temp = alloc_n_copy (str.begin (), str.end ());
32
+ elements = temp.first ;
33
+ firstfree = cap = temp.second ;
34
+ }
35
+
36
+ /* *
37
+ *StrVec(initializer_list<string> strlist)
38
+ *使用初始化列表的构造函数
39
+ */
40
+ StrVec::StrVec (initializer_list<string> strlist)
41
+ {
42
+ auto newcapacity = strlist.size ()*2 ;
43
+ auto data = alloc.allocate (newcapacity);
44
+ auto fisfree = uninitialized_copy (strlist.begin (), strlist.end (), data);
45
+ elements = data;
46
+ firstfree = fisfree;
47
+ cap = elements + newcapacity;
48
+ }
49
+ StrVec& StrVec::operator =(const StrVec& rhs)
50
+ {
51
+ auto data = alloc_n_copy (rhs.begin (), rhs.end ());
52
+ free ();
53
+ elements = data.first ;
54
+ firstfree = cap = data.second ;
55
+ return *this ;
56
+ }
57
+ StrVec::~StrVec ()
58
+ {
59
+ free ();
60
+ }
61
+ /* *
62
+ *reallocate()
63
+ *
64
+ */
65
+ void StrVec::reallocate ()
66
+ {
67
+ auto newcapacity = size () ? size ()*2 :1 ;
68
+ auto newdata = alloc.allocate (newcapacity);
69
+
70
+ auto dest = newdata;
71
+ auto elem = elements;
72
+ for (size_t i=0 ; i<size (); i++)
73
+ {
74
+ alloc.construct (dest++, std::move (*elem++));
75
+ }
76
+
77
+ free ();
78
+ elements = newdata;
79
+ firstfree = dest;
80
+ cap = elements + newcapacity;
81
+
82
+ }
83
+
84
+ void StrVec::reserve (size_t n)
85
+ {
86
+ size_t old_capacity = capacity ();
87
+ if (n > old_capacity)
88
+ {
89
+ auto newcapacity = n;
90
+ auto newdata = alloc.allocate (newcapacity);
91
+
92
+ auto dest = newdata;
93
+ auto elem = elements;
94
+ for (size_t i=0 ; i<size (); i++)
95
+ {
96
+ alloc.construct (dest++, std::move (*elem++));
97
+ }
98
+
99
+ free ();
100
+ elements = newdata;
101
+ firstfree = dest;
102
+ cap = elements + newcapacity;
103
+ }
104
+ }
105
+
106
+ void StrVec::resize (size_t n)
107
+ {
108
+ if (n > capacity ())
109
+ {
110
+
111
+ throw out_of_range (" out of range!" );
112
+ return ;
113
+
114
+ }
115
+
116
+ else if (n>size ())
117
+ {
118
+ auto count = n - size ();
119
+ uninitialized_fill_n (firstfree, count, " " );
120
+ }
121
+ }
122
+
123
+ void StrVec::resize (size_t n, string str)
124
+ {
125
+ if (n > capacity ())
126
+ {
127
+
128
+ throw out_of_range (" out of range!" );
129
+ return ;
130
+ }
131
+
132
+ else if (n>size ())
133
+ {
134
+ auto count = n - size ();
135
+ uninitialized_fill_n (firstfree, count, str);
136
+ }
137
+ }
138
+
139
+ int main ()
140
+ {
141
+ StrVec test{" xianguy" , " love" , " liuchang" };
142
+ test.push_back (" xiangyu" );
143
+ test.push_back (" liuchang" );
144
+ cout << " capacity: " << test.capacity () << endl;
145
+ cout << " size: " << test.size () << endl;
146
+ for (auto it=test.begin (); it !=test.end (); it++)
147
+ {
148
+ cout << *it << endl;
149
+ }
150
+ return 0 ;
151
+ }
0 commit comments