Skip to content

Commit 827f127

Browse files
committed
update Vector
1 parent 956bd8c commit 827f127

File tree

2 files changed

+242
-37
lines changed

2 files changed

+242
-37
lines changed

data-structures/Array/__test__/test_Array.cpp

Lines changed: 115 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,126 @@ void test_array(){
4242
std::cout << arr_5[i] << " ";
4343
}
4444
std::cout << std::endl;
45-
std::cout << "All tests passed!" << std::endl;
45+
std::cout << "Array All tests passed!" << std::endl;
4646
std::cout << "*****Array Test End*****" << std::endl;
4747
}
4848

4949
void test_vector(){
5050
std::cout << "*****Vector Test Begin*****" << std::endl;
51-
52-
53-
51+
Vector<int> vec_0(5);
52+
assert(vec_0.empty() == false);
53+
assert(vec_0.size() == 5);
54+
assert(vec_0.capacity() == 5);
55+
assert(vec_0[3] == 0);
56+
Vector<int> vec_1(3, 77);
57+
assert(vec_1.empty() == false);
58+
assert(vec_1.size() == 3);
59+
assert(vec_1.capacity() == 3);
60+
assert(vec_1[1] == 77);
61+
Vector<int> vec;
62+
assert(vec.empty() == true);
63+
assert(vec.size() == 0);
64+
assert(vec.capacity() == 0);
65+
try{
66+
vec.front();
67+
} catch(const std::underflow_error &e){
68+
std::cout << "Vector::front() throw an exception PASSED: " << e.what() << std::endl;
69+
}
70+
try{
71+
vec.back();
72+
} catch(const std::underflow_error &e){
73+
std::cout << "Vector::back() throw an exception PASSED: " << e.what() << std::endl;
74+
}
75+
try{
76+
vec.pop_back();
77+
} catch(const std::underflow_error &e){
78+
std::cout << "Vector::pop_back() throw an exception PASSED: " << e.what() << std::endl;
79+
}
80+
try{
81+
vec.at(0);
82+
} catch(const std::out_of_range &e){
83+
std::cout << "Vector::at() throw an exception PASSED: " << e.what() << std::endl;
84+
}
85+
try{
86+
vec.insert(1, 99);
87+
} catch(const std::out_of_range &e){
88+
std::cout << "Vector::insert() throw an exception PASSED: " << e.what() << std::endl;
89+
}
90+
try{
91+
vec.erase(0);
92+
} catch(const std::out_of_range &e){
93+
std::cout << "Vector::erase() throw an exception PASSED: " << e.what() << std::endl;
94+
}
95+
vec.push_back(12); // 12
96+
assert(vec.empty() == false);
97+
assert(vec.size() == 1);
98+
assert(vec.capacity() == 1);
99+
assert(vec[0] == 12);
100+
assert(vec.front() == 12);
101+
assert(vec.back() == 12);
102+
assert(vec.at(0) == 12);
103+
vec.resize(1); // do nothing
104+
vec.push_back(21); // 12 21
105+
assert(vec.empty() == false);
106+
assert(vec.size() == 2);
107+
assert(vec.capacity() == 2);
108+
assert(vec[1] == 21);
109+
assert(vec.front() == 12);
110+
assert(vec.back() == 21);
111+
assert(vec.at(0) == 12);
112+
vec.push_back(34); // 12 21 34
113+
assert(vec.empty() == false);
114+
assert(vec.size() == 3);
115+
assert(vec.capacity() == 4);
116+
assert(vec[1] == 21);
117+
assert(vec.front() == 12);
118+
assert(vec.back() == 34);
119+
assert(vec.at(2) == 34);
120+
vec.shrink_to_fit(); // 12 21 34
121+
assert(vec.empty() == false);
122+
assert(vec.size() == 3);
123+
assert(vec.capacity() == 3);
124+
assert(vec[0] == 12);
125+
assert(vec.front() == 12);
126+
assert(vec.back() == 34);
127+
assert(vec.at(1) == 21);
128+
vec.insert(1, 46); // 12 46 21 34
129+
assert(vec.empty() == false);
130+
assert(vec.size() == 4);
131+
assert(vec.capacity() == 6);
132+
assert(vec[1] == 46);
133+
assert(vec.front() == 12);
134+
assert(vec.back() == 34);
135+
assert(vec.at(2) == 21);
136+
vec.reserve(8); // 12 46 21 34
137+
assert(vec.empty() == false);
138+
assert(vec.size() == 4);
139+
assert(vec.capacity() == 8);
140+
assert(vec[1] == 46);
141+
assert(vec.front() == 12);
142+
assert(vec.back() == 34);
143+
assert(vec.at(2) == 21);
144+
vec.erase(2); // 12 46 34
145+
assert(vec.empty() == false);
146+
assert(vec.size() == 3);
147+
assert(vec.capacity() == 8);
148+
assert(vec[1] == 46);
149+
assert(vec.front() == 12);
150+
assert(vec.back() == 34);
151+
assert(vec.at(1) == 46);
152+
vec.pop_back(); // 12 46
153+
assert(vec.empty() == false);
154+
assert(vec.size() == 2);
155+
assert(vec.capacity() == 8);
156+
assert(vec[1] == 46);
157+
assert(vec.front() == 12);
158+
assert(vec.back() == 46);
159+
assert(vec.at(0) == 12);
160+
vec.clear(); // null
161+
assert(vec.empty() == true);
162+
assert(vec.size() == 0);
163+
assert(vec.capacity() == 8);
164+
std::cout << " Vector ALL TEST PASSED!" << std::endl;
54165
std::cout << "*****Vector Test End*****" << std::endl;
55166
}
56167

