-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmystl_vector.hpp
201 lines (165 loc) · 5.83 KB
/
mystl_vector.hpp
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
#ifndef _MYSTL_VECTOR_H
#define _MYSTL_VECTOR_H
#include "mystl_iterator.hpp"
#include "mystl_algobase.hpp"
#include <string.h>
namespace numb{
template <typename _Tp>
class Vector {
public:
typedef _Tp value_type;
typedef _Tp* pointer;
typedef const _Tp* const_pointer;
typedef _Tp& reference;
typedef const _Tp& const_reference;
typedef _Normal_iterator<pointer, Vector> Iterator;
typedef _Normal_iterator<const_pointer, Vector> Const_iterator;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
private:
_Tp* _M_start;
_Tp* _M_finish;
_Tp* _M_end_of_storage;
protected:
public:
Vector() : _M_start(NULL), _M_finish(NULL), _M_end_of_storage(NULL) {}
explicit Vector(size_type _n) { _M_fill_initialize(_n); }
Vector(const Vector& rhs)
: _M_start(NULL), _M_finish(NULL), _M_end_of_storage(NULL) {
_M_start = new _Tp[rhs.capacity()];
_M_finish = _M_start + rhs.size();
_M_end_of_storage = _M_start + rhs.capacity();
//for (size_type i = 0; i < size(); ++i)
// *(_M_start + i) = *(rhs._M_start + i);
memcpy(_M_start, rhs._M_start, size() * sizeof(_Tp));
}
Vector& operator=(const Vector& rhs) {
Vector copy = rhs;
Swap(copy);
return *this;
}
void swap(const Vector& rhs) {
using numb::Swap;
Swap(_M_start, rhs._M_start);
Swap(_M_finish, rhs._M_finish);
Swap(_M_end_of_storage, rhs._M_end_of_storage);
}
template <typename _InputIterator>
Vector(_InputIterator _first, _InputIterator _last)
{
difference_type _n = _last - _first;
_M_fill_initialize(_n);
for (; _first != _last; ++_first)
push_back(*_first);
}
~Vector() throw() { delete[] _M_start; }
Iterator begin() throw() { return Iterator(_M_start); }
Const_iterator begin() const throw() { return Const_iterator(_M_start); }
Iterator end() throw() { return Iterator(_M_finish); }
Const_iterator end() const throw() { return Const_iterator(_M_finish); }
size_type size() const throw() { return size_type(_M_finish - _M_start); }
size_type capacity() const throw() {
return size_type(_M_end_of_storage - _M_start);
}
bool empty() const throw() { return begin() == end(); }
reference operator[](size_type _n) {
if (_n < 0 || _n >= size()) throw;
return *(_M_start + _n);
}
const_reference operator[](size_type _n) const {
if (_n < 0 || _n >= size()) throw;
return *(_M_start + _n);
}
//reference front() { return *begin(); }
//const_reference front() const { return *begin(); }
//reference back() { return *(end() - 1); }
//const_reference back() const { return *(end() - 1); }
reference front() { return *begin(); }
const_reference front() const { return *_M_start; }
reference back() { return *(end() - 1); }
const_reference back() const { return *(_M_finish - 1); }
pointer data() throw() { return _M_start; }
void push_back(const value_type& _x) {
if (_M_finish == _M_end_of_storage) _reallocate(2 * Max(size(), size_type(1)));
*_M_finish++ = _x;
}
value_type pop_back() {
if (begin() == end()) throw;
--_M_finish;
value_type tmp = *_M_finish;
//_shrink();
return tmp;
}
// stl pop_back will call object's deconstructor
void assign(size_type _n, const value_type& _x) {
if (_n > capacity()) throw;
for (size_type i = 0; i < _n; ++i)
*_M_finish++ = _x;
}
void insert(size_type _pos, value_type _x) {
if (_pos <= 0 || _pos >= size())
return;
size_type sz = size();
if (_M_finish < _M_end_of_storage) {
for (size_type k = sz; k > _pos; --k)
*(_M_start + k) = *(_M_start + k - 1);
*(_M_start + _pos) = _x;
}
else {
size_type _newC = 2 * Max(size(), size_type(1));
_Tp* newV = new _Tp[_newC];
//for (size_type k = 0; k < _pos; ++k)
// newV[k] = *(_M_start + k);
memcpy(newV, _M_start, _pos * sizeof(_Tp));
newV[_pos] = _x;
//for (size_type k = (_pos + 1); k <= sz; ++k)
// newV[k] = *(_M_start + k - 1);
memcpy(newV + _pos + 1, _M_start + _pos, (sz - _pos) * sizeof(_Tp));
_M_start = newV;
_M_finish = _M_start + sz + 1;
_M_end_of_storage = _M_start + _newC;
}
}
value_type erase(size_type _pos) {
if (_pos < 0 || _pos >= size())
return -1;
value_type _tmp = *(_M_start + _pos);
for (size_type k = _pos; k < size(); ++k)
*(_M_start + k) = *(_M_start + k + 1);
--_M_finish;
//_shrink();
return _tmp;
}
protected:
void _M_fill_initialize(size_type _n) {
_M_start = new value_type[_n];
_M_finish = _M_start;
_M_end_of_storage = _M_start + _n;
}
void _reallocate(size_type _n);
void _shrink() {
if (size() > capacity() / 4) return;
_Tp* oldV = _M_start;
size_type newC = capacity() / 2;
_M_start = new _Tp[newC];
//for (size_type i = 0; i < size(); ++i) *(_M_start + i) = oldV[i];
memcpy(_M_start, oldV, size() * sizeof(_Tp));
_M_finish = _M_start + size();
_M_end_of_storage = _M_start + newC;
delete[] oldV;
}
};
template <typename _Tp>
void Vector<_Tp>::_reallocate(size_type _n) {
_Tp* oldV = _M_start;
size_type numToCopy = _n < size() ? _n : size();
_Tp* newV = new _Tp[_n];
//for (size_type i = 0; i < numToCopy; i++) newV[i] = *(_M_start + i);
memcpy(newV, _M_start, numToCopy * sizeof(_Tp));
_M_start = newV;
_M_finish = _M_start + numToCopy;
_M_end_of_storage = _M_start + _n;
delete[] oldV;
}
}
#endif