vector realization

Vector-version1-allocator + pointers

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

// main.cpp
// MyVector

// Created by 韩雪滢 on 2019/2/12.
// Copyright © 2019 韩雪滢. All rights reserved.



#include <memory>
#include <algorithm>
using namespace std;
template <class , class Alloc = std::allocator<T>> class myVector
{
public:
typedef T value_type;
typedef value_type* iterator;
typedef const value_type* const_iterator;
typedef value_type& reference;
typedef value_type* pointer;
typedef size_t size_type;
protected:
Alloc _alloc;
iterator _start;
iterator _end;
iterator _end_of_storage;
public:
myVector(): _start(0), _end(0), _end_of_storage(0){}
myVector(size_type n, const T& value);
myVector(const myVector& v);


iterator begin() {return _start;}
iterator end() {return _end;}
reference operator[] (size_type n){return *(begin() + n);}
myVector& operator= (const myVector& rv);
void push_back(const T& value);
void insert_aux(iterator position, const T& x);
size_type size(){return size_type(end() - begin());}
void _destroy();
const_iterator cbegin() const{return _start;}
const_iterator cend() const {return _end;}
void insert(iterator position, const T& value);

};

template<class , class Alloc>
myVector<T, Alloc>::myVector(size_type n, const T& value){
_start = _alloc.allocate(n);
std::uninitialized_fill(_start, _start + n, value);
_end = _end_of_storage = _start + n;
}

template<class , class Alloc>
myVector<T, Alloc>::myVector(const myVector& v){
_start = _alloc.allocate(v.cend() - v.cbegin());
_end = uninitialized_copy(v.cbegin(), v.cend(), _start);
}


template<class , class Alloc>
void myVector<T, Alloc>::_destroy(){
if(_start){
iterator it(_end);
while(it != _start){
_alloc.destroy(it--);
}
}
_alloc.deallocate(_start, _end_of_storage - _start);
_start = _end_of_storage = nullptr;
}

template<class , class Alloc>
void myVector<T, Alloc>::insert_aux(iterator position, const T &x){
if(_end == _end_of_storage){
size_type ori_size = size();
size_type len = ori_size ? ori_size * 2 : 1;
iterator new_start = _alloc.allocate(len);
iterator new_end = new_start;
new_end = uninitialized_copy(_start, position, new_start);
_alloc.construct(new_end, x);
new_end++;
new_end = uninitialized_copy(position, _end, new_end);
_destroy();
_start = new_start;
_end = new_end;
_end_of_storage = _start + len;
}
}

template<class T, class Alloc>
void myVector<T, Alloc>::push_back(const T &value){
if(_end != _end_of_storage){
_alloc.construct(_end, value);
_end++;
} else {
insert_aux(end(), value);
}
}

template<class T, class Alloc>
myVector<T, Alloc>& myVector<T, Alloc>::operator=(const myVector<T, Alloc> &rv){
if(this == &rv)
return *this;
_start = _alloc.allocate(rv.cend() - rv.cbegin());
_end = _end_of_storage = uninitialized_copy(rv.cbegin(), rv.cend(), _start);
return *this;
}

template<class T, class Alloc>
void myVector<T, Alloc>::insert(iterator position, const T &value){
if(_end == _end_of_storage){
size_type len = size() * 2;
iterator new_start = _alloc.allocate(len);
iterator new_end = uninitialized_copy(_start, position, new_start);
_alloc.construct(new_end, value);
new_end++;
new_end = uninitialized_copy(position, _end, new_end);
_destroy();
_start = new_start;
_end = new_end;
_end_of_storage = _start + len;
} else {
iterator old_end = _end;
_end += 1;
copy_backward(position, old_end, _end);
_alloc.construct(position, value);
}
}

int main(int argc, const char * argv[]) {
myVector<int> vec(3, 1);
myVector<int> vec2(5, 1);
vec.push_back(3);
vec2 = vec;

myVector<int> vec3(vec2);
vec3.insert(vec3.begin()+2, 0);
for(int i = 0; i < vec3.size(); i++)
cout << vec3[i] << " ";
cout << endl;

return 0;
}

C++ Review:

allocator:

  • destroy: destroy in-place the object pointed by pointer, does not deallocate the storage for the element
  • deallocate: releases the storage previously allocated by the allocator
  • construct: allocator.construct ( pointer, obj ) : construct an element object on the location pointed by the pointer
  • pointer allocate(size_type n): allocate a block of storage to contain n elements of type value_type and return a pointer to the first element.

Vector - version2 - array + realloc

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

using namespace std;

template <class T>
class AVector {
private:
typedef T value_type;
typedef size_t size_type;
typedef value_type* iterator;
value_type* array;
size_type allSize;
size_type usedSize;
public:
AVector(): allSize(1), usedSize(0){
array = new value_type[allSize];
}
AVector(const AVector& av);
value_type& operator[] (size_type n){return array[n];}
AVector& operator= (const AVector& av);
void push_back(const value_type& value);
void insert(value_type* position, const value_type& value);
void erase(value_type* position);
iterator begin() {return array;}
iterator end() {return array + usedSize;}
size_type size()const{return usedSize;}
};

template <class T>
AVector<T>::AVector(const AVector& av){
array = av.array;
usedSize = av.usedSize;
allSize = av.allSize;
}

template <class T>
void AVector<T>::push_back(const value_type &value){
if(usedSize == allSize){
allSize *= 2;
array = (value_type*) realloc(array, allSize);
}
array[usedSize++] = value;
}

template<class T>
void AVector<T>::insert(value_type *position, const value_type &value){
size_type p = position - begin();
if(usedSize == allSize){
allSize *= 2;
array = (value_type*) realloc(array, allSize);
}
for(size_type i = usedSize-1; i >= p; i--){
array[i+1] = array[i];
}
array[p] = value;
usedSize++;
}

template<class T>
void AVector<T>::erase(value_type *position){
size_type ind = position - begin();
for(size_type i = ind+1; i < usedSize; i++){
array[i-1] = array[i];
}
usedSize--;
}

template<class T>
AVector<T>& AVector<T>::operator=(const AVector<T> &av){
while(allSize < av.usedSize){
allSize *= 2;
}
array = new T[allSize];
for(int i = 0; i < av.usedSize; i++){
array[i] = *(av.array + i);
}
usedSize = av.usedSize;
return *this;
}

C++ Review

  • copy constructor OR assignment operator

    • if we first create an object by constructor, then

      1
      2
      3
      4
      5
      6
        * if we create an object by ``` ClassName object1 = object2```, it actually called copy constructor.
      * operator overloading
      * assignment operator
      * array index operator
      * realloc
      * ```(value_type*) realloc(value_type* ori, size)`

    • This function is used to reallocate the original array to a new block of memory with its all elements.