data-structures/Array/include/Vector.h

Lines changed: 127 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,22 @@ class Vector{
1616
bool empty() const {return _start == _finish;}
1717
size_t size() const {return static_cast<size_t>(_finish - _start);};
1818
size_t capacity() const {return static_cast<size_t>(_end_of_storage - _start);};
19+
void reserve (const size_t n);
1920
void shrink_to_fit();
2021
// Element access
2122
T& front();
2223
T& back();
2324
T& at(const size_t index);
2425
T& operator[](const size_t index);
2526
// Modifiers
26-
void clear();
27-
void resize(const size_t count);
28-
void insert(const size_t index);
29-
void erase(const size_t index);
3027
void push_back(const T &value);
3128
void pop_back();
29+
void insert(const size_t index, const T& value);
30+
void resize(const size_t count);
31+
void erase(const size_t index);
32+
void clear();
3233
private:
34+
bool _full() const {return _end_of_storage == _finish;}
3335
void _reallocate(const size_t new_capacity);
3436
private:
3537
T *_start;
@@ -39,61 +41,58 @@ class Vector{
3941

4042
//Constructor and Destructor
4143
template <typename T>
42-
Vector<T>::Vector(){
43-
_start = nullptr;
44-
_finish = nullptr;
45-
_end_of_storage = nullptr;
46-
}
44+
Vector<T>::Vector() : _start(nullptr), _finish(nullptr), _end_of_storage(nullptr) {}
4745

4846
template <typename T>
49-
Vector<T>::Vector(size_t N){
47+
Vector<T>::Vector(size_t N) : _start(nullptr), _finish(nullptr), _end_of_storage(nullptr){
5048
if(N > 0){
51-
_start = new T[N];
52-
_finish = _start;
53-
_end_of_storage = _start + N;
54-
}
55-
else{
56-
_start = nullptr;
57-
_finish = nullptr;
58-
_end_of_storage = nullptr;
49+
_start = static_cast<T*>(::operator new[](N * sizeof(T)));
50+
_finish = _start + N;
51+
_end_of_storage = _finish;
52+
for(T* p = _start; p != _finish; ++p){
53+
new(p) T();
54+
}
5955
}
6056
}
6157

6258
template <typename T>
63-
Vector<T>::Vector(size_t N, const T &value){
59+
Vector<T>::Vector(size_t N, const T &value) : _start(nullptr), _finish(nullptr), _end_of_storage(nullptr){
6460
if(N > 0){
65-
_start = new T[N];
61+
_start = static_cast<T*>(::operator new[](N * sizeof(T)));
6662
_finish = _start + N;
6763
_end_of_storage = _finish;
68-
for(size_t i = 0; i < N; ++i){
69-
_start[i] = value;
64+
for(T* p = _start; p != _finish; ++p){
65+
new(p) T(value);
7066
}
7167
}
72-
else{
73-
_start = nullptr;
74-
_finish = nullptr;
75-
_end_of_storage = nullptr;
76-
}
7768
}
7869

7970
template <typename T>
8071
Vector<T>::~Vector(){
81-
delete[] _start;
72+
if(_start){
73+
for(T* p = _start; p != _finish; ++p){
74+
p->~T();
75+
}
76+
::operator delete[](_start);
77+
}
8278
_start = nullptr;
8379
_finish = nullptr;
8480
_end_of_storage = nullptr;
8581
}
8682

83+
template <typename T>
84+
void Vector<T>::reserve(const size_t n){
85+
if(n > capacity()){
86+
_reallocate(n);
87+
}
88+
}
89+
8790
template <typename T>
8891
void Vector<T>::shrink_to_fit(){
8992
if(_finish == _end_of_storage){
9093
return;
9194
}
92-
while(_end_of_storage != _finish){
93-
T* del = _end_of_storage - 1;
94-
delete del;
95-
--_end_of_storage;
96-
}
95+
_reallocate(size());
9796
}
9897

9998
// Elements access
@@ -126,4 +125,99 @@ T& Vector<T>::operator[](const size_t index){
126125
return _start[index];
127126
}
128127

128+
//Modifier
129+
template <typename T>
130+
void Vector<T>::push_back(const T &value){
131+
if(_full() == true){
132+
size_t new_capacity = size() > 0 ? 2 * size() : 1;
133+
_reallocate(new_capacity);
134+
}
135+
*_finish = value;
136+
++_finish;
137+
}
138+
139+
template <typename T>
140+
void Vector<T>::pop_back(){
141+
if(empty()){
142+
throw std::underflow_error("pop_back(): This Vector is empty.");
143+
}
144+
--_finish;
145+
_finish->~T();
146+
}
147+
148+
template <typename T>
149+
void Vector<T>::insert(const size_t index, const T& value){
150+
if(index > size()){
151+
throw std::out_of_range("insert(): Index out of range.");
152+
}
153+
if(_full()){
154+
size_t new_capacity = size() > 0 ? 2 * size() : 1;
155+
_reallocate(new_capacity);
156+
}
157+
for(T* p = _finish; p != _start + index; --p){
158+
new(p) T(*(p-1));
159+
(p - 1)->~T();
160+
}
161+
new(_start+index) T(value);
162+
++_finish;
163+
}
164+
165+
template <typename T>
166+
void Vector<T>::resize(const size_t count){
167+
if(size() == count){
168+
return;
169+
}
170+
else if(size() > count){
171+
for(T* p = _start + count; p != _finish; ++p){
172+
p->~T();
173+
}
174+
_finish = _start + count;
175+
}
176+
else{
177+
if(count > capacity()){
178+
_reallocate(count);
179+
}
180+
for(T* p = _finish; p != _start + count; ++p){
181+
new(p) T();
182+
}
183+
_finish = _start + count;
184+
}
185+
}
186+
187+
template <typename T>
188+
void Vector<T>::erase(const size_t index){
189+
if(index >= size()){
190+
throw std::out_of_range("erase(): Index out of range.");
191+
}
192+
(_start + index)->~T();
193+
for(T* p = _start + index + 1; p != _finish; ++p){
194+
new(p-1) T(*(p));
195+
p->~T();
196+
}
197+
--_finish;
198+
}
199+
200+
template <typename T>
201+
void Vector<T>::clear(){
202+
for(T* p = _start; p != _finish; ++p){
203+
p->~T();
204+
}
205+
_finish = _start;
206+
}
207+
208+
// Privare Functions
209+
template <typename T>
210+
void Vector<T>::_reallocate(const size_t new_capacity){
211+
T *del = _start;
212+
T *new_start = static_cast<T*>(::operator new[](new_capacity * sizeof(T)));
213+
for(size_t i = 0; i < size(); ++i){
214+
new(new_start + i) T(_start[i]);
215+
_start[i].~T();
216+
}
217+
_finish = new_start + size();
218+
_start = new_start;
219+
_end_of_storage = new_start + new_capacity;
220+
::operator delete[](del);
221+
}
222+
129223
#endif // VECTOR_H

0 commit comments

Comments
 (0)